Mehrere Funktionen vom Trigger aus aufrufen?

8

Ich führe PostgreSQL-9.2.4 aus

Ist es möglich, 2 Funktionen von einem Trigger aus aufzurufen?

Angenommen, ich habe zwei Funktionen für zwei verschiedene Tabellen, die ausgeführt werden sollen, wenn folgende Triggerbrände auftreten:

Auslösen:

CREATE TRIGGER start ON system_status FOR EACH ROW
WHEN ((new.event = start_task))
EXECUTE PROCEDURE ...()

Funktion 1: (Wenn die Aufgabe startet => Entfernen Sie alle zuvor zugewiesenen nächsten Aufgaben für dieses System.)

CREATE FUNCTION void_next_task() RETURNS trigger AS $$

BEGIN
  DELETE FROM tasks_status ts
  WHERE ts.system = NEW.system
  AND ts.event = 'next_task';
  RETURN NEW;
  END;

$$

LANGUAGE plpgsql

Funktion 2: (Wenn eine Kombination von eingefügt taskund systembereits in der Tabelle dargestellt ist => Markieren Sie frühere Datensätze mit dieser Kombination als deleted)

CREATE FUNCTION void_dup_task() RETURNS trigger AS $$

BEGIN
  UPDATE system_status ss
  SET deleted = 'TRUE'
  WHERE ss.system = NEW.system
  AND ss.task = NEW.task
  AND ss.deleted IS FALSE;
  RETURN NEW;
  END;

$$

LANGUAGE plpgsql

Am Ende hatte ich folgende Möglichkeiten, um das Problem zu beheben:

  1. Einen Trigger haben, der zwei Funktionen aufruft;
  2. Eine Funktion zu haben, die eine Tabelle aktualisiert und eine andere löscht;
  3. Zwei genau gleiche Trigger und zwei verschiedene Funktionen haben;

Bevor ich mit der Implementierung der Lösung 3fortfahre, können Sie mir raten, ob eine Lösung vorliegt 1oder 2überhaupt möglich ist?

VL-80
quelle

Antworten:

10

Ein Trigger kann immer nur eine Tiggerfunktion aufrufen, also nein zu Punkt 1.

Die bevorzugte Form ist Punkt 2. IMO. Sie können so viele SQL-Anweisungen in eine einzelne plpgsql-Funktion einfügen, wie Sie möchten.

Punkt 3. ist ebenfalls möglich. Nun, nicht genau der gleiche Auslöser, der Name müsste anders sein. Auslöser für dasselbe Ereignis werden übrigens in alphabetischer Reihenfolge ausgelöst. Aber ich sehe keinen Gewinn in zwei getrennten Funktionen. Nur mehr Code und Overhead und zwei Funktionsaufrufe, was teurer ist.

2. ist der unbestrittene Sieger.

Erwin Brandstetter
quelle
2

Der Vollständigkeit halber gibt es auch die Nummer 4 - machen Sie gewöhnliche Funktionen, nicht Triggerfunktionen, und rufen Sie beide (oder nur eine, abhängig von einigen Bedingungen) von der Triggerfunktion aus auf. Dies hat mehrere Nachteile: Sie können NEW und OLD nicht in normalen Funktionen verwenden und müssen die Daten an Ihre Funktionen übergeben, was noch mehr Overhead bedeutet als in Fall 3. In Ihrem Fall würde es keinen signifikanten Gewinn dafür geben. Der einzige Vorteil, den ich mir vorstellen kann, ist die Lesbarkeit des Codes für sehr komplexe Triggerfunktionen.

Ich habe dies für eine große, stark verzweigte Funktion getan (einige Überprüfungen und Aktualisierungen für Tabelle A durchführen, dann einige andere Aktualisierungen für Tabelle B, C oder D, abhängig von Spalte A.1, nachdem die Aktualisierungen für B etwas Ähnliches für F oder getan haben G usw.); und trotzdem frage ich mich, ob ich es geteilt halten oder zu einer einzigen Funktion zurückkehren soll.

BEARBEITEN: Ein weiterer Fall, in dem dies nützlich ist, besteht darin, dass einige Teile des Codes von mehreren Triggerfunktionen gemeinsam genutzt werden. Dann kann es nützlich sein, den Code nur einmal zu schreiben und die Funktion aufzurufen, anstatt den gesamten Code erneut zu schreiben. Auch hier lohnt es sich nicht für ein paar Codezeilen wie in Ihrem Fall.

Pavel V.
quelle