如何根据使用触发器修改的记录的值更新另一个表上的记录

时间:2013-01-31 13:43:21

标签: triggers sql-update firebird

我有两个简单的(仅用于解释我的问题)表

  1. X与列(以及其他):IDX,CODE,NUMBER
  2. Y with columns(以及其他):CODE,NUMBER,id_fromX
  3. 我想(在插入或更新表X之后)使用来自X的实际记录中的变量更新表Y. 为此,我尝试使用触发器(在表X中),如下所示:

    SET TERM ^^ ;
    CREATE TRIGGER XYZFOR X ACTIVE AFTER INSERT OR UPDATE POSITION 0 AS
    begin
      if  (new.CODE is distinct old.CODE)  then
      BEGIN
      EXECUTE STATEMENT ('UPDATE Y SET CODE=:old.CODE, id_fromX=:old.IDX WHERE NUMBER=:old.NUMBER');
      END
    end ^^
    

    但我从服务器收到错误:

    Execute statement error at jrd8_prepare :\
    335544569 : Dynamic SQL Error
    335544436 : SQL error code = -104
    335544634 : Token unknown - line 1, column 23
    335544382 : .
    Statement : UPDATE Y SET CODE=:old.CODE, id_fromX=:old.IDX WHERE NUMBER=:old.NUMBER\
    Data source : Internal::
    At trigger 'XYZ' line: 15, col: 7
    

    如下所示的静态更新:

    CREATE TRIGGER XYZ FOR X ACTIVE AFTER INSERT OR UPDATE POSITION 0 AS
    begin
    if  (new.CODE is distinct from old.CODE)  then
    BEGIN
    EXECUTE STATEMENT ('UPDATE Y SET CODE=1, id_fromX=111 WHERE NUMBER=1');
    END
    end ^^
    SET TERM ; ^^
    

    完美无缺。 如何引用X表字段来更新表Y(具有相似名称的字段)?

4 个答案:

答案 0 :(得分:5)

您使用冒号,但旧/新记录不使用冒号。另外,这里不要使用execute语句,因为sql语句是静态的。

将其更改为:

SET TERM ^^ ;
CREATE TRIGGER XYZFOR X ACTIVE AFTER INSERT OR UPDATE POSITION 0 AS
begin
  if  (new.CODE is distinct old.CODE)  then
  BEGIN
    UPDATE Y 
       SET CODE = old.CODE, id_fromX = old.IDX 
     WHERE NUMBER = old.NUMBER;
  END
end ^^

答案 1 :(得分:2)

您不能将参数直接写入EXECUTE STATEMENT的语句中,有关正确的语法,请参阅documentation。基本上,它应该像

EXECUTE STATEMENT ('UPDATE Y SET CODE = :CODE, id_fromX = :IDX WHERE NUMBER=:NUMBER')
(CODE := old.CODE, IDX := old.IDX, NUMBER := old.NUMBER);

但实际上你不需要EXECUTE STATEMENT,直接使用UPDATE语句。

答案 2 :(得分:2)

您不能在old.<column>中使用触发器上下文变量(new.<column>EXECUTE STATEMENT),因为它们是单独的上下文(EXECUTE STATEMENT中的语句无法看到它们)。您需要使用普通UPDATE语句而不诉诸EXECUTE STATEMENT,否则您应该通过parameters。像:

EXECUTE STATEMENT 
   ('UPDATE Y SET CODE=:code, id_fromX=:idx WHERE NUMBER=:number') 
   (code := old.CODE, idx := old.IDX, number := old.NUMBER);

答案 3 :(得分:0)

不应该:old.CODE老了.CODE?