Hallo, ich versuche gerade eine Art Historisierung umzusetzen. Also soll beim Datensatzlöschen stattdessen ein Update stattfinden, außerdem sollen alle Datensätze die den betroffennen Datensatz mittels Fremdschlüsselbeziehungen referenzieren ebenfalls historisiert werden usw.
Leider verstehe ich nicht wieso die Tabelle t3 dadurch nicht beeinflusst wird, eigentlich sollten alle Datensätze in allen Tabellen dadurch historisiert werden.Code:DROP TABLE IF EXISTS t1 CASCADE; DROP TABLE IF EXISTS t2 CASCADE; DROP TABLE IF EXISTS t3 CASCADE; CREATE TABLE t1(id integer primary key, value real, archive_date timestamp, reference_id integer); CREATE TABLE t2(id integer primary key, value real, t1_id integer, archive_date timestamp, reference_id integer, FOREIGN KEY (t1_id) REFERENCES t1 (id) MATCH FULL ON UPDATE CASCADE ON DELETE CASCADE); CREATE TABLE t3(id integer primary key, value real, t2_id integer, archive_date timestamp, reference_id integer, FOREIGN KEY (t2_id) REFERENCES t2 (id) MATCH FULL ON UPDATE CASCADE ON DELETE CASCADE); CREATE OR REPLACE RULE _delete AS ON DELETE TO t1 DO INSTEAD (UPDATE t1 SET archive_date = now(), reference_id = id WHERE id = OLD.id AND archive_date IS NULL; DELETE FROM t2 WHERE t1_id = OLD.id AND archive_date IS NULL;); CREATE OR REPLACE RULE _delete AS ON DELETE TO t2 DO INSTEAD (UPDATE t2 SET archive_date = now(), reference_id = id WHERE id = OLD.id AND archive_date IS NULL; DELETE FROM t3 WHERE t2_id = OLD.id AND archive_date IS NULL;); CREATE OR REPLACE RULE _delete AS ON DELETE TO t3 DO INSTEAD UPDATE t3 SET archive_date = now(), reference_id = id WHERE id = OLD.id AND archive_date IS NULL; INSERT INTO t1(id, value) VALUES (1,10); INSERT INTO t2(id, value, t1_id) VALUES (1,10,1); INSERT INTO t3(id, value, t2_id) VALUES (1,10,1); DELETE FROM t1; test=# select * from t1; select * from t1; id | value | archive_date | reference_id ----+-------+-------------------------+-------------- 1 | 10 | 2010-02-12 16:05:50.312 | 1 (1 Zeile) test=# select * from t2; select * from t2; id | value | t1_id | archive_date | reference_id ----+-------+-------+-------------------------+-------------- 1 | 10 | 1 | 2010-02-12 16:05:50.312 | 1 (1 Zeile) test=# select * from t3; select * from t3; id | value | t2_id | archive_date | reference_id ----+-------+-------+--------------+-------------- 1 | 10 | 1 | | (1 Zeile)
Danke
Alger
Xandrian: Kurz gesagt: Du hast ein falsches Konzept und willst nicht auf ads hören
Jetzt NEU: PostgreSQL - Datenbankpraxis für Anwender, Administratoren und Entwickler
PostgreSQL Service & Support
Hallo Ads,
danke für den tipp, aber möchte an meinem Konzept festhalten, mich interessiert wieso MEINE Lösung nicht funktioniert.
Weil Du nicht auf ads hörst!
AndreasCode:test=# DROP TABLE IF EXISTS t1 CASCADE; NOTICE: drop cascades to constraint t2_id_t1_fkey on table t2 DROP TABLE Zeit: 1,755 ms test=*# DROP TABLE IF EXISTS t2 CASCADE; DROP TABLE Zeit: 0,525 ms test=*# DROP TABLE IF EXISTS t3 CASCADE; NOTICE: table "t3" does not exist, skipping DROP TABLE Zeit: 0,074 ms test=*# CREATE TABLE t1(id integer primary key, value real, archive_date timestamp, reference_id integer); NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t1_pkey" for table "t1" CREATE TABLE Zeit: 5,820 ms test=*# CREATE TABLE t2(id integer primary key, value real, t1_id integer, archive_date timestamp, reference_id integer, test(# FOREIGN KEY (t1_id) REFERENCES t1 (id) MATCH FULL ON UPDATE CASCADE ON DELETE CASCADE); NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t2_pkey" for table "t2" CREATE TABLE Zeit: 12,127 ms test=*# CREATE TABLE t3(id integer primary key, value real, t2_id integer, archive_date timestamp, reference_id integer, test(# FOREIGN KEY (t2_id) REFERENCES t2 (id) MATCH FULL ON UPDATE CASCADE ON DELETE CASCADE); NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t3_pkey" for table "t3" CREATE TABLE Zeit: 4,732 ms test=*# test=*# CREATE OR REPLACE RULE _delete AS test-# ON DELETE TO t1 test-# DO INSTEAD test-# (UPDATE t1 SET archive_date = now(), reference_id = id test(# WHERE id = OLD.id AND archive_date IS NULL; test(# DELETE FROM t2 WHERE t1_id = OLD.id AND archive_date IS NULL;); CREATE RULE Zeit: 0,744 ms test=*# test=*# CREATE OR REPLACE RULE _delete AS test-# ON DELETE TO t2 test-# DO INSTEAD test-# (DELETE FROM t3 WHERE t2_id = OLD.id AND archive_date IS NULL; test(# UPDATE t2 SET archive_date = now(), reference_id = id test(# WHERE id = OLD.id AND archive_date IS NULL;); CREATE RULE Zeit: 0,712 ms test=*# test=*# CREATE OR REPLACE RULE _delete AS test-# ON DELETE TO t3 test-# DO INSTEAD test-# UPDATE t3 SET archive_date = now(), reference_id = id test-# WHERE id = OLD.id AND archive_date IS NULL; CREATE RULE Zeit: 0,496 ms test=*# test=*# INSERT INTO t1(id, value) VALUES (1,10); INSERT 0 1 Zeit: 0,339 ms test=*# INSERT INTO t2(id, value, t1_id) VALUES (1,10,1); INSERT 0 1 Zeit: 0,456 ms test=*# INSERT INTO t3(id, value, t2_id) VALUES (1,10,1); INSERT 0 1 Zeit: 0,447 ms test=*# test=*# DELETE FROM t1; DELETE 0 Zeit: 1,085 ms test=*# select * from t1; id | value | archive_date | reference_id ----+-------+----------------------------+-------------- 1 | 10 | 2010-02-12 17:27:41.398094 | 1 (1 Zeile) Zeit: 0,102 ms test=*# select * from t2; id | value | t1_id | archive_date | reference_id ----+-------+-------+----------------------------+-------------- 1 | 10 | 1 | 2010-02-12 17:27:41.398094 | 1 (1 Zeile) Zeit: 0,097 ms test=*# select * from t3; id | value | t2_id | archive_date | reference_id ----+-------+-------+----------------------------+-------------- 1 | 10 | 1 | 2010-02-12 17:27:41.398094 | 1 (1 Zeile) Zeit: 0,094 ms test=*#
--
Papa-Kind-Kur vom 8. bis 29. September ;-)
PostgreSQL Hosting
http://www.amazon.de/gp/registry/2APKFICAIYMWBads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
https://www.xing.com/profile/Andreas_Kretschmer7
Danke Andreas, könntest du mit kurz erklären, wieso die Reihenfolge der Statements hier Unterschied ausmacht? Alger
--
Papa-Kind-Kur vom 8. bis 29. September ;-)
PostgreSQL Hosting
http://www.amazon.de/gp/registry/2APKFICAIYMWBads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
https://www.xing.com/profile/Andreas_Kretschmer7
Also, ich bin ehrlich:
ich kann es nicht *genau* erklären. Ich hab grad mit jemand gesprochen, der da mehr Plan hat als ich. Das Problem ist, daß bei mehreren Befehlen in einer Rule u.U. durch den ersten Befehl in nachfolgenden Befehlen die Sichtbarkeit von Variablen (OLD, NEW) bzw. allgemein die Sichtbarkeit der Tupel nicht mehr gegeben ist bzw. wenn man ein Tupel updatet, auf den man später nochmals referenziert, dann gibt es Probleme.
Ich hab grad nicht wirklich Zeit und Ruhe, da mehr drüber nachzudenken, und vielleicht sagt jemand anders da noch was dazu.
Andreas
--
Papa-Kind-Kur vom 8. bis 29. September ;-)
PostgreSQL Hosting
http://www.amazon.de/gp/registry/2APKFICAIYMWBads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
https://www.xing.com/profile/Andreas_Kretschmer7
Links: Tobias Bauer - IT- und Funkdienstleistungen - Bilderrahmen-kaufen.de - Der Onlineshop für Bilderrahmen & Fotorahmen - Funkforum
Lesezeichen