问题
My trigger in Oracle looks like this…
CREATE OR REPLACE TRIGGER example$example
BEFORE UPDATE OR DELETE ON example
FOR EACH ROW
BEGIN
INSERT INTO
example$
VALUES
(
:old.key,
:old.name,
:old.describe
seq.nextVal
);
END;
I thought I could simply translate to Postgresql with this…
CREATE OR REPLACE TRIGGER example$example
BEFORE UPDATE OR DELETE ON example
FOR EACH ROW
BEGIN
INSERT INTO
example$
VALUES
(
OLD.key,
OLD.name,
OLD.describe,
NEXTVAL('seq')
);
END;
I'm getting an error at the end of the INSERT statement. Are there no anonymous blocks in Postgresql? Do I have to put this in a function? If so, what is the return value of the function? NULL?
EDIT:
So I'm now trying this…
CREATE OR REPLACE FUNCTION example$trigger()
RETURNS TRIGGER AS
$func$
BEGIN
INSERT INTO
example$
(
key,
name,
describe,
seq
)
VALUES
(
OLD.key,
OLD.name,
OLD.describe,
NEXTVAL('seq')
);
END
$func$ LANGUAGE plpgsql
CREATE OR REPLACE TRIGGER example$trigger
AFTER UPDATE OR DELETE ON example
FOR EACH ROW
EXECUTE PROCEDURE example$trigger;
The function compiles with no errors by the trigger reports…
ERROR: syntax error at or near "TRIGGER"
LINE 1: CREATE OR REPLACE TRIGGER example$trigger
^
********** Error **********
ERROR: syntax error at or near "TRIGGER"
SQL state: 42601
Character: 19
回答1:
Triggers in Postgres don't provide trigger code directly, but call a trigger function, which can be called from any number of triggers, though often they are customized for one particular event on one particular table.
Trigger function:
CREATE OR REPLACE FUNCTION trg_some_tbl_foo()
RETURNS trigger AS
$func$
BEGIN
INSERT INTO some_tbl(key, name, describe) -- or some_other_tbl?
VALUES (OLD.key, OLD.name, OLD.describe);
RETURN OLD;
END
$func$ LANGUAGE plpgsql
Trigger:
CREATE TRIGGER foo -- not: "CREATE OR REPLACE" !
AFTER UPDATE OR DELETE ON some_tbl
FOR EACH ROW EXECUTE PROCEDURE trg_some_tbl_foo()
Make it an
AFTER
trigger to simplify. ABEFORE
trigger would have toRETURN NEW
to make updates work, butNEW
is not visible in aDELETE
trigger. So you'd needIF TG_OP = ...
etc.Always provide a target list for persisted
INSERT
statements. This is just as bad in an Oracle trigger.You probably have a table with a
serial
column. Just don't mention it in the insert, the next id from the sequence is inserted automatically.
There are numerous code examples here on SO.
来源:https://stackoverflow.com/questions/25536275/migrating-trigger-from-oracle-11g-to-postgresql-8-4