Générer une exception avec un contexte

13

Lorsque PostgreSQL lève une exception, il y a une ligne "CONTEXT" comme:

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

Mais quand je lève une exception, cette ligne n'est pas là. Je n'ai pas trouvé comment l'ajouter.

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

Est-il possible d'ajouter cette ligne à mon exception?

Quentin
la source

Réponses:

13

Je n'ai pas pu trouver un moyen direct de sortir la CONTEXTligne avec une exception définie par l'utilisateur. Cette option n'est tout simplement pas (encore) implémentée dans PostgreSQL 9.1. Lisez le manuel ici .
Cependant, j'ai trouvé un ...

solution de contournement

... qui devrait fonctionner parfaitement . Vous pouvez faire en sorte que plpgsql se comporte comme vous le souhaitez en appelant une autre fonction qui déclenche l'erreur pour vous. Cela fonctionne avec PostgreSQL 9.0 ou version ultérieure .
Pour la version 8.4, vous devez effectuer un ajustement mineur: les paramètres ne peuvent pas être attribués.

Fonction pour déclencher une erreur (avertissement, avis, ..) avec un message défini par l'utilisateur et 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';

Utilisez la fonction pour générer une erreur comme celle-ci:

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;

Appel:

SELECT test_err('wrong parameter');

Valeurs par défaut et paramètres nommés

J'ai amélioré la syntaxe et ajouté des valeurs par défaut à la définition de la fonction. Si vous l'appelez sans paramètres (ou un seul) et les valeurs par défaut seront utilisées pour les valeurs manquantes. En combinaison avec des paramètres nommés , vous pouvez faire à peu près n'importe quoi. Exemples:

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