oracle,sql,触发器

Posted

技术标签:

【中文标题】oracle,sql,触发器【英文标题】:oracle , sql , trigger 【发布时间】:2016-03-15 14:48:32 【问题描述】:
CREATE TRIGGER "CPI"."TRGPRODOFFRPRICE" 
AFTER UPDATE or INSERT ON CPI_LOADER_EXEMPTIONS
FOR EACH ROW
DECLARE
table_name varchar(32);
BEGIN
 if substr(:new.SID_ID,1,3) = 'POP' then
  table_name := 'PROD_OFFR_PRICE_CHARGE';
 else 
  table_name := 'PROD_OFFR_PRICE_ALTERATION';
 end if;
 execute immediate 'UPDATE  :1 set CPI_EXEMPTION=:2 WHERE SID_ID=:3'   using table_name, :new.FLAG, :new.SID_ID;
END;

基于我编辑成这个表单的 cmets,它看起来更好,但是当试图将值插入到启动触发器的表中时,我收到错误“无效的表名”,知道是什么原因造成的吗?可能有错误的 tab var 声明?

【问题讨论】:

一如既往地从简单开始...让一个简单的触发器正常工作,然后逐步实现上述复杂目标...好处是您遇到的任何错误都可以轻松识别为最后一次更改.. . 尝试上述定义的错误可能指向太多原因 这看起来“不错”,但您想使用完整的动态 sql —— 仅将表作为变量是行不通的 Should I use tags in titles?: "因为标签出现在问题下方,并且标签与您的问题内容一起被搜索引擎索引,您可以相信其他人将能够根据您的问题找到您的问题他们关注或搜索的标签”。我很难编辑您的问题标题(您真正有机会将您的问题“出售”给潜在的回答者),因为它是 完全 标签。请编辑您的标题,使其更具描述性 您不能将标识符(表或列名)作为参数传递给execute immediate。你只能传递真实值 【参考方案1】:

试试这个(真正的 PL/SQL):

CREATE TRIGGER trgSample
AFTER UPDATE or INSERT ON EXEMPTIONS
FOR EACH ROW
DECLARE
   sid varchar(10);
   sidVal varchar(100);
   table_name varchar(32);
   flag int;
BEGIN
  sid   := substr(:new.SID_ID,1,3);
  flag  := :new.FLAG;
  sidVal := :new.SID_ID;
  if sid = 'POP' then
    table_name := 'PROD_VAL';
  else 
    table_name := 'PROD_VAL2';
  end if;
  execute immediate 'UPDATE ' || table_name 
                    || ' set EXEMPTION=sidVal WHERE SID_ID=:x' using sidVal;
END;

【讨论】:

【参考方案2】:

在所有这些更改都是必要的之后: '将表名的 var 更改为 varchar2:' 仅对执行语句进行轻微更新: '执行立即'UPDATE :1 set CPI_EXEMPTION=:2 WHERE SID_ID=:3' using table_name, :new.FLAG, :new.SID_ID;'

感谢所有 cmets,他们对我帮助很大。不得不说我学到了很多东西。

【讨论】:

以上是关于oracle,sql,触发器的主要内容,如果未能解决你的问题,请参考以下文章

ORACLE触发器中如何终止SQL语句

oracle如何用sql查看触发器?

SQL server与Oracle触发器的创建与使用

oracle sql语句

将SQL Server触发器转换为oracle触发器

基本 Oracle 触发器审计表