+ Antworten
Ergebnis 1 bis 7 von 7

Thema: RULE-Problem

  1. #1
    alger ist offline Neuer Benutzer
    Registriert seit
    14.12.2009
    Beiträge
    14

    Standard RULE-Problem

    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.
    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)
    
    Leider verstehe ich nicht wieso die Tabelle t3 dadurch nicht beeinflusst wird, eigentlich sollten alle Datensätze in allen Tabellen dadurch historisiert werden.

    Danke

    Alger

  2. #2
    ads
    ads ist gerade online Moderator
    Registriert seit
    08.02.2006
    Ort
    MD
    Beiträge
    3.408

    Standard

    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

  3. #3
    alger ist offline Neuer Benutzer
    Registriert seit
    14.12.2009
    Beiträge
    14

    Standard

    Hallo Ads,

    danke für den tipp, aber möchte an meinem Konzept festhalten, mich interessiert wieso MEINE Lösung nicht funktioniert.

  4. #4
    akretschmer ist offline Erfahrener Benutzer
    Registriert seit
    29.10.2006
    Ort
    Nähe Dresden
    Beiträge
    4.478

    Standard

    Zitat Zitat von alger Beitrag anzeigen
    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!

    Code:
    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=*#
    
    Andreas
    --
    Papa-Kind-Kur vom 8. bis 29. September ;-)
    PostgreSQL Hosting
    ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
    http://www.amazon.de/gp/registry/2APKFICAIYMWB
    https://www.xing.com/profile/Andreas_Kretschmer7

  5. #5
    alger ist offline Neuer Benutzer
    Registriert seit
    14.12.2009
    Beiträge
    14

    Standard

    Danke Andreas, könntest du mit kurz erklären, wieso die Reihenfolge der Statements hier Unterschied ausmacht? Alger

  6. #6
    akretschmer ist offline Erfahrener Benutzer
    Registriert seit
    29.10.2006
    Ort
    Nähe Dresden
    Beiträge
    4.478

    Standard

    Zitat Zitat von alger Beitrag anzeigen
    Danke Andreas, könntest du mit kurz erklären, wieso die Reihenfolge der Statements hier Unterschied ausmacht? Alger
    Nein.

    Andreas
    --
    Papa-Kind-Kur vom 8. bis 29. September ;-)
    PostgreSQL Hosting
    ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
    http://www.amazon.de/gp/registry/2APKFICAIYMWB
    https://www.xing.com/profile/Andreas_Kretschmer7

  7. #7
    akretschmer ist offline Erfahrener Benutzer
    Registriert seit
    29.10.2006
    Ort
    Nähe Dresden
    Beiträge
    4.478

    Standard

    Zitat Zitat von akretschmer Beitrag anzeigen
    Nein.

    Andreas
    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
    ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
    http://www.amazon.de/gp/registry/2APKFICAIYMWB
    https://www.xing.com/profile/Andreas_Kretschmer7

+ Antworten

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein

Links: Tobias Bauer - IT- und Funkdienstleistungen   -   Bilderrahmen-kaufen.de - Der Onlineshop für Bilderrahmen & Fotorahmen   -   Funkforum