Gere uma exceção com um contexto

13

Quando o PostgreSQL lança uma exceção, existe uma linha "CONTEXTO" como:

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

Mas quando ligo uma exceção, essa linha não está lá. Não encontrei como adicioná-lo.

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

É possível adicionar esta linha à minha exceção?

Quentin
fonte

Respostas:

13

Não consegui encontrar uma maneira direta de gerar a CONTEXTlinha com uma exceção definida pelo usuário. Esta opção ainda não está implementada (ainda) no PostgreSQL 9.1. Leia o manual aqui .
No entanto, eu encontrei um ...

Gambiarra

... isso deve funcionar perfeitamente . Você pode fazer com que o plpgsql se comporte conforme desejado, chamando outra função que gera o erro para você. Isso funciona com o PostgreSQL 9.0 ou posterior .
Para a versão 8.4, é necessário fazer um pequeno ajuste: Não é possível atribuir parâmetros.

Função para gerar um erro (aviso, aviso, ..) com uma mensagem definida pelo usuário e 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';

Use a função para gerar um erro como este:

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;

Ligar:

SELECT test_err('wrong parameter');

Valores padrão e parâmetros nomeados

Melhorei a sintaxe e adicionei valores padrão à definição da função. Se você chamá-lo sem parâmetros (ou apenas um) e os padrões serão usados ​​para valores ausentes. Em combinação com os parâmetros nomeados , você pode fazer praticamente qualquer coisa. Exemplos:

SELECT f_raise();
SELECT f_raise('WARNING');
SELECT f_raise(_msg := 'boohoo');
SELECT f_raise(_lvl := 'WARNING');
Erwin Brandstetter
fonte