初始ORACLE DUMP 函数
2012-02-09
起因:
上个月某个晚上(具体时间我也记不清了),我在等同事系统升级完成后,以便后续我进行应用测试。一个人晚上在办公室中等同事升级完成的电话实在是很“刮三”、很无聊的事情。为了打发时间,在网上漫无目的查点资料看看,无意中看到了ICTCLAS分词系统,在了解该系统和它所带字库文件过程时,突然冒出想探寻一下在Oracle中数据是如何保存和获取的。此Blog也仅仅记录我在了解过程中的点点滴滴,顺便也锻炼一下自己的语言能力,更为了督促自己持续学习,控制平时晚上花在下围棋的时间。纠结一下,ITPUB的那个博客太不好用了,期间还用了sina 博客,最后还是选择博客园。
环境:
VM6.5+Win2003 SP1+ Oracle 11.2.0.1(32-bit)
Oracle 数据库字符集:ZHS16GBK 国家字符集AL16UTF16
今天的任务:
了解oracle DUMP函数
目的:
了解信息在由DUMP函数处理后是如何输出的。
简单接受,开始我的学习路程。
首先了解一个DUMP的语法
(该图取自Oralce官方文档Oracle® Database SQL Language Reference 11g Release 2 (11.2))
DUMP函数返回一个Varchar2的值,该值格式如下
Type=××× Len=×××: ×××(,×××)*
Type可以参阅Data Types
Len 字节数
参数说明:
return_fmt
8 返回8进制结果
10 返回10进制结果
16返回16进制结果
17以每个字节作为单个字符返回,当且仅当它可以被解释为编译器的字符集中的可打印字符-------通常是ASCII or EBCDIC。
start_position and length
确定要返回的内部表示形式的哪个部分。
expr 为 null,则此函数返回 NULL。
该函数不支持CLOB直接作为参数。但是,可以作为通过隐式数据转换参数中传递 CLOB值。
例子如下:
SQL> select dump(1,16) from dual;
DUMP(1,16)
-----------------
Typ=2 Len=2: c1,2
SQL> select dump(1,10) from dual;
DUMP(1,10)
------------------
Typ=2 Len=2: 193,2
SQL> select dump('火狐',16) from dual;
DUMP('火狐',16)
-------------------------
Typ=96 Len=4: bb,f0,ba,fc
SQL> select dump('US',16) from dual;
DUMP('US',16)
-------------------
Typ=96 Len=2: 55,53
SQL> select dump('US',17) from dual;
DUMP('US',17)
-----------------
Typ=96 Len=2: U,S
SQL> select dump('火狐',17) from dual;
DUMP('火狐',17)
-------------------------
Typ=96 Len=4: bb,f0,ba,fc
SQL> select dump(1,17) from dual;
DUMP(1,17)
------------------
Typ=2 Len=2: c1,^B
SQL> select dump('火狐',17,1,1) from dual;
DUMP('火狐',17,1
----------------
Typ=96 Len=4: bb
SQL> select dump('火狐',17,1,2) from dual;
DUMP('火狐',17,1,2)
-------------------
Typ=96 Len=4: bb,f0
其次,了解一下Number类型数据在DUMP是如何处理的。
Number型数据经DUMP函数处理以后,输出格式如下:
Type=2 Len=×××:符号/指数位, [数字1,数字2,数字3,. . . ,数字20]
Type=2 :表示Number类型
注意:如果是负数,且总长度小于21个字节,最后加一个102(是为了排序的需要)
DUMP(number,10)是以指数的方式处理的
正数: 符号/指数位 > 128
计算公式:
指数=符号/指数位(第一字节)-193, 设 N为指数
数值1 = (数字1-1)*100^(N-0)
数值2 = (数字2-1)*100^(N-1)
.
.
.
数值20 = (数字20-1)*100^(N-19)
-------------------------------------------------------------
Number数值 sum(数值1,数值2,数值3,. . . , 数值20)
负数:符号/指数位 < 128
指数=62-符号/指数位(第一字节),设 N为指数
数值1 = (101-数字1)*100^(N-0)
数值2 = (101-数字2)*100^(N-1)
.
.
.
数值20 = (101-数字20)*100^(N-19)
-------------------------------------------------------------
Number数值 sum(数值1,数值2,数值3,. . . , 数值20)
0是区分正数和负数的分割点,0既不属于正数也不属于负数
0的以10进制方式DUMP出来的信息如下:
SQL> select dump(0) from dual;
DUMP(0)
----------------
Typ=2 Len=1: 128
根据上面的信息,我们可以计算得到16进制的DUMP信息应该是0X80,转换成二进制为1000 0000,正好是是一个字节编码最大值的一半。
以根据上面正数和负数的公式,我们计算以下数值的10和16进制的DUMP信息:
1)、150 2)、34.33 3)、-140 4)、 -333.99
第1)解题步骤:
150=100+50=100^1+ 50 ,
故根据上述,应该可以初步确认,150 DUMP函数输出格式:
Type=2 Len=3: 符号/指数位(第一字节),数字1,数字2
指数=符号/指数位(第一字节)-193 ,符号/指数位(第一字节)=194
100 ^1=(数字1-1)*100^(1-0)=(数字1-1)*100
数字1-1=1 ===> 数字1 = 2
50=(数字2-1)*100^(1-1)= (数字2-1)*1
数字2-1=50 ===> 数字2 = 51
150的DUMP函数10进制输出为: Type=2 Len=3: 194, 2, 51
根据上面,10进制194, 2, 51转换为16进制,则DUMP函数16进制为:
Type=2 Len=3: C2, 2, 33
Oracle SQL确认:
SQL> select dump(150) from dual;
DUMP(150)
---------------------
Typ=2 Len=3: 194,2,51
SQL> select dump(150,16) from dual;
DUMP(150,16)
--------------------
Typ=2 Len=3: c2,2,33
SQL>
第2)解题步骤:
33.33=33+0.33= (数字1-1)*100^(N-0)+ (数字2-1)*100^(N-1)
可以初步确认,33.33 DUMP函数输出格式:
Type=2 Len=3: 符号/指数位(第一字节),数字1,数字2
33 < 100 ===> 33 < 100^1 ===> N = 0
符号/指数位(第一字节)= 193
(数字1-1)*100^0=33 ===> 数字1=34
(数字2-1)*100^(0-1)=0.33 ===> 数字2-1 = 33 ===> 数字2=34
33.33的DUMP函数10进制输出为: Type=2 Len=3: 193, 34, 34
16进制输出格式:Type=2 Len=3: C1, 22, 22
Oracle SQL确认:
SQL> select dump(33.33,16) from dual;
DUMP(33.33,16)
---------------------
Typ=2 Len=3: c1,22,22
SQL> select dump(33.33) from dual;
DUMP(33.33)
----------------------
Typ=2 Len=3: 193,34,34
第3题忽略不做……
第4)解题步骤:
-333.99=-(300+33+0.99)=-(3*100^1+33+0.99)
是负数
可以初步确认,-333.99 DUMP函数输出格式:
Type=2 Len=5: 符号/指数位(第一字节),数字1,数字2,数字3 , 120
指数=62-符号/指数位(第一字节), 数字1上的指数是1 ,N=1
故 1=62-符号/指数位(第一字节) ===> 符号/指数位(第一字节)=61
3*100^1 = (101-数字1)*100^(N-0)= (101-数字1)*100^1 ===> 3 = (101-数字1)
数字1=98
33=(101-数字2)*100^(1-1) ===> 33= (101-数字2)
数字2=68
0.99==(101-数字3)*100^(1-2) ===> 0.99= (101-数字3)*100^-1
数字3 = 2
-333.99的DUMP函数10进制输出为: Type=2 Len=5: 61, 98, 68, 2,102
16进制输出格式:Type=2 Len=5: 3D, 62, 44,2,66
Oracle SQL确认:
SQL> select dump(-333.99) from dual;
DUMP(-333.99)
---------------------------
Typ=2 Len=5: 61,98,68,2,102
SQL> select dump(-333.99,16) from dual;
DUMP(-333.99,16)
--------------------------
Typ=2 Len=5: 3d,62,44,2,66