Generieren Sie eine Ausnahme mit einem Kontext

13

Wenn PostgreSQL eine Ausnahme auslöst, gibt es eine Zeile "CONTEXT" wie:

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

Aber wenn ich eine Ausnahme mache, ist diese Zeile nicht vorhanden. Ich habe nicht gefunden, wie ich es hinzufügen soll.

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

Kann ich diese Zeile zu meiner Ausnahme hinzufügen?

QUentin
quelle

Antworten:

13

Ich konnte keine direkte Möglichkeit finden, die CONTEXTZeile mit einer benutzerdefinierten Ausnahme auszugeben . Diese Option ist (noch) nicht in PostgreSQL 9.1 implementiert. Lesen Sie das Handbuch hier .
Ich fand jedoch eine ...

Umgehung

... das sollte einwandfrei funktionieren . Sie können plpgsql dazu bringen, sich wie gewünscht zu verhalten, indem Sie eine andere Funktion aufrufen, die den Fehler für Sie auslöst. Dies funktioniert mit PostgreSQL 9.0 oder höher .
Für die Version 8.4 müssen Sie eine geringfügige Anpassung vornehmen: Parameter können nicht zugewiesen werden.

Funktion zum Auslösen eines Fehlers (Warnung, Hinweis, ..) mit einer benutzerdefinierten Meldung und 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';

Verwenden Sie die Funktion, um einen Fehler wie diesen auszulösen:

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;

Anruf:

SELECT test_err('wrong parameter');

Standardwerte und benannte Parameter

Ich habe die Syntax verbessert und der Funktionsdefinition Standardwerte hinzugefügt . Wenn Sie es ohne Parameter (oder nur mit einem) aufrufen, werden die Standardwerte für fehlende Werte verwendet. In Kombination mit benannten Parametern können Sie so ziemlich alles tun. Beispiele:

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