我编写了一个程序STRING_SESTAVLJEN_ENAKOST_TABEL('MERILA_STRANKE')
,它生成了我想要执行的代码的一部分(一些if if语句)
IF ((new.LOKACIJA IS DISTINCT FROM old.LOKACIJA )
OR (new.MODIFIED IS DISTINCT FROM old.MODIFIED )
OR (new.KARAKTERISTIKE IS DISTINCT FROM old.KARAKTERISTIKE )
OR (new.LETNIK IS DISTINCT FROM old.LETNIK )
OR (new.ID_PNS_CERT_POS IS DISTINCT FROM old.ID_PNS_CERT_POS )
OR (new.ID_PNS_CERT_POS IS DISTINCT FROM old.ID_PNS_CERT_POS ))
我希望在触发器中调用它,然后添加一些代码并将它们一起运行。
代码是:
SET TERM ^ ;
ALTER TRIGGER BI_MERILA_STRANKE ACTIVE
BEFORE INSERT OR UPDATE POSITION 0
AS
declare variable besedilo_primerjave varchar(5000);
BEGIN
begin
if (new.ID_MERILA_STRANKE is null OR new.ID_MERILA_STRANKE = 0) then new.ID_MERILA_STRANKE = gen_id(GEN_ID_MERILA_STRANKE,1);
end
begin
execute procedure STRING_SESTAVLJEN_ENAKOST_TABEL('MERILA_STRANKE')
returning_values :besedilo_primerjave;
execute statement besedilo_primerjave || ' THEN BEGIN INSERT INTO SYNC_INFO(TABLE_NAME,ID_COLUMN_NAME,ID_VALUE,DATETIME)
VALUES (
''MERILA_STRANKE'',
''ID_MERILA_STRANKE'',
NEW.ID_MERILA_STRANKE,
CURRENT_TIMESTAMP
);
END ELSE BEGIN
exception ENAK_RECORD;
END';
end
END^
SET TERM ; ^
现在,当我运行更新并触发触发器时,我收到此错误:
SQL消息:-104无效令牌
引擎代码:335544569引擎消息:动态SQL错误SQL 错误代码= -104令牌未知 - 第1行,第1列IF
另一方面,如果我这样写:
SET TERM ^ ;
ALTER TRIGGER BI_MERILA_STRANKE ACTIVE
BEFORE INSERT OR UPDATE POSITION 0
AS
BEGIN
begin
if (new.ID_MERILA_STRANKE is null OR new.ID_MERILA_STRANKE = 0) then new.ID_MERILA_STRANKE = gen_id(GEN_ID_MERILA_STRANKE,1);
end
begin
IF ((new.LOKACIJA IS DISTINCT FROM old.LOKACIJA )
OR (new.MODIFIED IS DISTINCT FROM old.MODIFIED )
OR (new.KARAKTERISTIKE IS DISTINCT FROM old.KARAKTERISTIKE )
OR (new.LETNIK IS DISTINCT FROM old.LETNIK )
OR (new.ID_PNS_CERT_POS IS DISTINCT FROM old.ID_PNS_CERT_POS )
OR (new.ID_PNS_CERT_POS IS DISTINCT FROM old.ID_PNS_CERT_POS ))
THEN BEGIN
INSERT INTO SYNC_INFO(TABLE_NAME,ID_COLUMN_NAME,ID_VALUE,DATETIME)
VALUES (
'MERILA_STRANKE',
'ID_MERILA_STRANKE',
NEW.ID_MERILA_STRANKE,
CURRENT_TIMESTAMP
);
END ELSE BEGIN
exception ENAK_RECORD;
END
end
END^
SET TERM ; ^
它可以正常工作。我不明白为什么它不会运行,如果是或多或少相同的代码。
答案 0 :(得分:3)
正如我在上一个问题中所提到的,execute statement
不能用于执行PSQL(程序SQL)的片段,它只能执行普通的DSQL(动态SQL)。由于它不了解PSQL,因此“{token}”会出现“令牌未知 - 如果”错误,因为if
在DSQL中无效。
execute statement
相当于自己从查询工具或应用程序执行SQL(它使用相同的API),你也不能在那里使用if
。
使用execute block
语句存在漏洞,但仍然不允许您访问NEW
(或OLD
)触发器上下文变量,除非作为参数显式传递,这将否定动态生成的代码在此上下文中的大部分用处。
唯一真正的解决方案是编写触发器而不是动态执行,也许使用代码生成器(我不确定是否存在,否则你需要自己编写)。