Ergebnis 1 bis 6 von 6

Thema: Mittels einer RULE eine UPDATE-Abfrage ändern ...

  1. #1
    kiaaap ist offline Benutzer
    Registriert seit
    08.05.2007
    Ort
    Ulm
    Beiträge
    31

    Standard Mittels einer RULE eine UPDATE-Abfrage ändern ...

    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

  2. #2
    akretschmer ist gerade online Super-Moderator
    Registriert seit
    29.10.2006
    Ort
    Dresden
    Beiträge
    5.472

    Standard

    Zitat Zitat von kiaaap Beitrag anzeigen
    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.
    Nehme einen TRIGGER dafür und alles wird gut.

    Andreas
    --
    ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
    https://www.xing.com/profile/Andreas_Kretschmer7

  3. #3
    kiaaap ist offline Benutzer
    Registriert seit
    08.05.2007
    Ort
    Ulm
    Beiträge
    31

    Standard

    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

  4. #4
    akretschmer ist gerade online Super-Moderator
    Registriert seit
    29.10.2006
    Ort
    Dresden
    Beiträge
    5.472

    Standard

    Zitat Zitat von kiaaap Beitrag anzeigen

    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.


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

  5. #5
    akretschmer ist gerade online Super-Moderator
    Registriert seit
    29.10.2006
    Ort
    Dresden
    Beiträge
    5.472

    Standard

    Zitat Zitat von akretschmer Beitrag anzeigen

    Code:
    ...
    NEW.t_stamp := now();
    return NEW;
    end;
    $$ language plpgsql;
    ...

    Andreas
    Noch nachzutragen ist, daß now() den Startzeitpunkt einer TX zurückgibt. Falls es Dich wundern sollte, warum alle
    Werte, die in einer TX geupdatetet wurden, exakt denselben Timestamp haben, dann tausche now() gegen timeofday() aus.

    Andreas
    --
    ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
    https://www.xing.com/profile/Andreas_Kretschmer7

  6. #6
    kiaaap ist offline Benutzer
    Registriert seit
    08.05.2007
    Ort
    Ulm
    Beiträge
    31

    Daumen hoch Jetzt klappt 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

Ähnliche Themen

  1. Antworten: 9
    Letzter Beitrag: 02.03.2010, 18:38
  2. Problem Kennzeichnung der Values bei Update Rule
    Von drooper im Forum PL/pgSQL
    Antworten: 25
    Letzter Beitrag: 04.10.2009, 18:44
  3. Update einer Tabelle mittels View
    Von ballibum im Forum Benutzer- & Rechteverwaltung
    Antworten: 5
    Letzter Beitrag: 30.09.2009, 12:48
  4. Antworten: 5
    Letzter Beitrag: 30.07.2009, 19:53
  5. Problem Datenübertragung mittels update
    Von eremit im Forum SQL
    Antworten: 10
    Letzter Beitrag: 03.07.2009, 19:22

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