Sql 似乎无法为insert-Oracle创建触发器
我正在尝试在表上为插入创建触发器。以下是创建脚本:Sql 似乎无法为insert-Oracle创建触发器,sql,oracle,plsql,triggers,Sql,Oracle,Plsql,Triggers,我正在尝试在表上为插入创建触发器。以下是创建脚本: CREATE OR REPLACE TRIGGER INTEG_QRY_NEW AFTER INSERT ON INTEG_LOG FOR EACH ROW DECLARE VAR2 NUMBER(10); LOG_TEXT1 VARCHAR2(1000); RESULT1 VARCHAR2(1000); QUERY_NUM1 VARCHAR2(1000); QUERY_TIME1 VARCHAR2(1000); LOG_INDE
CREATE OR REPLACE TRIGGER INTEG_QRY_NEW
AFTER INSERT
ON INTEG_LOG
FOR EACH ROW
DECLARE
VAR2 NUMBER(10);
LOG_TEXT1 VARCHAR2(1000);
RESULT1 VARCHAR2(1000);
QUERY_NUM1 VARCHAR2(1000);
QUERY_TIME1 VARCHAR2(1000);
LOG_INDEX1 NUMBER(10);
BEGIN
SELECT COUNT(*) INTO VAR2 FROM USER_TAB_COLS WHERE (COLUMN_NAME = 'RESULT' OR COLUMN_NAME = 'QUERY_NUM' OR COLUMN_NAME = 'DATE_TIME' ) AND TABLE_NAME = 'INTEG_LOG';
IF VAR2=0 THEN
EXECUTE IMMEDIATE 'ALTER TABLE INTEG_LOG ADD RESULT VARCHAR2(50); ALTER TABLE INTEG_LOG ADD DATE_TIME DATE; ALTER TABLE INTEG_LOG ADD QUERY_NUM VARCHAR2(50);';
END IF;
LOG_TEXT1 := :NEW.LOG_TEXT;
QUERY_TIME1 := :NEW.QUERY_TIME;
LOG_INDEX1 := :NEW.LOG_INDEX;
IF QUERY_TIME1 = '' THEN
RESULT1 := '-1';
QUERY_NUM1 := '';
UPDATE INTEG_LOG
SET RESULT = RESULT1,
DATE_TIME = CURRENT_DATE,
QUERY_NUM = QUERY_NUM1
WHERE LOG_INDEX = LOG_INDEX1;
ELSE
RESULT1 := SUBSTR(LOG_TEXT1,(INSTR(LOG_TEXT1,'Result = ')+9),9);
QUERY_NUM1 := SUBSTR(SUBSTR(LOG_TEXT1,INSTR(LOG_TEXT1,'Q# ')+3,20),1,INSTR(SUBSTR(LOG_TEXT1,INSTR(LOG_TEXT1,'Q# ')+3,20),' '));
UPDATE INTEG_LOG
SET RESULT = RESULT1,
DATE_TIME = CURRENT_DATE,
QUERY_NUM = QUERY_NUM1
WHERE LOG_INDEX = LOG_INDEX1;
END IF;
END;
/
触发器负责对来自应用程序的以下列进行常规插入:
日志日期编号10
日志时间编号10
日志类型编号10
LOG_TEXT VARCHAR22000字节
日志索引编号10
查询时间VARCHAR28字节
触发器检查以下列是否存在,如果不存在,则添加它们:
结果VARCHAR250字节,
日期/时间日期,
查询\u NUM VARCHAR250字节
现在,它获取字符串LOG_TEXT列,并提取“Q”后面的结果值和查询编号。
接下来,它应该更新相同的insert操作,并将这些值添加到新的3列result、date\u time和query\u num中。
触发器确实成功创建,但问题是,当我尝试插入表INTEG_LOG时,出现以下错误:
表string.string正在发生变化,触发器/函数可能看不到它
原因:引用的触发器或用户定义的plsql函数
在此语句中,试图查看或修改已删除的表
在被修改的语句的中间。
操作:重写触发器或函数,使其不读取该值
桌子
这可能是语法错误吗?请帮忙。谢谢。触发器编译的唯一原因是,INTEG\u LOG已经包含了动态SQL试图添加的列。如果表中没有这些列,触发器将不会添加它们,因为触发器将无效,因为这些UPDATE语句无法编译 应该避免使用动态SQL的原因之一是它将编译错误转化为运行时错误 但是,试图在基于表的触发器中向表中添加列是一个非常糟糕的想法。除此之外,DDL语句还发出隐式提交,我们不能在触发器中提交,因为这会对事务造成严重破坏。是的,有pragma-autonomous\u事务,但使用它通常是一种代码味道 正确的解决方案是: 编写一个一次性DDL脚本来添加这些列 如有必要,在执行ALTER TABLE语句之前,通过检查这些列是否存在,使脚本幂等 运行脚本。 用所有列填充表。
当然,这与那些UPDATE语句导致的突变表错误无关。我们无法在承载触发器的表上执行DML,包括selects。我不确定您试图实现的业务规则是什么,但您需要一种不同的方式来实现它 不能在触发该表的触发器中向该表添加列。您不应该向触发器中的任何表添加列。我想不出任何一个用例会是一个好主意。