Создать исключение с контекстом

13

Когда PostgreSQL генерирует исключение, появляется строка «КОНТЕКСТ», например:

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

Но когда я выбрасываю исключение, этой строки там нет. Я не нашел, как добавить это.

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

Можно ли добавить эту строку в мое исключение?

Quentin
источник

Ответы:

13

Я не смог найти прямой способ вывода CONTEXTстроки с пользовательским исключением. Эта опция просто не реализована (пока) в PostgreSQL 9.1. Прочтите руководство здесь .
Тем не менее, я нашел ...

Временное решение

... это должно работать безупречно . Вы можете заставить plpgsql вести себя так, как вам нужно, вызывая другую функцию, которая вызывает ошибку для вас. Это работает с PostgreSQL 9.0 или новее .
Для версии 8.4 вы должны сделать небольшую корректировку: параметры не могут быть назначены.

Функция для выдачи ошибки (предупреждение, уведомление, ..) с определенным пользователем сообщением и 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';

Используйте функцию, чтобы вызвать ошибку как это:

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;

Вызов:

SELECT test_err('wrong parameter');

Значения по умолчанию и именованные параметры

Я улучшил синтаксис и добавил значения по умолчанию в определение функции. Если вы вызываете его без параметров (или только один) и значения по умолчанию будут использоваться для пропущенных значений. В сочетании с именованными параметрами вы можете делать практически все что угодно. Примеры:

SELECT f_raise();
SELECT f_raise('WARNING');
SELECT f_raise(_msg := 'boohoo');
SELECT f_raise(_lvl := 'WARNING');
Эрвин Брандштеттер
источник