Postgres aktualisieren ein Datumsfeld, wenn ein boolean Feld auf true gesetzt ist
-
05-07-2019 - |
Frage
Aus Gründen des Betrachten Sie als Beispiel eine Tabelle
create table foo (
contents text NOT NULL,
is_active boolean NOT NULL DEFAULT false,
dt_active date
)
Ich lege einen Datensatz:
insert into foo (contents) values ('bar')
So weit, so gut. Später möchte ich jetzt ‚aktivieren‘ die Aufzeichnung:
update foo set is_active = true
Was Ich mag würde tun, wenn is_active
von false
geändert wird, true
ist für dt_active
eingestellt ist now()
. Für Bonuspunkte wäre es schön, wenn is_active
von true
geändert wird fals
e, dt_active auf null gesetzt wird, aber ich kann ohne leben.
Ich möchte wirklich dieses Housekeeping in die Datenbank schieben, wäre es den Client-Code viel sauberer machen (da viele Tabellen (und sogar Spalte Tupel innerhalb von Tabellen) von dieser Technik profitieren könnten).
Ich bin ratlos, wie in den Auslöser, um den aktuellen Datensatz in der Datenbank zu ziehen (ich verwende plpgsql), um die „dann“ mit dem „jetzt“ zu vergleichen. Zeiger auf Code-Beispiele oder Schnipsel sehr geschätzt.
Lösung
CREATE OR REPLACE FUNCTION trg_update_foo() RETURNS TRIGGER AS
$BODY$
BEGIN
IF OLD.is_active = false AND NEW.is_active = true THEN
NEW.dt_active := now();
ELSIF OLD.is_active = true AND NEW.is_active = false THEN
NEW.dt_active := NULL;
END IF;
RETURN NEW;
END;
$BODY$
LANGUAGE 'plpgsql';
CREATE TRIGGER trg_update_foo BEFORE UPDATE ON foo FOR EACH ROW EXECUTE PROCEDURE trg_update_foo();
Sollte funktionieren. Für weitere Informationen besuchen pl / PgSQL Trigger manuell und für Extra-Punkte -. whole plpgsql docs
Andere Tipps
In Ihrem plpgsql Triggerprozedur haben Sie Zugriff auf einige spezielle Datensatz-Typ Variablen namens NEW
und OLD
, die für Sie erstellt werden.
In einem UPDATE
oder INSERT
Trigger, NEW
wird die Aufzeichnung der neuen Datenbankzeile darstellen.
In einem UPDATE
oder DELETE
Trigger OLD
den Wert der ursprünglichen Datenbank Zeile darstellen.
In anderen Kontext Erklärung wird dieser Rekord Variablen NULL
werden.
Daher scheint es, wie Sie ein INSERT OR UPDATE
Trigger erstellen müssen, die auf den Werten von OLD.is_active
und NEW.is_active
aussieht.
Hier ist die Dokumentation Seite - http: //www.postgresql. org / docs / 8.1 / interactive / plpgsql-trigger.html Diese Seite enthält Beispielcode für plpgsql die NEW
und OLD
Haben Sie versucht, die Handbuch ?
Jeder Trigger-Funktion hat einige automatische Variablen. Im Falle einer Aktualisierung löst die alten Zeilen Werte sind zugänglich über OLD
und die geänderten Werte über NEW
Sie können einfach überprüfen Sie die Spalte Wert von OLD durch OLD.is_active
. Auf die gleiche Weise können Sie die Werte ändern können in der Datenbank wie NEW.dt_active := now();
gesetzt werden
Hope this hels.
CREATE FUNCTION actrigger() RETURNS TRIGGER AS $$ BEGIN
IF TG_OP='UPDATE' THEN
IF NEW.is_active THEN
IF NOT OLD.is_active THEN
NEW.dt_active := current_date;
END IF;
ELSIF NEW.dt_active IS NOT NULL
NEW.dt_active := NULL;
END IF;
END IF;
RETURN NEW;
END; $$ LANGUAGE plpgsql;
CREATE TRIGGER foobefore BEFORE UPDATE ON foo FORR EACH ROW
EXECUTE PROCEDURE actrigger();
Und Sie können auch von INSERT
kümmern, der außer ziemlich ähnlich sein würde, es nicht zu OLD
beziehen.