Migrating trigger from Oracle 11g to Postgresql 8.4

我是研究僧i 提交于 2021-02-08 09:27:11

问题


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. A BEFORE trigger would have to RETURN NEW to make updates work, but NEW is not visible in a DELETE trigger. So you'd need IF 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!