从DUMP函数说开去
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                从DUMP函数说开去
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.                        
                                
                            
                            
                            ? ? 因為最近研究字符集,所以對于Oracle內部的一些存儲模式產生了一些興趣,據(jù)說DUMP這個函數(shù)的功能非常強大,所以專門研究了一下。當然研究的都比較初級,只是了解一下。具體哪里可以用到暫時還不知道 -_-||| ,另外對字符集的轉換等一些函數(shù)也了解一下:
 
 ?
 
 ?
 
 一、函數(shù)用法?
? ??? 函數(shù)的標準格式是:DUMP(expr[,return_fmt[,start_position][,length]]) ? ??? 基本參數(shù)時4個,最少可以填的參數(shù)時0個,當完全沒有參數(shù)時,直接返回null。另外3個參數(shù)也都有各自的默認值,一個一個來看: ? ????expr:這個參數(shù)是要進行分析的表達式(數(shù)字或字符串等,可以是各個類型的值) ????return_fmt:指返回參數(shù)的格式,這個參數(shù)有5種用法 ??????? 1) 8:以8進制返回結果的值 ??????? 2) 10:以10進制返回結果的值(默認) ??????? 3) 16:以16進制返回結果的值 ??????? 4) 17:以單字符的形式返回結果的值 ??????? 5) 1000:以上4種加上1000,表示在返回值中加上當前字符集 ????start_position:開始進行返回的字符位置 ????length:需要返回的字符長度 ? ? 舉幾個例子: ? SQL> SELECT DUMP('abc') FROM DUAL;
?
DUMP('ABC')
----------------------
Typ=96 Len=3: 97,98,99
?
SQL> SELECT DUMP('abc',16) FROM DUAL;
?
DUMP('ABC',16)
----------------------
Typ=96 Len=3: 61,62,63
?
SQL> SELECT DUMP('abc',1016) FROM DUAL;
?
DUMP('ABC',1016)
----------------------------------------
Typ=96 Len=3 CharacterSet=UTF8: 61,62,63
?
SQL> SELECT DUMP('abc',17,2,2) FROM DUAL;
?
DUMP('ABC',17,2,2)
------------------
Typ=96 Len=3: b,c ? ? 二、結果分析 ? ??? 結果的格式一般都是類似: typ=96 Len=3 [CharacterSet=UTF8]: 61,62,63 ? ??? 1、type ? ??? 其中typ表示了當前的expr值的類型,例如2表示NUMBER,96表示CHAR等等。 ??? 具體的所有格式列表在SQL Reference文檔中沒有找到,但是在網上找到了,網址:http://vongates.itpub.net/post/2553/17275?
? CODE TYP
----- ------------------------------
??? 1 VARCHAR2
??? 2 NUMBER
??? 8 LONG
?? 12 DATE
?? 23 RAW
?? 24 LONG RAW
?? 69 ROWID
?? 96 CHAR
? 112 CLOB
? 113 BLOB
? 114 BFILE
? 180 TIMESTAMP
? 181 TIMESTAMP WITH TIMEZONE
? 182 INTERVAL YEAR TO MONTH
? 183 INTERVAL DAY TO SECOND
? 208 UROWID
? 231 TIMESTAMP WITH LOCAL TIMEZONE ? ??? 具體可以從USER_TAB_COLS視圖的定義中獲取這個方法: ? select text from dba_views where view_name = 'USER_TAB_COLS'; ? ??? 2、Len ? ??? Len表示該值所占用的字節(jié)數(shù)。 ? ??? 這個沒有什么好解釋的,但是有時我們也可以使用這個特性發(fā)現(xiàn)一些問題,例如: ? SQL> select value from v$nls_parameters where parameter='NLS_CHARACTERSET';
?
VALUE
----------------------------------------------------------------
UTF8
?
SQL> select dump('多多',1010) from dual;
?
DUMP('多多',1010)
-------------------------------------------------------
Typ=96 Len=6 CharacterSet=UTF8: 229,164,154,229,164,154
? ? SQL> conn?wxq/wxq@win10gr2 ?
SQL> select value from v$nls_parameters where parameter='NLS_CHARACTERSET';
?
VALUE
----------------------------------------------------------------
ZHS16GBK
?
SQL> select dump('多多',1010) from dual;
?
DUMP('多多',1010)
---------------------------------------------------
Typ=96 Len=4 CharacterSet=ZHS16GBK: 182,224,182,224 ? ??? 可以看到,UTF8對于漢字來說,需要3個字節(jié)來存儲1個漢字,而我們常用的ZHS16GBK只需要2個字節(jié)。 ? ? ??? 3、Value ? ??? 最后就是具體的存儲值了,這里的講究就比較多了,不是幾句話就能夠講得清楚的,更何況我自己就不清楚。恩,簡單得來說,這些返回的數(shù)值就是Oracle在自己內部對前面的這個expr值的存儲形式。對于非漢字的普通字符串,可以理解為就是它的ASCII碼(字符集中的編碼值)。可以舉個例子證明一下: ? SQL> select dump('a=?5') from dual;
?
DUMP('A=?5')
-------------------------
Typ=96 Len=4: 97,61,63,53
 
SQL> SELECT CHR(97),CHR(61),CHR(63),CHR(53) FROM DUAL;
?
CHR(97) CHR(61) CHR(63) CHR(53)
------- ------- ------- -------
a?????? =?????? ??????? 5
?
SQL> SELECT ASCII('a'),ASCII('='),ASCII('?'),ASCII('5') FROM DUAL;
?
ASCII('A') ASCII('=') ASCII('?') ASCII('5')
---------- ---------- ---------- ----------
??????? 97???????? 61???????? 63???????? 53 ? ??? 而對于漢字的存儲,就不太好測試了,而且也沒有搞清楚原理,應該是直接套用字符集的漢字編碼規(guī)則的。 ? ??? 對于數(shù)字的存儲,并不像字符那么簡單,而是應用了Oracle自己的一個算法,eygle有過很詳細的說明: ??? 具體的算法原理可以參見eygle的這篇文章:http://www.eygle.com/archives/2005/12/how_oracle_stor.html ? 三、關于其他 ? ??? 順帶介紹一下怎么查找?Oracle對字符集類型的編碼(dump文件的前2個字節(jié)): ? ??? SELECT NLS_CHARSET_NAME(1) FROM DUAL;? --返回數(shù)值對應的字符集名稱
??? SELECT NLS_CHARSET_ID('US7ASCII') FROM DUAL;? --返回字符集對應的數(shù)值 ? ? ? ? ? 附:dump函數(shù)對number的存儲表示 http://www.eygle.com/archives/2005/12/how_oracle_stor.html -------------------------------------------------------------------------------- How Oracle Store Number internal??
作者:eygle |English Version 【轉載時請以超鏈接形式標明文章出處和作者信息及本聲明】
鏈接:?http://www.eygle.com/archives/2005/12/how_oracle_stor.html?
--------------------------------------------------------------------------------
Oracle在數(shù)據(jù)庫內部通過相應的算法轉換來進行數(shù)據(jù)存儲,本文簡單介紹Oracle的Number型數(shù)值存儲及轉換.這個內容是為了回答留言板上的2119號問題. ? 我們可以通過DUMP函數(shù)來轉換數(shù)字的存儲形式,一個簡單的輸出類似如下格式: ? SQL> select dump(1) from dual; DUMP(1) ------------------ Typ=2 Len=2: 193,2 ? DUMP函數(shù)的輸出格式類似: ? 類型 <[長度]>,符號/指數(shù)位 [數(shù)字1,數(shù)字2,數(shù)字3,......,數(shù)字20] ? 各位的含義如下: ? 1.類型: Number型,Type=2 (類型代碼可以從Oracle的文檔上查到) ? 2.長度:指存儲的字節(jié)數(shù) ? 3.符號/指數(shù)位 ? 在存儲上,Oracle對正數(shù)和負數(shù)分別進行存儲轉換: ? 正數(shù):加1存儲(為了避免Null)
負數(shù):被101減,如果總長度小于21個字節(jié),最后加一個102(是為了排序的需要) ? 指數(shù)位換算: ? 正數(shù):指數(shù)=符號/指數(shù)位 - 193 (最高位為1是代表正數(shù))?
負數(shù):指數(shù)=62 - 第一字節(jié) ? 4.從<數(shù)字1>開始是有效的數(shù)據(jù)位 ? 從<數(shù)字1>開始是最高有效位,所存儲的數(shù)值計算方法為: ? 將下面計算的結果加起來: ? 每個<數(shù)字位>乘以100^(指數(shù)-N) (N是有效位數(shù)的順序位,第一個有效位的N=0) ? 5. 舉例說明 ? SQL> select dump(123456.789) from dual; DUMP(123456.789) ------------------------------- Typ=2 Len=6: 195,13,35,57,79,91 ?
<指數(shù)>:?? 195 - 193 = 2?
<數(shù)字1>??? 13 - 1??? = 12 *100^(2-0) 120000?
<數(shù)字2>??? 35 - 1??? = 34 *100^(2-1) 3400?
<數(shù)字3>??? 57 - 1??? = 56 *100^(2-2) 56?
<數(shù)字4>??? 79 - 1??? = 78 *100^(2-3) .78?
<數(shù)字5>??? 91 - 1??? = 90 *100^(2-4) .009?
??????????????????????????? 123456.789 ? SQL> select dump(-123456.789) from dual; DUMP(-123456.789) ---------------------------------- Typ=2 Len=7: 60,89,67,45,23,11,102 ?
<指數(shù)>???? 62 - 60 = 2(最高位是0,代表為負數(shù))?
<數(shù)字1> 101 - 89 = 12 *100^(2-0) 120000?
<數(shù)字2> 101 - 67 = 34 *100^(2-1) 3400?
<數(shù)字3> 101 - 45 = 56 *100^(2-2) 56?
<數(shù)字4> 101 - 23 = 78 *100^(2-3) .78?
<數(shù)字5> 101 - 11 = 90 *100^(2-4) .009?
????????????????????????????? 123456.789(-) ? 現(xiàn)在再考慮一下為什么在最后加102是為了排序的需要,-123456.789在數(shù)據(jù)庫中實際存儲為 ? 60,89,67,45,23,11 ? 而-123456.78901在數(shù)據(jù)庫中實際存儲為 ? 60,89,67,45,23,11,91 ? 可見,如果不在最后加上102,在排序時會出現(xiàn)-123456.789<-123456.78901的情況。 ? 對于2119號提問,第一個問題是: ? 1.請問為什么193,2各代表什么意思? ? 從上面就可以看到答案了. ? 2.還有NUMBER數(shù)字類型為什么有2個字節(jié)的長度呢? ? 對于這個問題,我想我們應該知道,所有數(shù)據(jù)類型最終在計算機里都以二進制存儲,實際上所謂的數(shù)據(jù)類型都是我們定義的.所以存儲只由算法決定. ? 所以這個問題是不成立的.比如: ? SQL> select dump(110) from dual; DUMP(110) --------------------- Typ=2 Len=3: 194,2,11 ? SQL> select dump(1100) from dual; DUMP(1100) ------------------- Typ=2 Len=2: 194,12 ?
我們會看到,雖然1100>110,但是存儲上1100卻只占2字節(jié),而110卻占了3個字節(jié).
                        
                        
                        ? ??? 函數(shù)的標準格式是:DUMP(expr[,return_fmt[,start_position][,length]]) ? ??? 基本參數(shù)時4個,最少可以填的參數(shù)時0個,當完全沒有參數(shù)時,直接返回null。另外3個參數(shù)也都有各自的默認值,一個一個來看: ? ????expr:這個參數(shù)是要進行分析的表達式(數(shù)字或字符串等,可以是各個類型的值) ????return_fmt:指返回參數(shù)的格式,這個參數(shù)有5種用法 ??????? 1) 8:以8進制返回結果的值 ??????? 2) 10:以10進制返回結果的值(默認) ??????? 3) 16:以16進制返回結果的值 ??????? 4) 17:以單字符的形式返回結果的值 ??????? 5) 1000:以上4種加上1000,表示在返回值中加上當前字符集 ????start_position:開始進行返回的字符位置 ????length:需要返回的字符長度 ? ? 舉幾個例子: ? SQL> SELECT DUMP('abc') FROM DUAL;
?
DUMP('ABC')
----------------------
Typ=96 Len=3: 97,98,99
?
SQL> SELECT DUMP('abc',16) FROM DUAL;
?
DUMP('ABC',16)
----------------------
Typ=96 Len=3: 61,62,63
?
SQL> SELECT DUMP('abc',1016) FROM DUAL;
?
DUMP('ABC',1016)
----------------------------------------
Typ=96 Len=3 CharacterSet=UTF8: 61,62,63
?
SQL> SELECT DUMP('abc',17,2,2) FROM DUAL;
?
DUMP('ABC',17,2,2)
------------------
Typ=96 Len=3: b,c ? ? 二、結果分析 ? ??? 結果的格式一般都是類似: typ=96 Len=3 [CharacterSet=UTF8]: 61,62,63 ? ??? 1、type ? ??? 其中typ表示了當前的expr值的類型,例如2表示NUMBER,96表示CHAR等等。 ??? 具體的所有格式列表在SQL Reference文檔中沒有找到,但是在網上找到了,網址:http://vongates.itpub.net/post/2553/17275?
? CODE TYP
----- ------------------------------
??? 1 VARCHAR2
??? 2 NUMBER
??? 8 LONG
?? 12 DATE
?? 23 RAW
?? 24 LONG RAW
?? 69 ROWID
?? 96 CHAR
? 112 CLOB
? 113 BLOB
? 114 BFILE
? 180 TIMESTAMP
? 181 TIMESTAMP WITH TIMEZONE
? 182 INTERVAL YEAR TO MONTH
? 183 INTERVAL DAY TO SECOND
? 208 UROWID
? 231 TIMESTAMP WITH LOCAL TIMEZONE ? ??? 具體可以從USER_TAB_COLS視圖的定義中獲取這個方法: ? select text from dba_views where view_name = 'USER_TAB_COLS'; ? ??? 2、Len ? ??? Len表示該值所占用的字節(jié)數(shù)。 ? ??? 這個沒有什么好解釋的,但是有時我們也可以使用這個特性發(fā)現(xiàn)一些問題,例如: ? SQL> select value from v$nls_parameters where parameter='NLS_CHARACTERSET';
?
VALUE
----------------------------------------------------------------
UTF8
?
SQL> select dump('多多',1010) from dual;
?
DUMP('多多',1010)
-------------------------------------------------------
Typ=96 Len=6 CharacterSet=UTF8: 229,164,154,229,164,154
? ? SQL> conn?wxq/wxq@win10gr2 ?
SQL> select value from v$nls_parameters where parameter='NLS_CHARACTERSET';
?
VALUE
----------------------------------------------------------------
ZHS16GBK
?
SQL> select dump('多多',1010) from dual;
?
DUMP('多多',1010)
---------------------------------------------------
Typ=96 Len=4 CharacterSet=ZHS16GBK: 182,224,182,224 ? ??? 可以看到,UTF8對于漢字來說,需要3個字節(jié)來存儲1個漢字,而我們常用的ZHS16GBK只需要2個字節(jié)。 ? ? ??? 3、Value ? ??? 最后就是具體的存儲值了,這里的講究就比較多了,不是幾句話就能夠講得清楚的,更何況我自己就不清楚。恩,簡單得來說,這些返回的數(shù)值就是Oracle在自己內部對前面的這個expr值的存儲形式。對于非漢字的普通字符串,可以理解為就是它的ASCII碼(字符集中的編碼值)。可以舉個例子證明一下: ? SQL> select dump('a=?5') from dual;
?
DUMP('A=?5')
-------------------------
Typ=96 Len=4: 97,61,63,53
SQL> SELECT CHR(97),CHR(61),CHR(63),CHR(53) FROM DUAL;
?
CHR(97) CHR(61) CHR(63) CHR(53)
------- ------- ------- -------
a?????? =?????? ??????? 5
?
SQL> SELECT ASCII('a'),ASCII('='),ASCII('?'),ASCII('5') FROM DUAL;
?
ASCII('A') ASCII('=') ASCII('?') ASCII('5')
---------- ---------- ---------- ----------
??????? 97???????? 61???????? 63???????? 53 ? ??? 而對于漢字的存儲,就不太好測試了,而且也沒有搞清楚原理,應該是直接套用字符集的漢字編碼規(guī)則的。 ? ??? 對于數(shù)字的存儲,并不像字符那么簡單,而是應用了Oracle自己的一個算法,eygle有過很詳細的說明: ??? 具體的算法原理可以參見eygle的這篇文章:http://www.eygle.com/archives/2005/12/how_oracle_stor.html ? 三、關于其他 ? ??? 順帶介紹一下怎么查找?Oracle對字符集類型的編碼(dump文件的前2個字節(jié)): ? ??? SELECT NLS_CHARSET_NAME(1) FROM DUAL;? --返回數(shù)值對應的字符集名稱
??? SELECT NLS_CHARSET_ID('US7ASCII') FROM DUAL;? --返回字符集對應的數(shù)值 ? ? ? ? ? 附:dump函數(shù)對number的存儲表示 http://www.eygle.com/archives/2005/12/how_oracle_stor.html -------------------------------------------------------------------------------- How Oracle Store Number internal??
作者:eygle |English Version 【轉載時請以超鏈接形式標明文章出處和作者信息及本聲明】
鏈接:?http://www.eygle.com/archives/2005/12/how_oracle_stor.html?
--------------------------------------------------------------------------------
Oracle在數(shù)據(jù)庫內部通過相應的算法轉換來進行數(shù)據(jù)存儲,本文簡單介紹Oracle的Number型數(shù)值存儲及轉換.這個內容是為了回答留言板上的2119號問題. ? 我們可以通過DUMP函數(shù)來轉換數(shù)字的存儲形式,一個簡單的輸出類似如下格式: ? SQL> select dump(1) from dual; DUMP(1) ------------------ Typ=2 Len=2: 193,2 ? DUMP函數(shù)的輸出格式類似: ? 類型 <[長度]>,符號/指數(shù)位 [數(shù)字1,數(shù)字2,數(shù)字3,......,數(shù)字20] ? 各位的含義如下: ? 1.類型: Number型,Type=2 (類型代碼可以從Oracle的文檔上查到) ? 2.長度:指存儲的字節(jié)數(shù) ? 3.符號/指數(shù)位 ? 在存儲上,Oracle對正數(shù)和負數(shù)分別進行存儲轉換: ? 正數(shù):加1存儲(為了避免Null)
負數(shù):被101減,如果總長度小于21個字節(jié),最后加一個102(是為了排序的需要) ? 指數(shù)位換算: ? 正數(shù):指數(shù)=符號/指數(shù)位 - 193 (最高位為1是代表正數(shù))?
負數(shù):指數(shù)=62 - 第一字節(jié) ? 4.從<數(shù)字1>開始是有效的數(shù)據(jù)位 ? 從<數(shù)字1>開始是最高有效位,所存儲的數(shù)值計算方法為: ? 將下面計算的結果加起來: ? 每個<數(shù)字位>乘以100^(指數(shù)-N) (N是有效位數(shù)的順序位,第一個有效位的N=0) ? 5. 舉例說明 ? SQL> select dump(123456.789) from dual; DUMP(123456.789) ------------------------------- Typ=2 Len=6: 195,13,35,57,79,91 ?
<指數(shù)>:?? 195 - 193 = 2?
<數(shù)字1>??? 13 - 1??? = 12 *100^(2-0) 120000?
<數(shù)字2>??? 35 - 1??? = 34 *100^(2-1) 3400?
<數(shù)字3>??? 57 - 1??? = 56 *100^(2-2) 56?
<數(shù)字4>??? 79 - 1??? = 78 *100^(2-3) .78?
<數(shù)字5>??? 91 - 1??? = 90 *100^(2-4) .009?
??????????????????????????? 123456.789 ? SQL> select dump(-123456.789) from dual; DUMP(-123456.789) ---------------------------------- Typ=2 Len=7: 60,89,67,45,23,11,102 ?
<指數(shù)>???? 62 - 60 = 2(最高位是0,代表為負數(shù))?
<數(shù)字1> 101 - 89 = 12 *100^(2-0) 120000?
<數(shù)字2> 101 - 67 = 34 *100^(2-1) 3400?
<數(shù)字3> 101 - 45 = 56 *100^(2-2) 56?
<數(shù)字4> 101 - 23 = 78 *100^(2-3) .78?
<數(shù)字5> 101 - 11 = 90 *100^(2-4) .009?
????????????????????????????? 123456.789(-) ? 現(xiàn)在再考慮一下為什么在最后加102是為了排序的需要,-123456.789在數(shù)據(jù)庫中實際存儲為 ? 60,89,67,45,23,11 ? 而-123456.78901在數(shù)據(jù)庫中實際存儲為 ? 60,89,67,45,23,11,91 ? 可見,如果不在最后加上102,在排序時會出現(xiàn)-123456.789<-123456.78901的情況。 ? 對于2119號提問,第一個問題是: ? 1.請問為什么193,2各代表什么意思? ? 從上面就可以看到答案了. ? 2.還有NUMBER數(shù)字類型為什么有2個字節(jié)的長度呢? ? 對于這個問題,我想我們應該知道,所有數(shù)據(jù)類型最終在計算機里都以二進制存儲,實際上所謂的數(shù)據(jù)類型都是我們定義的.所以存儲只由算法決定. ? 所以這個問題是不成立的.比如: ? SQL> select dump(110) from dual; DUMP(110) --------------------- Typ=2 Len=3: 194,2,11 ? SQL> select dump(1100) from dual; DUMP(1100) ------------------- Typ=2 Len=2: 194,12 ?
我們會看到,雖然1100>110,但是存儲上1100卻只占2字節(jié),而110卻占了3個字節(jié).
總結
以上是生活随笔為你收集整理的从DUMP函数说开去的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: 查询计划中集的势(Cardinality
 - 下一篇: 关于10g RAC监听设置,tnsnam