eygle在"使用errorstack跟踪ORA-01438错误"这篇文章里,推荐了itpub上一篇文章----"一次ora-01438错误的处理",我去看了这篇文章。
看到itpub上有很多朋友不知道写这篇文章的人的想法,我看上面很多朋友都觉得是高深莫测。
呵呵,其实是很简单的问题,我来解释一下eygle推荐的那篇文章里所谓的两个高深莫测的地方:
1、为什么搜索的字符串变成了"2E313133
答:因为他的系统是redhat 4 64bit,是little endian,所以要颠倒过来。这里的颠倒过来倒不是说oracle在block内会颠倒过来存,而是指oracle在内存里会颠倒存。比如如下的例子:
比如对于一个number(24)的整数123456789123456789123456,在little endian的操作系统里,block内部oracle还是会存成CC 0D 23 39 4F 5C 18 2E 44 5A 0D 23 39,只不过对于上述操作系统而言,oracle在内存里会这么存:
Dump of memory from 0x0792DFE8 to 0x0792E450
792DFE0 00010000 000AE
792DFF0 00000000 00000000 00000000 00000000
792E000 00000000 00000000 39230DCC 2E
792E010 230D
792E020 00000000 00000000 00000000 00000000
即按照4个byte为一组,每组里高位跟低位颠倒。
如果是AIX,则oracle在内存里不会颠倒,因为AIX是big endian。比如同样对于上述值,在AIX上oracle在内存里会这样存:
Dump of memory from 0x000000011067B670 to 0x000000011067BB80
11067B670 00010000 EDD5FBB0 00090000 00000000
11067B680 00000000 00000000 00000000 00000000
11067B690 CC0D2339
11067B
2、他在文中提到"本值在数据库中定义为number(8)类型,但从结果来看,系统把这个值当成了number(24)类型",很多朋友不明白为什么这里是number(24)?
答:这是因为上述trace文件里记录的值是"3331312E 0406C102 C9BBC6C8 52024D01 30310248 00003304",我们来还原一下这个值:
SQL> select utl_raw.cast_to_number(hextoraw('3331312E
UTL_RAW.CAST_TO_NUMBER(HEXTORA
------------------------------
-5.25255979409E23
这不就是一个number(24)吗?
但我并不认为这里应该是number(24)。
这里其实应该以oracle实际存在dmp文件中的值来判断上述column的长度,即以"2E313133 02C10604 C8C6BBC9 014D0252 48023130 04330000"来判断上述字段的长度:
SQL> select utl_raw.cast_to_number(hextoraw('2E
UTL_RAW.CAST_TO_NUMBER(HEXTORA
------------------------------
-5.2525098089598E33
所以这里实际上是一个number(34)。
Leave a comment