先说一下问题的背景吧,最近用户在使用系统的一个功能的时候报错,查看了错误日志,是熟悉的ORA-01722: invalid number,原因看起来很简单,本来该输入NUMBER的地方给了字符。报错的SQL语句是这样的:
INSERT INTO PS_GP_PI_MNL_DATA(GP_PAYGROUP,CAL_ID,EMPLID,EMPL_RCD,PIN_NUM,INSTANCE,ENTRY_TYPE_ID,PI_ACTION_TYPE,CURRENCY_CD,GP_RATE,ENTRY_TYPE_RATE,PIN_RATE_NUM,GP_UNIT,ENTRY_TYPE_UNIT,PIN_UNIT_NUM,GP_BASE,ENTRY_TYPE_BASE,PIN_BASE_NUM,GP_PCT,ENTRY_TYPE_PCT,PIN_PCT_NUM,GP_AMT,ENTRY_TYPE_AMT,PIN_AMT_NUM,BUSINESS_UNIT,DESCR,GP_BATCH_CD,BAL_ADJ,LASTUPDOPRID,LASTUPDDTTM) VALUES(:1,:2,:3,:4,:5,:6,:7,:8,:9,:10,:11,:12,:13,:14,:15,:16,:17,:18,:19,:20,:21,:22,:23,:24,:25,:26,:27,:28,:29,TO_TIMESTAMP(:30,'YYYY-MM-DD-HH24.MI.SS.FF')),如此多的绑定变量,要快速的确定问题,还是要确定这些绑定值, 庆幸的是在UAT可以重现这个问题。
从网上参考了很多文章,比较靠谱的是使用oracle的10046事件跟踪SQL语句,但是设置10046跟踪必须要获得用户的session信息,这个有点难了,因为session的产生非常短暂,所以只好作罢。
想起以前看过一个文章,可以根据出错号来进行跟踪,果然可以如愿,步骤如下:
1、使用ERRORSTACK进行错误跟踪,诊断事件可以设置在session级别,也可以设置在系统级别,针对ORA-01722,设置如下:
SQL > alter system set events '1722 trace name errorstack level 8';
System altered.
2、执行出错的功能。
3、到user_dump_dest目录下,获得出错的Trace文件
SQL> show parameter user_dump_dest;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
user_dump_dest string /oracle/diag/rdbms/hr91dev/HR91DEV/trace
4、到指定的目录下找到产生的Trace文件
cd /oracle/diag/rdbms/hr91dev/HR91DEV/trace
ls -lt|head
找到最新的trace文件,找到bind这一段,就可以看到绑定变量了,如图:
从Trace文件中发现,第四个绑定变量是Number型,但却传了个字符,所以报错了。希望对大家有所帮助。