sql >select * from tab;
TNAME TABTYPE CLUSTERID
------------------------------ ------- ----------
TEST_CHAR TABLE
TABLE3 TABLE
MY_ALL_OBJECTS TABLE
TEST TABLE
已用时间: 00: 00: 00.01
sql >select rowid from test where rownum<2;
ROWID
------------------
AAAM1KAAEAAAAGcAAA
rowid 有18位 每位采用64位编码 分别A-Z a-z 0-9 + / 共64位字符表示。A表示0 ... z表示25 a表示26
z表示51 0为52 9为61 +为62 /为63。
rowid 分为逻辑ROWID(索引组织表使用) 和 物理ROWID 。
Rowid前6 位是data object number
7-9 位是相对表空间的数据文件号
10-15位是数据所在的block号
后三位是记录号
计算公式如下 ( d * b^p ) b基数为64 p是从右到左 以0开始
如上面的 AAE(文件号) 0+0+4*(64^0) = 4 参照上面字符所对应的number
也可以通过以下代码计算出记录所在文件号和块号
sql>select dbms_rowid.rowid_object('AAAM1KAAEAAAAGcAAA') obj_id,
dbms_rowid.rowid_relative_fno('AAAM1KAAEAAAAGcAAA') file_id,
dbms_rowid.rowid_block_number('AAAM1KAAEAAAAGcAAA') block_id,
dbms_rowid.rowid_row_number('AAAM1KAAEAAAAGcAAA') num from dual;
OBJ_ID FILE_ID BLOCK_ID NUM
---------- ---------- ---------- ----------
52554 4 412 0
最终要记录所在的 文件号 和 块号有什么用呢 ?
sql >alter system dump datafile 4 block 412;
可以去 ORACLE_HOME/admin/orcl/udump 文件夹下去查找最新的trc文件 在其中可以看到这行存储的数据
创建了一个名为test_char的表 结构如下:
c:/>desc test_char
名称 是否为空? 类型
----------------------------------------- -------- ---------------------------
CHAR_COL CHAR(10)
VARCHAR_COL VARCHAR2(10)
LOG_COL LONG
c:/>select * from test_char; --查询表内容
CHAR_COL VARCHAR_CO LOG_COL
---------- ---------- --------------------
abc 123 fd
将这行的数据dump 出来 打开ORACLE_HOME/admin/orcl/udump/orcl_ora_2136.trc文件如下
......
......
......
0xe:pti[0] nrow=1 offs=0
0x12:pri[0] offs=0x1f83
block_row_dump:
tab 0, row 0, @0x1f83
tl: 21 fb: --H-FL-- lb: 0x1 cc: 3
col 0: [10] 61 62 63 20 20 20 20 20 20 20
col 1: [ 3] 31 32 33
col 2: [ 2] 66 64
end_of_block_dump
End dump data blocks tsn: 7 file#: 6 minblk 20 maxblk 20
当前文件的上面可以忽略 看看 col 0: [10] 列 61 62 63 表示 a b c 20 表示空
col 1: [ 3] 31 32 33 表示 1 2 3
col 2: [ 2] 66 64 表示 f d
这是如何计算的呢?
c:/>select to_number('61','xx') from dual;
TO_NUMBER('61','XX')
--------------------
97
已用时间: 00: 00: 00.00
c:/>select chr(97) from dual;
C
-
a
SQL> SELECT DUMP(CHAR_COL, 16) D_CHAR FROM TEST_CHAR;
D_CHAR
------------------------------------------------------------
Typ=96 Len=10: 61,62,63,20,20,20,20,20,20,20
SQL> SELECT DUMP(VARCHAR_COL, 16) D_VARCHAR2 FROM TEST_CHAR;
D_VARCHAR2
-------------------------------------------------------------
Typ=1 Len=3: 31,32,33
SQL> SELECT DUMP(LONG_COL, 16) D_VARCHAR2 FROM TEST_CHAR;
SELECT DUMP(LONG_COL, 16) D_VARCHAR2 FROM TEST_CHAR
7a|9`5a5Z0 *
Fy9ji!k0ERROR 位于第 1 行:
ORA-00997: 非法使用 LONG 数据类型
由于DUMP不支持LONG类型,因此我们使用了alter system dump block的方式,
通过比较两种方式得到的结果,发现DUMP()函数不但方便,结果清晰,而且指出了进行DUMP的数据类型,
在以后的例子中,除非必要的情况,否则都会采用DUMP()函数的方式进行说明。
--进制转换
1.16进制转换为10进制
可以通过to_number函数实现
SQL> select to_number('19f','xxx') from dual;
TO_NUMBER('19F','XXX')
----------------------
415
SQL> select to_number('f','xx') from dual;
TO_NUMBER('F','XX')
-------------------
15
2.10进制转换为16进制
可以通过to_char函数转换
SQL> select to_char(123,'xxx') from dual;
TO_C
----
7b
SQL> select to_char(4567,'xxxx') from dual;
TO_CH
-----
11d7
3.2进制转换为10进制
从Oracle9i开始,提供函数bin_to_num进行2进制到10进制的转换
SQL> select bin_to_num(1,1,0,1) a,bin_to_num(1,0) b from dual;
A B
----- ----------
13 2
SQL> select bin_to_num(1,1,1,0,1) from dual;
BIN_TO_NUM(1,1,1,0,1)
---------------------
29