最近在一个项目中碰到一个事情,缘由大概如下:
业务由中间价tomcat连接到oracle db,每连接一次呢要插入对应表中一条数据,结果出现了偶尔报错ora-01461的错误,估计是因为插入的数据表中对应字段使用varchar2类型数据,但是经过字符集转换后由于长短不一直造成自负超过4000字节,此时数据库会将数据类型转换成long字段类型数据插入,导致字段类型不一致,所以报错01046的错误。
像这类错误只会在业务前端展示,在数据库这层无法看到明确的报错,解决这类问题有2个思路:
一是更新jdbc的驱动;
二是找到对应的表更改字段的varchar2为long等长字段。
我遇到情况是上面的第一种,当时我采用oracle 10g最新的jdbc驱动更新中间件的tomcat(数据库版本为9206),但是很遗憾隔了没多久又出现同样的报错情况。最终我决定要找到对应的表,可是这时候应用开发也不知道是哪张表,无赖之下只能在oracle层面采取errorstack的方式跟踪,大概的原理如下:
errorstack事件:dump 错误栈信息,通常Oracle发生错误时前台进程将得到一条错误信息,但某些情况下得不到错误信息,可以采用这种方式得到Oracle错误。
使用语法:
alter session set events ’12899 trace name errorstack forever’; 不需要重启数据库,在session级别生效。 alter system set events ’12899 trace name errorstack forever’;-需要重启数据库,在全局系统生效
我这里以错误ORA-12899的方式为例,具体如下:
执行语句: alter system set events ’12899 trace name errorstack forever’; SQL> alter system set events '12899 trace name errorstack forever'; System altered. SQL> desc t1 Name Null? Type ----------------------------------------- -------- ---------------------------- ID NUMBER NAME VARCHAR2(4) SQL> insert into t1 values(250,'ludatou'); insert into t1 values(250,'ludatou') * ERROR at line 1: ORA-12899: value too large for column "SYS"."T1"."NAME" (actual: 7, maximum: 4)
可以在user_dump下找到最新的dump,ls -lFrt,就为此次错误的跟踪trace,Trace的内容如下:
*** 2014-01-15 17:24:13.461 ----- Error Stack Dump ----- ORA-12899: value too large for column "SYS"."T1"."NAME" (actual: 7, maximum: 4) ----- Current SQL Statement for this session (sql_id=8f4g5vujpymhg) ----- insert into t1 values(250,'ludatou') ↑↑↑↑↑ 这个trace把语句也抓起来了。 ----- Call Stack Trace ----- calling call entry argument values in hex location type point (? means dubious value) -------------------- -------- -------------------- ---------------------------- *** 2014-01-15 17:24:13.992 skdstdst()+38 call kgdsdst() BFD338FC ? 2 ? ksedst1()+88 call skdstdst() BFD338FC ? 0 ? 1 ? AC9E128 ? 8551B9E ? AC9E128 ? ksedst()+33 call ksedst1()+8 0 ? F9F580 ? 2050033 ? 0 ? FF ? 2004 ? dbkedDefDump()+1062 call ksedst() 0 ? 0 ? 0 ? 0 ? 0 ? 0 ? ksedmp()+47 call dbkedDefDump() 1 ? 0 ? dbkdaKsdActDriver() call 00000000 1 ? 1F060C ? 1D19EC ? 0 ? +1481 FAA03A0 ? F9E3720 ? dbgdaExecuteAction( call 00000000 F9F580 ? BFD35630 ? )+595 dbgdaRunAction()+89 call dbgdaExecuteAction( F9F580 ? F21B294 ? 20C0002 ? 4 ) BFD35630 ? 1 ? dbgdRunActions()+64 call dbgdaRunAction() F9F580 ? 71D0810 ? dbgdProcessEventAct call dbgdRunActions() DC16520 ? DC16529 ? ions()+604 dbgdChkEventKgErr() call dbgdProcessEventAct F9F580 ? FAA03A0 ? 71D093C ? +1542 ions() 0 ? 1 ? EA055FB ? dbkdChkEventRdbmsEr call dbgdChkEventKgErr() F9F580 ? 223BAD0 ? 3263 ? r()+23 __PGOSF12_ksfpec()+ call dbkdChkEventRdbmsEr 3263 ? 8 ? EABE0A0 ? 139 r() EABE0A0 ? EAB6A38 ? BFD35F24 ? dbgePostErrorKGE()+ call 00000000 FAA03A0 ? 3263 ? 825