oracle - 将触发器从 Oracle 11g 迁移到 Postgresql 8.4

标签 oracle postgresql oracle11g postgresql-8.4 triggers

我在 Oracle 中的触发器看起来像这样......

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;

我以为我可以用这个简单地翻译成 Postgresql……

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;

我在 INSERT 语句末尾遇到错误。 Postgresql 中没有匿名 block 吗?我必须把它放在一个函数中吗?如果是这样,函数的返回值是多少?空?

编辑:

所以我现在正在尝试这个......

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;

函数通过触发器报告编译没有错误......

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

最佳答案

Postgres 中的触发器不直接提供触发器代码,而是调用一个触发器函数,它可以从任意数量的触发器中调用,尽管它们通常是为一个特定表上的一个特定事件定制的.

触发函数:

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()
  • 将其设为 AFTER 触发器以进行简化。 BEFORE 触发器必须 RETURN NEW 才能使更新工作,但 NEWDELETE 触发器中不可见.所以你需要 IF TG_OP = ...

  • 始终为持久化的 INSERT 语句提供目标列表。这在 Oracle 触发器中同样糟糕。

  • 您可能有一个包含 serial 列的表。只是不要在插入中提及它,序列中的下一个 ID 会自动插入。

SO 上有很多代码示例。

关于oracle - 将触发器从 Oracle 11g 迁移到 Postgresql 8.4,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25536275/

相关文章:

sql - 处理递归 cte 中的大量列

sql - 检查 Oracle 中是否存在记录的最有效方法是什么?

Oracle Select * 返回行但 Select count(1) 返回 0

java - 性能 : Writing oracle ResultSet into XLSX using Java, Apache-POI

postgresql - 奇怪的 postgres 序列行为

ruby-on-rails - 生成连接多个表并对某些列求和的 PostgreSQL 查询

sql - 使用键作为列将主表数据与另一个表中的键值属性连接起来

Oracle SQL Developer SQL 工作表未打开

Oracle 分析滚动百分位数

sql - ORA-01877 : string is too long for internal buffer