2014-08-27 83 views
0

我在Oracle触发器看起来像这样...从的Oracle 11g触发迁移到PostgreSQL 8.4

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中没有匿名块吗?我必须把它放在一个函数中吗?如果是这样,函数的返回值是多少?空值?

编辑:

所以我现在想要这个...

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 
+2

请阅读手册:http://www.postgresql.org/docs/current/static/plpgsql-trigger.html另外:为什么你会迁移到Postgres 8.4? 8.4已经报废,不再支持 – 2014-08-27 20:32:40

+1

@a_horse_with_no_name这就是为什么我学会了讨厌stackoverflow。任何人都可以做的最好的事情就是告诉我RTFM,就好像我还没有那样做。 – dacracot 2014-08-28 01:39:37

+1

a_horse没有问你如何看待SO,但为什么你想迁移到过时的Postgres版本。一个有效的问题,看起来像一个很大的错误。另外,这个问题应该提供一些解释触发器应该做什么。我可以猜到,但我不应该。普通大众可能没有那么有经验。 – 2014-08-28 02:38:30

回答

4

触发的Postgres别t直接提供触发代码,但调用触发功能,可以从任何数量调用触发器,尽管它们经常被定制为一个特定表上的特定事件。

触发功能:

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触发简化。 A BEFORE触发器必须RETURN NEW才能使更新正常工作,但在DELETE触发器中不可见。所以你需要IF TG_OP = ...

  • 总是提供持续INSERT陈述的目标列表。这在Oracle触发器中同样糟糕。

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

这里有很多关于SO的代码示例。

+0

触发器创建中存在语法错误。 – dacracot 2014-08-28 15:26:28

+0

@dacracot:['CREATE TRIGGER',没有'CREATE OR REPLACE TRIGGER'](http://www.postgresql.org/docs/current/interactive/sql-createtrigger.html)。 – 2014-08-28 15:31:50