Problem mit After Trigger

Hallo,

ich habe 2 Tabellen: “orderbook” und “orderkook_history”. Wenn in “orderbook” etwas eingetragen wird soll es in “orderkook_history” archiviert werden:

CREATE OR REPLACE FUNCTION order_archiv()

RETURNS trigger AS
$$  
begin

   if (TG_OP='INSERT') then
     insert into ORDERBOOK_HISTORY VALUES (new.ORDERBOOK_ID, new.STATUS_TIMESTAMP, new.DELIVERY_STATUS_TYPE,null,new.FETCHING_STATUS_TYPE, new.SOURCE_INFORMATION_TYPE, new.SOURCE_INFORMATION_ID, new.DRIVER_ID);
   end if;

  RETURN NULL;
end
$$
LANGUAGE 'plpgsql';



CREATE TRIGGER trg_order_archiv AFTER INSERT  
ON orderbook FOR EACH ROW 
EXECUTE PROCEDURE order_archiv()

Mein Problem ist das “orderbook_history” einen Fremdschlüssel auf “orderbook” hat. Es wird mir eine Fehlermeldung ausgegeben, weil “orderbook_history” keinen passenden Eintrag in “orderbook” findet:

FEHLER: Einfügen oder Aktualisieren in Tabelle »orderbook_history« verletzt Fremdschlüssel-Constraint »orderbook_history_orderbook_id_fkey«
DETAIL: Schlüssel (orderbook_id)=(121) ist nicht in Tabelle »orderbook« vorhanden.

Ich habe doch einen After Trigger geschrieben. Warum ist der Eintrag in der Tabelle “orderbook” nicht schon eingetragen? Warum arbeitet mein Trigger wie ein Before Trigger?

Ich hoffe, ich könnt mir helfen.

Return NULL ist da, ähm, kontraproduktiv. Tausche NULL gegen NEW.

test=*# create table foo(id serial primary key);
NOTICE:  CREATE TABLE will create implicit sequence "foo_id_seq" for serial column "foo.id"
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "foo_pkey" for table "foo"
CREATE TABLE
Zeit: 136,755 ms
test=*# commit;
COMMIT
Zeit: 0,873 ms
test=# create table foo_history(id serial primary key);
NOTICE:  CREATE TABLE will create implicit sequence "foo_history_id_seq" for serial column "foo_history.id"
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "foo_history_pkey" for table "foo_history"
CREATE TABLE
Zeit: 31,209 ms
test=*# commit;
COMMIT
Zeit: 0,392 ms
test=# create or replace function save_foo() returns trigger as $$begin insert into foo_history values (new.id); return new; end; $$language plpgsql;
CREATE FUNCTION
Zeit: 78,938 ms
test=*# commit;
COMMIT
Zeit: 0,407 ms
test=# create trigger trg_foo after insert on foo for each row execute procedure save_foo();
CREATE TRIGGER
Zeit: 24,260 ms
test=*#
test=*#
test=*# commit;
COMMIT
Zeit: 0,400 ms
test=# insert into foo values (1);
INSERT 0 1
Zeit: 1,256 ms
test=*# select * from foo_history;
 id
----
  1
(1 Zeile)

Andreas

Danke! Das war die Lösung. :smiley:

Kann ich “Return NEW” immer als Rückgabe bei einem Trigger verwenden? Wann sollte ich “Return NULL” verwenden?

wobei es das nicht ist, denn dies funktioniert:

test=# create table foo(id serial primary key);
NOTICE:  CREATE TABLE will create implicit sequence "foo_id_seq" for serial column "foo.id"
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "foo_pkey" for table "foo"
CREATE TABLE
Zeit: 24,009 ms
test=*# create table foo_history(id serial references foo);
NOTICE:  CREATE TABLE will create implicit sequence "foo_history_id_seq" for serial column "foo_history.id"
CREATE TABLE
Zeit: 18,740 ms
test=*# create or replace function save_foo() returns trigger as $$begin if TG_OP = 'INSERT' then insert into foo_history values (new.id); end if;return null; end; $$language plpgsql;
CREATE FUNCTION
Zeit: 0,419 ms
test=*# create trigger trg_foo after insert on foo for each row execute procedure save_foo();
CREATE TRIGGER
Zeit: 0,630 ms
test=*# insert into foo values (1);
INSERT 0 1
Zeit: 1,050 ms
test=*# select * from foo;
 id
----
  1
(1 Zeile)

Zeit: 0,274 ms
test=*# select * from foo_history;
 id
----
  1
(1 Zeile)

Andreas

Ähm, bei AFTER-Triggern ist das relativ Banane …


Andreas

Na anscheinend nicht, denn mit NULL hat es nicht funktioniert und mit NEW funktioniert es.