Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle 为特定值在表中插入时创建触发器_Oracle_Triggers_Insert - Fatal编程技术网

Oracle 为特定值在表中插入时创建触发器

Oracle 为特定值在表中插入时创建触发器,oracle,triggers,insert,Oracle,Triggers,Insert,我试图在Oracle12c中装入一个触发器,如果插入的值包含特定值,它将执行该过程 我试图做的是在某些表(事件、标记、阶段)全部刷新之后,才希望触发器运行refreshu MVS();程序 刷新后存储在计数表中。所以我正在检查新插入计数是否包含关键字:事件、标记、阶段 这样做吗 CREATE or replace TRIGGER MV_REFRESH AFTER INSERT ON COUNTS FOR EACH ROW DECLARE MODEL_NAME varchar2(20)

我试图在Oracle12c中装入一个触发器,如果插入的值包含特定值,它将执行该过程

我试图做的是在某些表(事件、标记、阶段)全部刷新之后,才希望触发器运行refreshu MVS();程序

刷新后存储在计数表中。所以我正在检查新插入计数是否包含关键字:事件、标记、阶段

这样做吗

CREATE or replace TRIGGER MV_REFRESH
AFTER INSERT ON COUNTS
  FOR EACH ROW

DECLARE
   MODEL_NAME varchar2(20);

BEGIN
   select MODEL INTO MODEL_NAME from COUNTS;

  IF(MODEL_NAME = 'EVENTS' AND MODEL_NAME = 'MARKS' AND MODEL_NAME = 'STAGE')
  THEN
      REFRESH_MVS();           
  END IF;     
END;
在成功编译后,如果我运行INSERT:

INSERT INTO COUNTS 
values ('EVENTS',   '11658495', '0.11', '17-MAR-14',    '17-MAR-14');
它抛出错误:

Error starting at line 3 in command:
INSERT INTO COUNTS
values ('EVENTS',   '11658495', '0.11', '17-MAR-17',    '17-MAR-17')
Error report:
SQL Error: ORA-04091: table COUNTS is mutating, trigger/function may not see it
ORA-06512: at "MV_REFRESH", line 5
ORA-04088: error during execution of trigger 'MV_REFRESH'
04091. 00000 -  "table %s.%s is mutating, trigger/function may not see it"
*Cause:    A trigger (or a user defined plsql function that is referenced in
           this statement) attempted to look at (or modify) a table that was
           in the middle of being modified by the statement which fired it.
*Action:   Rewrite the trigger (or function) so it does not read that table.

你试图做的似乎并不明智。如果您能解释您试图解决的业务问题,我们可能会帮助您提出更合适的技术实现

通常,在表的行级触发器中,您不能查询有问题的表。不过,您似乎不需要在此触发器中查询表。我猜您只需要使用
:new.model\u name
。但是如果是这样的话,逻辑就没有意义了——当然,一个属性不可能同时有三个不同的值

IF(:NEW.MODEL_NAME = 'EVENTS' AND 
   :NEW.MODEL_NAME = 'MARKS' AND 
   :NEW.MODEL_NAME = 'STAGE')
THEN
  REFRESH_MVS();           
END IF;  
也许你的意思是
,而不是

IF(:NEW.MODEL_NAME = 'EVENTS' OR
   :NEW.MODEL_NAME = 'MARKS' OR 
   :NEW.MODEL_NAME = 'STAGE')
THEN
  REFRESH_MVS();           
END IF;  
这可以简化

IF(:NEW.MODEL_NAME IN( 'EVENTS', 'MARKS', 'STAGE') )
THEN
  REFRESH_MVS();           
END IF;  
现在,如果
refresh\u mvs
尝试查询
counts
表,您还将得到mutating table异常。如果当前实现尝试查询
计数
,则需要将过程更改为接受当前插入行中所需的任何数据作为参数


如果
refresh\u mvs
实际上正在刷新物化视图,这意味着它至少在执行隐式提交。这将产生进一步的问题,因为您无法在触发器中提交(除非触发器被定义为自治事务,这在这里不合适)。

我试图做的是在所有3个表都完成刷新并出现在计数表中后运行REFRESH\u MVS()过程。也许这不是解决问题的办法?@Angelina-“在所有三张桌子都完成刷新后”是什么意思?您是否有某种ETL流程正在加载
事件
标记
、和
阶段
表?如果是这样,为什么该过程不启动物化视图的刷新?如果这些是通过
dbms\u scheduler
调度的单独作业,则可以创建该作业以刷新物化视图,并将其添加为链中的一个步骤,当这三个链步骤完成时,该链将运行。或者您可以有一个单独的作业,定期运行,查询
计数
表,并刷新物化视图。我的问题是独立脚本。每个表都有自己的脚本加载该表,然后插入表名、计数、开始、结束。所以我找不到检查三个表何时全部完成的方法。@Angelina-大概每个脚本都是以某种方式安排好的。这是什么机制。如果您使用的是
dbms\u调度程序
,则可以创建依赖于成功完成之前多个步骤的步骤。或者,您可以编写一个单独的作业,定期运行,查询
计数
表,并调用您的存储过程。@Angelina-如果您使用的是
dbms\u调度程序
,那么,是的,将其构造为具有多个依赖项的链中的步骤是有意义的。