利用dump函数理解oracle如何存储各种类型数据

摘要:
因为这个机器是little-endianarchitecture的服务器,“221,7”应该解读为“7,221”,两个数字分别换算成十六进制后合起来就是“0x7DD”,即2013,这就对上了!1SYS@crmASSYSDBA˃selectto_charfromdual;2TO_C3----4dd5Elapsed:00:00:00.0067SYS@crmASSYSDBA˃selectto_numberFROMDUAL;8TO_NUMBER9----------------------1020132.2Number类型Number类型dump出来有点特别,value方面里第一个数字代表符号位/指数,按以下方法来计算正数:指数=value1-193负数:指数=62-value1从value2开始,正数加1存储;负数被101减后存储,并且如果总长度小于21个字节,为了排序的需要,最后加一个102。

1.dump函数介绍

1.1标准格式

DUMP(expr[,return_fmt[,start_position][,length]])

expr:需要dump的表达式

return_fmt:指返回参数的格式,有5种用法:

1)8:以8进制返回结果的值

2)10:以10进制返回结果的值(默认)

3)16:以16进制返回结果的值

4)17:以单字符的形式返回结果的值

5)1000:以上4种加上1000,表示在返回值中加上当前字符集

start_position:需要返回的起始字符位置

length:需要返回的字符长度

1.2 返回结果

返回结果包含三方面值,分别是TYPE、LEN、VALUE,例如

1 DUMP('ABC')
2 ----------------------
3 Typ=96 Len=3: 97,98,99

其一,typ表示当前的expr值的类型,有如下类型

1 CODE TYP
2 ----- ------------------------------
3 1     VARCHAR2
4 2     NUMBER
5 8     LONG
6 12DATE
7 23    RAW
8 24    LONG RAW
9 69ROWID
10 96    CHAR
11 112CLOB
12 113BLOB
13 114BFILE
14 180   TIMESTAMP
15 181   TIMESTAMP WITHTIMEZONE
16 182   INTERVAL YEAR TO MONTH
17 183   INTERVAL DAY TOSECOND
18 208UROWID
19 231   TIMESTAMP WITH LOCAL TIMEZONE

其二,len表示该值所占用的字节数

其三,value部分即为oracle在内部如何来存储这个expr值

2.几种常用数据类型的dump

2.1Date类型

1 SYS@crm AS SYSDBA>col DUMP_DATE format a50
2 SYS@crm AS SYSDBA>select dump(last_ddl_time) dump_date, to_char(last_ddl_time,'yyyy-mm-dd hh24:mi:ss') real_date from user_objects where rownum=1;
3 
4 DUMP_DATE                                          REAL_DATE
5 -------------------------------------------------- -------------------
6 Typ=12 Len=7: 120,112,5,21,21,33,9                 2012-05-21 20:32:08
7 
8 Elapsed: 00:00:00.01

Oracle是按如下表格所示来存储date类型数据的,根据dump值做相应的逆行运算即可.

世纪

120- 100 =20

世纪和年份加100后存储

年份

112- 100 =12

月份

5

月份和日期按原值存储

日期

21

小时

21- 1 =20

时间均加1后存储

分钟

33- 1 =32

9- 1 =8

留意了一下内存中date类型数据的表示,果然还是不一样。

1 SYS@crm AS SYSDBA>col dumpsysdate format a50
2 SYS@crm AS SYSDBA>select dump(sysdate) dumpsysdate, sysdate fromdual;
3 
4 DUMPSYSDATE                                        SYSDATE
5 -------------------------------------------------- -------------------
6 Typ=13 Len=8: 221,7,7,29,12,5,25,0                 2013-07-29 12:05:25

这里有几个需要注意的:typ变成了13,这在上面列举的数据类型表里貌似没有。看的出来,除了世纪和年份,其它值和真实值都一模一样;那这里的2013是怎么运算得出221,7的呢?

因为这个机器是little-endian architecture的服务器,“221,7”应该解读为“7,221”,两个数字分别换算成十六进制后合起来就是“0x7DD”,即2013,这就对上了!

1 SYS@crm AS SYSDBA>select to_char(221,'xxx') fromdual;
2 TO_C
3 ----
4 dd
5 Elapsed: 00:00:00.00
6 
7 SYS@crm AS SYSDBA>select to_number('7DD','XXX') FROMDUAL;
8 TO_NUMBER('7DD','XXX')
9 ----------------------
10                   2013

2.2 Number类型

Number类型dump出来有点特别,value方面里第一个数字(用value1来表示)代表符号位/指数,按以下方法来计算

正数:指数=value1 - 193 (value1换算成二进制后最高位为1则代表正数)
负数:指数=62 -value1(value1换算成二进制后最高位为0则代表负数)

从value2开始,正数加1存储;负数被101减后存储,并且如果总长度小于21个字节,为了排序的需要,最后加一个102。

所存储的数值计算方法为:

把下面计算的结果加起来:

每个数字乘以100^(指数-N)(N是有效位数的顺序位,第一个有效位的N=0)

例:

1 select dump(123456.789) fromdual;
2 DUMP(123456.789)
3 -------------------------------
4 Typ=2 Len=6: 195,13,35,57,79,91

Value1(指数)

195- 193 = 2

Value2

13- 1 = 12

*1002-0

120000

Value3

35- 1 = 34

*1002-1

3400

Value4

57- 1 = 56

*1002-2

56

Value5

79- 1 = 78

*1002-3

.78

Value6

91- 1 = 90

*1002-4

.009

123456.789

1 select dump(-123456.789) fromdual;
2 DUMP(-123456.789)
3 ----------------------------------
4 Typ=2 Len=7: 60,89,67,45,23,11,102

Value1(指数)

62 -60= 2

Value2

101 -89= 12

*1002-0

120000

Value3

101 -67= 34

*1002-1

3400

Value4

101 -45= 56

*1002-2

56

Value5

101 -23= 78

*1002-3

.78

Value6

101 -11= 90

*1002-4

.009

123456.789(-)

这里在最后加102是为了排序的需要,-123456.789在数据库中实际存储为

60,89,67,45,23,11

而-123456.78901在数据库中实际存储为

60,89,67,45,23,11,91

可见,如果不在最后加上102,在排序时会出现-123456.789<-123456.78901的情况

2.3charvarchar2类型

英文字符的dump值可以直接理解为对应的ASCII码。

1 SYS@crm AS SYSDBA>select dump('abcdefg') fromdual;
2 DUMP('ABCDEFG')
3 --------------------------------------
4 Typ=96 Len=7: 97,98,99,100,101,102,103

中文字符的dump值则要看具体的字符集了。

1 SYS@crm AS SYSDBA>select dump('笑看风云') fromdual;
2 DUMP('笑看风云')
3 --------------------------------------------------------------
4 Typ=96 Len=12: 231,172,145,231,156,139,233,163,142,228,186,145
5 Elapsed: 00:00:00.00
6 SYS@crm AS SYSDBA>select dump('笑看风云',1010) fromdual; 7 DUMP('笑看风云',1010) 8 ------------------------------------------------------------------------------------ 9 Typ=96 Len=12 CharacterSet=AL32UTF8: 231,172,145,231,156,139,233,163,142,228,186,145 10 Elapsed: 00:00:00.00

下面看看char varchar2两种类型数据的存储的区别。

1 SYS@crm AS SYSDBA>create table zjtest(c1 varchar2(10),c2 char(10));
2 Tablecreated.
3 Elapsed: 00:00:00.11
4 
5 SYS@crm AS SYSDBA>insert into zjtest values (1,1);
6 1row created.
7 Elapsed: 00:00:00.00
8 
9 SYS@crm AS SYSDBA>insert into zjtest values (2,2);
10 1row created.
11 Elapsed: 00:00:00.00
12 
13 SYS@crm AS SYSDBA>insert into zjtest values (3,3);
14 1row created.
15 Elapsed: 00:00:00.00
16 SYS@crm AS SYSDBA>commit;
17 SYS@crm AS SYSDBA>col DUMP(C1) format a50
18 SYS@crm AS SYSDBA>col DUMP(C2) format a50
19 SYS@crm AS SYSDBA>select c1,dump(c1),c2,dump(c2) fromzjtest;
20 
21 C1         DUMP(C1)                                           C2         DUMP(C2)
22 ---------- -------------------------------------------------- ---------- --------------------------------------------------
23 1          Typ=1 Len=1: 49                                    1          Typ=96 Len=10: 49,32,32,32,32,32,32,32,32,32
24 2          Typ=1 Len=1: 50                                    2          Typ=96 Len=10: 50,32,32,32,32,32,32,32,32,32
25 3          Typ=1 Len=1: 51                                    3          Typ=96 Len=10: 51,32,32,32,32,32,32,32,32,32
26 
27 Elapsed: 00:00:00.00

两者的区别一览无余。

注:本文部分内容引用自eygle博客http://www.eygle.com/archives/2005/12/how_oracle_stor.html

免责声明:文章转载自《利用dump函数理解oracle如何存储各种类型数据》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇MD5算法微信 ios端config配置失败 android端正常下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

这样做,免费从Oracle同步数据

点击▲关注 “数据和云” 给公众号标星置顶 更多精彩 第一时间直达 刘伟 刘伟,云和恩墨软件开发部研究院研究员;前微博DBA,主要研究方向为开源数据库,分布式数据库,擅长自动化运维以及数据库内核研究。 不得不承认的一点是,当前数据库的使用趋势,至少在国内,是逐渐从Oracle转向MySQL(扩大化概念的话,就是包括PG等在内的开源数据库,以及rds类的云...

授权某个数据库某个表权限

revoke SELECT ON `open`.`admins` from wuzg;revoke SELECT ON *.* from wuzg;show GRANTS for wuzg;GRANT SELECT ON open.admins TO 'wuzg'@'%'...

oracle中建立函数?如何查看自己都建立了哪些函数?

SQL PLUS下:查看建了哪些函数,注意,引号内大写select object_name from user_objects where object_type='FUNCTION';查看函数内容,引号内为你要查询的函数名,也要大写select text from user_source where name='函数名'; PLSQL Developer...

SQL 删除前100条 with as

with cte as(select top 50* from tableName)delete from cte WITH AS短语,也叫做子查询部分(subquery factoring),可以让你做很多事情,定义一个SQL片断,该SQL片断会被整个SQL语句所用到。有的时候,是为了让SQL语句的可读性更高些,也有可能是在UNION ALL的不同部分,...

Oracle查询用户权限

Oracle查询用户权限-- 确定角色的权限select * from role_tab_privs ; 包含了授予角色的对象权限select * from role_role_privs ; 包含了授予另一角色的角色select * from role_sys_privs ; 包含了授予角色的系统权限-- 确定用户帐户所授予的权限select * fro...

Oracle子查询相关内容(包含TOP-N查询和分页查询)

本节介绍Oracle子查询的相关内容: 实例用到的数据为oracle中scott用户下的emp员工表,dept部门表,数据如下: 一、子查询 1、概念:嵌入在一个查询中的另一个查询语句,也就是说一个查询作为另一个查询的条件,这个查询称为子查询。 那么可以使用子查询的位置有select后面、from后面、where后面以及having后面。 2、分类:(1...