`
LynsaHuang
  • 浏览: 47035 次
  • 性别: Icon_minigender_2
  • 来自: 北京
社区版块
存档分类
最新评论

trigger 错误ORA-04084 ORA-04088

阅读更多
错误trigger code
CREATE OR REPLACE TRIGGER trig_usernumber_insert_dxdss after insert  on dxdss
referencing old as old_value  new as new_value for each row
declare
v_curr_size integer;
v_has number;
v_sql varchar2(128);
v_num varchar2(33);
p_nError        NUMBER;
p_userID        NUMBER;
p_vaddusID        NUMBER;
p_dxhfsID        NUMBER;
p_dxhfsSID        NUMBER;
p_dxhfsWID        NUMBER;
p_dxhfsBID        NUMBER;
V_ERROR_MESSAGE VARCHAR2(500);
begin
    select count(*) into v_has from DXBG_MAIL_BOX_COUNT where usernumber=:new_value.USERNUMBER;   
if(v_has =0) then
    select count(*) into v_curr_size from DXdss where usernumber=:new_value.USERNUMBER;    insert into DXBG_MAIL_BOX_COUNT (USERNUMBER,BOX_CURR_SIZE)  values (:new_value.USERNUMBER,v_curr_size);
elsif(v_has =1) then
    select BOX_CURR_SIZE into v_curr_size from DXBG_MAIL_BOX_COUNT where usernumber=:new_value.USERNUMBER;
    v_curr_size:=v_curr_size+1;
    update DXBG_MAIL_BOX_COUNT set BOX_CURR_SIZE=v_curr_size where usernumber=:new_value.USERNUMBER;
else    
     select count(*) into v_curr_size from DXdss where usernumber=:new_value.USERNUMBER;
     delete from DXBG_MAIL_BOX_COUNT where usernumber=:new_value.USERNUMBER;
     insert into DXBG_MAIL_BOX_COUNT (USERNUMBER,BOX_CURR_SIZE)  values (:new_value.USERNUMBER,v_curr_size);
end if;
EXCEPTION   
    when others then
      p_nError := SQLCODE;
      V_ERROR_MESSAGE := sqlerrm;
      insert into HISTORYOAMALERT (ALERTTYPE, ALERTTIME, ALERTFROM, COMPUTER, ALERTLEVEL, DESCRIPTION)
      values('ORACLE',TO_CHAR(SYSDATE, 'YYYYMMDDHH24MISS'),'ORACLE','DB','1',p_nError||'  '||V_ERROR_MESSAGE);    
      RAISE;

END;
ORA-04091 table string.string is mutating, trigger/function may not see it

Cause: A trigger (or a user defined PL/SQL 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.

ORA-06512 at string line string

Cause: Backtrace message as the stack is unwound by unhandled exceptions.

Action: Fix the problem causing the exception or write an exception handler for this condition. Or you may need to contact your application administrator or database administrator.

ORA-04088 error during execution of trigger 'string.string'

Cause: A runtime error occurred during execution of a trigger.

解释:
变异表是一个当前正在改变的表。改变可以是因为INSERT、UPDATE或DELETE语句,或者由于DELETE CASCADE约束。

这种错误类型只会在行级触发器上发生。

当表在改变时,不能对表进行查询或修改。细想一下就会发现它是有意义的。如果触发器因为表上的改变而激发,那么直到结束之前都看不到这种改变。尽管可以访问new和old伪记录,但是不能读取表的状态。任何这么做的企图都会引发ORA-04091异常。

下面演示了变异错误的发生过程。按照如下代码所示创建一个mutant表:

CREATE TABLE mutant

( mutant_id NUMBER

, mutant_name VARCHAR2(20));

然后可以插入4个主要“忍者神龟”:

INSERT INTO mutant VALUES (mutant_s1.nextval,'Donatello');

INSERT INTO mutant VALUES (mutant_s1.nextval,'Leonardo');

INSERT INTO mutant VALUES (mutant_s1.nextval,'Michelangelo');

INSERT INTO mutant VALUES (mutant_s1.nextval,'Raphael');

插入数据以后,可以构建下面的触发器:

CREATE OR REPLACE TRIGGER mutator

AFTER DELETE ON mutant

FOR EACH ROW

DECLARE

rows NUMBER;

BEGIN

SELECT COUNT(*) INTO rows FROM mutant;

dbms_output.put_line('[rows] has '||rows||']');

END;

/

触发器主体试图得到行数,但是它得不到行数,因为记录集没有结束。存在这个限制是为了防止触发器看到不一致的数据。

可以通过运行下面的命令删除变异表中的Michelangelo来激发触发器。DELETE语句为:

DELETE FROM MUTANT WHERE mutant_name = 'Michelangelo';

运行了该语句后,DELETE语句会抛出下面的错误堆栈:

DELETE FROM mutant WHERE mutant_name = 'Michelangelo'

ERROR at line 1:

ORA-04091: table PLSQL.MUTANT is mutating, trigger/function may not see it

ORA-06512: at "PLSQL.MUTATOR", line 4

ORA-04088: error during execution of trigger 'PLSQL.MUTATOR'

当触发器遇到变异表时,它会回滚触发器主体指令和触发语句。知道了为什么会生生变异表错误,就应当小心地避免这种错误。


错误的触发器code:
CREATE OR REPLACE TRIGGER trig_dxbg_count_insert after insert on DXBG_MAIL_BOX_COUNT
referencing old as old_value  new as new_value FOR EACH ROW
declare
v_curr_size integer;
v_has number;
v_boxid VARCHAR2(32);
v_box VARCHAR2(32);
v_sql VARCHAR2(128);
p_nError        NUMBER;
V_ERROR_MESSAGE VARCHAR2(500);
begin
    v_boxid:=SUBSTR((:new_value.USERNUMBER),10);
    v_box:='DXBG_MAIL_BOX_'||v_boxid;   
    v_sql:='select count(*) from '||v_box||' where usernumber='||:new_value.USERNUMBER;
    execute immediate v_sql into v_curr_size;
    :new_value.BOX_CURR_SIZE:=v_curr_size;
EXCEPTION   
    when others then
      p_nError := SQLCODE;
      V_ERROR_MESSAGE := sqlerrm;
      insert into HISTORYOAMALERT (ALERTTYPE, ALERTTIME, ALERTFROM, COMPUTER, ALERTLEVEL, DESCRIPTION)
      values('ORACLE',TO_CHAR(SYSDATE, 'YYYYMMDDHH24MISS'),'ORACLE','DB','1',p_nError||'  '||V_ERROR_MESSAGE);    
      RAISE;

END;
/

执行报错,错误信息:ORA-04084 无法更改此触发器类型的NEW值

New trigger variables can only be changed in before row insert or update triggers.

把触发器的after改成before 触发
分享到:
评论

相关推荐

    Drop goldengate用户时报ORA-00604 ORA-20782 ORA-06512问题解决

    `命令时,可能会遭遇ORA-00604、ORA-20782以及ORA-06512等错误。这些错误通常是因为Goldengate用户在安装Oracle GoldenGate (OGG) 时配置了DDL捕获功能。 #### 二、错误分析及处理步骤 **1. 错误现象** 执行`drop ...

    oracle中用户连接问题.docx

    1. **日志文件**:检查Oracle监听器日志(例如 `$ORACLE_HOME/network/log/listener_orarac1.log`),在其中可能找到连接的IP信息。 2. **触发器**:创建一个登录触发器来记录IP地址。下面是一个示例: ```sql ...

    Java Functions, Stored Procedures, Triggers

    当遇到像"ORA-29549: class SCOTT.HelloWorld has changed, Java session state cleared"这样的错误时,可能是因为Java类发生了变化。这时,需要再次调用`dbms_java.set_output(10000)`来清理Java会话状态并重新...

    Quartz2.2.3+Spring4.3.14整合demo

    4. 配置 Spring:在 `applicationContext.xml` 中定义 Job 和 Trigger 的 Bean,使用 Spring 的 `QuartzJobBean` 来托管 Job,然后定义 Trigger 来指定 Job 的执行时机。 5. 初始化 Quartz:在 `web.xml` 中添加一个...

    PLSQL中文详细使用教程 有标签可快速定位

    3. 触发器(TRIGGER):在特定的数据库事件发生时自动执行的代码。 4. 过程和函数(PROCEDURE & FUNCTION):可以独立于SQL语句执行的代码单元,可以在PLSQL或SQL中调用。 七、事务管理 PLSQL支持事务的概念,允许...

    博洋oracle课件

    - 触发器(Trigger)是数据库级的事件驱动程序,当特定的DML操作(如INSERT, UPDATE, DELETE)发生时自动执行。 - 触发器可用于实现业务规则、审计日志记录等自动化功能,但过度使用可能影响性能。 这些课件内容...

    ora数据库的一些常用简单知识

    9. **触发器(Trigger)**:触发器是一种数据库对象,当特定的DML事件(INSERT, UPDATE, DELETE)发生时自动执行。它们可以用于实现复杂的业务规则和数据完整性检查。 10. **存储过程和函数**:存储过程和函数是预...

    oracle触发器调用存储过程

    4. AT程序必须以commit或rollback结尾,否则会产生Oracle错误ORA-06519: active autonomous transaction detected and rolled back。 Oracle触发器调用存储过程可以通过使用自治事务来解决事务隔离性问题,确保业务...

    Oracle触发器表发生了变化 触发器不能读它的解决方法(必看)

    CREATE or replace TRIGGER T_userupdateT BEFORE update ON T_user REFERENCING OLD AS old NEW AS N_ROW FOR EACH ROW DECLARE U_xtfidemp1 varchar(36); u_xtempcode1 varchar(20); u_xtempcodeCount int:=0; ...

    Oracle基于系统级触发器的审计功能

    CREATE OR REPLACE TRIGGER audit_ddl AFTER DDL ON DATABASE DECLARE v_operation VARCHAR2(30); v_object_name VARCHAR2(30); v_object_owner VARCHAR2(30); v_object_type VARCHAR2(20); BEGIN v_...

    Oracle 10g 学习笔记

    │ 手工配置listener.ora【避免出现ORA-12514错误】.txt │ 贴子树状态存储结构.jpg │ 贴子树状态存储结构.sql │ ├─01 Oracle入门 │ 01 Oracle 简介.txt │ 02 Oracle安装.txt │ 03 sqlplusw的使用.txt │ ...

    OCA评估测试试题,中文版的

    14. 数据库连接:如果在服务器端执行命令 sqlplus scott/trigger 时,收到错误提示 ORA-01034:oracle not available,则数据库状态是数据库和实例没有开始。 15. 数据库连接:使用命令 sqlplusscott/trigger@abc....

    ORACLE_数据库日常工作维护知识总结.pdf

    - 检查无效的trigger:无效的trigger可能会影响数据库操作,需要进行检查和优化。 以上知识点涵盖了Oracle数据库维护的关键领域,包括数据库状态监控、日志文件检查、性能分析和优化、安全检查以及备份验证。对...

    Oracle PL_SQL应用指南

    - **ORA-01422 错误**: 当尝试通过游标返回多行数据时可能会遇到此错误。解决方法通常涉及使用 REF CURSOR。 - **重建触发器**: 如果需要修改已有的触发器逻辑,可以使用 `DROP TRIGGER` 和 `CREATE TRIGGER` 语句来...

    ogg12c安装部署文档(详)

    $ sed -i "s/INSTALL_OPTION=/INSTALL_OPTION=ORA12c/" "/home/oracle/fbo_ggs_Linux_x64_shiphome/Disk1/response/oggcore.rsp" $ sed -i "s|SOFTWARE_LOCATION=|SOFTWARE_LOCATION=/u01/app/goldengate|" "/home...

    oracle dba常用sql

    - 对于包含ORA-错误号的日志,可以快速定位问题所在。 #### 3. 备份与恢复 - **RMAN备份**: - RMAN (Recovery Manager) 是Oracle提供的备份和恢复工具,可以用来进行数据文件、控制文件、表空间等的备份。 - 在...

    Oracle 12C CDB、PDB常用管理命令.docx

    * CREATE OR REPLACE TRIGGER open_pdbs AFTER STARTUP ON DATABASE BEGIN EXECUTE IMMEDIATE 'ALTER PLUGGABLE DATABASE ALL OPEN'; END open_pdbs; 从 PDBSEED 创建 PDB 可以使用以下命令来从 PDBSEED 创建 PDB...

    Oracle10g数据库日常维护手册

    - **注意**: 应确保必要的服务进程如`ora_pmon`和`ora_psp0`等存在且运行正常。 ##### 1.3 检查Oracle监听状态 - **目的**: 确保监听器能够正确地监听客户端请求。 - **方法**: 使用命令`lsnrctl status`或通过`v$...

    Oracle数据库日常维护手册.pdf

    - **计数命令**: `$ ps -ef | grep ora_ | grep -v grep | wc -l` - **输出示例**: `oracle 2960 10 May 07` - **解释**: 这里显示了Oracle相关进程的数量和部分进程信息。 ##### 1.3 检查Oracle监听状态 - **...

Global site tag (gtag.js) - Google Analytics