Hallo,
ich habe folgendes Problem:
Ich versuch mittels einer Regel (RULE) bei jeder Änderung (UPDATE) einer bestimmten Tabelle in der betreffenden Relation einen TIMESTAMP in das dafür vorgesehenes Datumsfeld zu setzen.
Also in etwa so ...
CREATE RULE rule_name
AS ON UPDATE
TO tabelle
DO
UPDATE tabelle
SET timeNeu = 'now';
Wie nicht anders zu erwarten führt das ganze zu einer Rekursion.
Im PG-Handbuch heißt es, das man mittels einer Regel die eigentliche Abfrage (hier das UPDATE) verändern kann ... und genau das will ich ja ... aber wie mache ich das, wenn sich die Änderung auf die gleiche Tabelle bezieht ?!
Bin für jede Hilfe dankbar !!!
Andreas
--
https://www.xing.com/profile/Andreas_Kretschmer7ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
Hallo Andreas
habe Deinen Hinweis wie folgt ausprobiert:
Zwei Tabellen:
CREATE TABLE tabelle
(
id serial NOT NULL, -- ID, Primärschlüssel
wert varchar(20),
t_stamp timestamp,
CONSTRAINT tabelle_pkey PRIMARY KEY (id)
)
CREATE TABLE tabelle_hist
(
id int4 NOT NULL,
wert varchar(20),
t_stamp timestamp
)
eine Funktion:
CREATE OR REPLACE FUNCTION table_function_histo()
RETURNS "trigger" AS
$BODY$
BEGIN
INSERT INTO tabelle_hist (id, wert, t_stamp)
VALUES (OLD.id, OLD.wert, OLD.t_stamp);
UPDATE tabelle
SET t_stamp = 'now'
where OLD.id = id;
RETURN new;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;
ALTER FUNCTION table_function_histo() OWNER TO postgres;
... und natürlich den TRIGGER:
CREATE TRIGGER trigger_upd
AFTER UPDATE
ON tabelle
FOR EACH ROW
EXECUTE PROCEDURE table_function_histo();
Sobald ich jedoch einen 'wert' in der Tabelle 'tabelle' ändere resultiert daraus eine endlose Rekursion.
Ginge es um meine Datenbank, würde ich die Timestamps zum protokollieren in eine extra Tabelle auslagern ... hätte ja auch noch andere Vorteile.
Der Sinn des UPDATES von dem Timestamp bei jeder Änderung in der Originaltabelle (im Bsp. also 'tabelle') ist die Berücksichtigung bei umfangreichen Matching-Läufen der Datenbank.
Unter Informix kann man den Wert im Trigger direkt mittels 'INTO' in der betreffenden Tabelle ändern z.B. so:
...
FOR EACH ROW
EXECUTE PROCEDURE getTimestamp() INTO NEW.t_stamp;
wobei getTimestamp() einfach einen aktuellen Timestamp zurückliefert.
Kann man ggf. den TRIGGER so einrichten, das sich das UPDATE nur auf die Pseudo-Relation 'NEW' bezieht ?!
Viele Grüße,
Andreas
1. Du willst den neu einzufügenden Datensatz noch verändern (NEW.t_stamp setzen). Dazu brauchst Du einen before - Trigger.
2. Du darfst nicht wieder UPDATE aufrufen, da kommt die Rekursion. Statt dessen modifizierst Du NEW.t_stamp. Dein Beispiel sollte in etwa wie folgt funktionieren:
Code:create or replace function tf() returns TRIGGER as $$ begin INSERT INTO tabelle_hist (id, wert, t_stamp) VALUES (OLD.id, OLD.wert, OLD.t_stamp); NEW.t_stamp := now(); return NEW; end; $$ language plpgsql; create trigger t1 before update on tabelle for each row execute procedure tf();
Andreas
--
https://www.xing.com/profile/Andreas_Kretschmer7ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
--
https://www.xing.com/profile/Andreas_Kretschmer7ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
Super ...
Jetzt klappt es wie gewünscht.
Großes Lob an Dein Engagement und Dein Fachwissen ... so macht Postgres erst richtig Spaß !
Vielen vielen Dank !!!
Andreas
Links: Tobias Bauer - IT- und Funkdienstleistungen - Bilderrahmen-kaufen.de - Der Onlineshop für Bilderrahmen & Fotorahmen - Funkforum
Lesezeichen