Wygeneruj wyjątek z kontekstem


13

Gdy PostgreSQL zgłasza wyjątek, pojawia się wiersz „KONTEKST”, taki jak:

    ERROR:  INSERT has more target COLUMNS than expressions
    LINE 3: ...
                                                         ^
    QUERY:  INSERT INTO ...
    CONTEXT:  PL/pgSQL FUNCTION "XXXXX" line 4 at SQL statement

Ale kiedy rzucę wyjątek, tej linii nie ma. Nie znalazłem jak go dodać.

    RAISE EXCEPTION 'blablabla' USING HINT = 'blablablabla';

Czy można dodać tę linię do mojego wyjątku?

Odpowiedzi:


13

Nie mogłem znaleźć bezpośredniego sposobu wyprowadzenia CONTEXTlinii z wyjątkiem zdefiniowanym przez użytkownika. Ta opcja po prostu nie jest jeszcze zaimplementowana w PostgreSQL 9.1. Przeczytaj instrukcję tutaj .
Jednak znalazłem ...

Obejście

... które powinny działać bezbłędnie . Możesz sprawić, aby plpgsql zachowywał się tak, jak chcesz, wywołując inną funkcję, która podnosi błąd. Działa to z PostgreSQL 9.0 lub nowszym .
W przypadku wersji 8.4 należy dokonać niewielkiej korekty: parametrów nie można przypisać.

Funkcja zgłaszania błędu (ostrzeżenie, zawiadomienie, ...) w komunikacie zdefiniowanym przez użytkownika i CONTEXT:

CREATE OR REPLACE FUNCTION f_raise(_lvl text = 'EXCEPTION'
                                 , _msg text = 'Default error msg.')
  RETURNS void AS
$func$
BEGIN
   CASE upper(_lvl)
      WHEN 'EXCEPTION' THEN RAISE EXCEPTION '%', _msg;
      WHEN 'WARNING'   THEN RAISE WARNING   '%', _msg;
      WHEN 'NOTICE'    THEN RAISE NOTICE    '%', _msg;
      WHEN 'DEBUG'     THEN RAISE DEBUG     '%', _msg;
      WHEN 'LOG'       THEN RAISE LOG       '%', _msg;
      WHEN 'INFO'      THEN RAISE INFO      '%', _msg;
      ELSE RAISE EXCEPTION 'f_raise(): unexpected raise-level: "%"', _lvl;
   END CASE;
END
$func$  LANGUAGE plpgsql;

COMMENT ON FUNCTION f_raise(text, text) IS 'Raise error or given level with msg and context.
Call from inside another function instead of raising an error directly
  to get plpgsql to add CONTEXT (with line number) to error message.
$1 .. error level: EXCEPTION | WARNING | NOTICE | DEBUG | LOG | INFO
$2 .. error message';

Użyj funkcji, aby zgłosić taki błąd:

CREATE OR REPLACE FUNCTION test_err(text)
  RETURNS void AS
$func$
BEGIN
   -- do stuff    

   IF TRUE THEN  -- some condition here?
      -- instead of raising error like this:
      -- RAISE EXCEPTION 'unexpected parameter: "%"', $1;
      PERFORM f_raise('EXCEPTION', 'My message "' || $1 || '"');
   END IF;
END
$func$  LANGUAGE plpgsql;

Połączenie:

SELECT test_err('wrong parameter');

Wartości domyślne i nazwane parametry

Poprawiłem składnię i dodałem wartości domyślne do definicji funkcji. Jeśli wywołasz go bez parametrów (lub tylko jednego), a dla brakujących wartości zostaną użyte wartości domyślne. W połączeniu z nazwanymi parametrami możesz zrobić prawie wszystko. Przykłady:

SELECT f_raise();
SELECT f_raise('WARNING');
SELECT f_raise(_msg := 'boohoo');
SELECT f_raise(_lvl := 'WARNING');
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.