oracle1422,奇怪的ORA-1422错误

发现bug总是喜欢扎堆,也许很长时间都碰不到bug,可能会在短时间内,碰到很多的bug。

这个bug又是在10.2.0.3上发现的。

检查后台alert文件时,发现一个JOB运行报错:

Errors in file /opt/oracle/admin/tradedb/bdump/tradedb1_j000_5103.trc:

ORA-12012:自动执行作业77出错ORA-01422:实际返回的行数超出请求的行数ORA-06512:在line 14

查询DBA_JOBS,发现这个JOB会运行一个存储过程。

开始没有太当回事,一般造成这个错误都是由于类似SELECT INTO的时候读取了多条记录造成的,比如:

SQL> DECLARE

2 V_NAME VARCHAR2(30);

3 BEGIN

4 SELECT TNAME INTO V_NAME FROM TAB;

5 END;

6 /

DECLARE

*第1行出现错误:

ORA-01422:实际返回的行数超出请求的行数ORA-06512:在line 4

但是在检查存储过程的时候,并没有发现类似的问题。而且,存储过程中进行了错误信息的捕获。

既然进行错误的捕获,而错误还能被抛出来,那么错误应该是出自存储过程的EXCEPTION部分。

但是EXCEPTION部分代码很简单,出错的可能性很小,更没有可能出现ORA-1422错误。

尝试执行这个存储过程,结果发现存储过程可以顺利执行。尝试DBMS_JOB.RUN运行这个失败的JOB,发现JOB也可以顺利运行。

于是开始怀疑这个问题是Oracle的bug,到metalink上一搜索,果然如此。

由于建立了一个系统登陆触发器,且触发器中对V$SESSION动态视图进行了查询,由于包含对SYSDATE的访问,造成了对JOB运行的阻塞,导致触发器中读取V$SESSION视图时出现ORA-1422错误。

Oracle给出的解决方法是删除或禁止系统触发器,或者在触发器中去掉SYSDATE函数。

Oracle在Doc ID:Note:402508.1中给出详细的描述。

根据Oracle给出的方法,原始的触发器:

SQL> CREATE TABLE LOGIN_LOGS

2 (

3 LOGIN_DATE DATE,

4 USERNAME VARCHAR2(30),

5 BG_JOB_ID VARCHAR2(64),

6 INSTANCE VARCHAR2(30),

7 IP_ADDRESS VARCHAR2(30),

8 OS_USER VARCHAR2(30),

9 TERMINAL VARCHAR2(30),

10 MACHINE VARCHAR2(64),

11 PROGRAM VARCHAR2(48),

12 MODULE VARCHAR2(48),

13 CLIENT_INFO VARCHAR2(64),

14 SERVICE_NAME VARCHAR2(64)

15 );

表已创建。

SQL> CREATE OR REPLACE TRIGGER TRI_ON_LOGON AFTER LOGON ON DATABASE

2 DECLARE

3 V_USER VARCHAR2(30);

4 V_OSUSER VARCHAR2(30);

5 V_TERMINAL VARCHAR2(30);

6 V_MACHINE VARCHAR2(64);

7 V_PROGRAM VARCHAR2(48);

8 V_MODULE VARCHAR2(48);

9 V_CLIENT_INFO VARCHAR2(64);

10 V_SERVICE_NAME VARCHAR2(64);

11 BEGIN

12 SELECT UPPER(USER) INTO V_USER FROM DUAL;

13 IF V_USER = 'YANGTK' THEN

14

15 SELECT OSUSER, TERMINAL, MACHINE, PROGRAM, MODULE, CLIENT_INFO, SERVICE_NAME

16 INTO V_OSUSER, V_TERMINAL, V_MACHINE, V_PROGRAM, V_MODULE, V_CLIENT_INFO, V_SERVICE_NAME

17 FROM V$SESSION

18 WHERE AUDSID = SYS_CONTEXT('USERENV', 'SESSIONID');

19

20 INSERT INTO LOGIN_LOGS VALUES

21 (

22 SYSDATE,

23 V_USER,

24 SYS_CONTEXT('USERENV', 'FG_JOB_ID'),

25 SYS_CONTEXT('USERENV', 'INSTANCE'),

26 SYS_CONTEXT('USERENV', 'IP_ADDRESS'),

27 V_OSUSER,

28 V_TERMINAL,

29 V_MACHINE,

30 V_PROGRAM,

31 V_MODULE,

32 V_CLIENT_INFO,

33 V_SERVICE_NAME

34 );

35 END IF;

36 END;

37 /

触发器已创建

应该修改为:

SQL> CREATE OR REPLACE TRIGGER TRI_ON_LOGON AFTER LOGON ON DATABASE

2 DECLARE

3 V_USER VARCHAR2(30);

4 V_OSUSER VARCHAR2(30);

5 V_TERMINAL VARCHAR2(30);

6 V_MACHINE VARCHAR2(64);

7 V_PROGRAM VARCHAR2(48);

8 V_MODULE VARCHAR2(48);

9 V_CLIENT_INFO VARCHAR2(64);

10 V_SERVICE_NAME VARCHAR2(64);

11 BEGIN

12 SELECT UPPER(USER) INTO V_USER FROM DUAL;

13 IF V_USER = 'YANGTK' THEN

14

15 SELECT OSUSER, TERMINAL, MACHINE, PROGRAM, MODULE, CLIENT_INFO, SERVICE_NAME

16 INTO V_OSUSER, V_TERMINAL, V_MACHINE, V_PROGRAM, V_MODULE, V_CLIENT_INFO, V_SERVICE_NAME

17 FROM V$SESSION

18 WHERE AUDSID = SYS_CONTEXT('USERENV', 'SESSIONID')

19 AND ROWNUM = 1;

20

21 INSERT INTO LOGIN_LOGS VALUES

22 (

23 SYSDATE,

24 V_USER,

25 SYS_CONTEXT('USERENV', 'FG_JOB_ID'),

26 SYS_CONTEXT('USERENV', 'INSTANCE'),

27 SYS_CONTEXT('USERENV', 'IP_ADDRESS'),

28 V_OSUSER,

29 V_TERMINAL,

30 V_MACHINE,

31 V_PROGRAM,

32 V_MODULE,

33 V_CLIENT_INFO,

34 V_SERVICE_NAME

35 );

36 END IF;

37 END;

38 /

触发器已创建

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值