Decode360's Blog

          業(yè)精于勤而荒于嬉 QQ:150355677 MSN:decode360@hotmail.com

            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 ::  :: 管理 ::
            397 隨筆 :: 33 文章 :: 29 評(píng)論 :: 0 Trackbacks
          從DUMP函數(shù)說(shuō)開(kāi)去
          ?
          ?
          ??? 因?yàn)樽罱芯孔址詫?duì)于Oracle內(nèi)部的一些存儲(chǔ)模式產(chǎn)生了一些興趣,據(jù)說(shuō)DUMP這個(gè)函數(shù)的功能非常強(qiáng)大,所以專門研究了一下。當(dāng)然研究的都比較初級(jí),只是了解一下。具體哪里可以用到暫時(shí)還不知道 -_-||| ,另外對(duì)字符集的轉(zhuǎn)換等一些函數(shù)也了解一下:
          ?
          ?
          一、函數(shù)用法
          ?
          ??? 函數(shù)的標(biāo)準(zhǔn)格式是:DUMP(expr[,return_fmt[,start_position][,length]])
          ?
          ??? 基本參數(shù)時(shí)4個(gè),最少可以填的參數(shù)時(shí)0個(gè),當(dāng)完全沒(méi)有參數(shù)時(shí),直接返回null。另外3個(gè)參數(shù)也都有各自的默認(rèn)值,一個(gè)一個(gè)來(lái)看:
          ?
          ??? expr:這個(gè)參數(shù)是要進(jìn)行分析的表達(dá)式(數(shù)字或字符串等,可以是各個(gè)類型的值)
          ??? return_fmt:指返回參數(shù)的格式,這個(gè)參數(shù)有5種用法
          ??????? 1) 8:以8進(jìn)制返回結(jié)果的值
          ??????? 2) 10:以10進(jìn)制返回結(jié)果的值(默認(rèn))
          ??????? 3) 16:以16進(jìn)制返回結(jié)果的值
          ??????? 4) 17:以單字符的形式返回結(jié)果的值
          ??????? 5) 1000:以上4種加上1000,表示在返回值中加上當(dāng)前字符集
          ??? start_position:開(kāi)始進(jìn)行返回的字符位置
          ??? length:需要返回的字符長(zhǎng)度
          ?
          ?
          舉幾個(gè)例子:
          ?
          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
          ?
          ?
          二、結(jié)果分析
          ?
          ??? 結(jié)果的格式一般都是類似: typ=96 Len=3 [CharacterSet=UTF8]: 61,62,63
          ?
          ??? 1、type
          ?
          ??? 其中typ表示了當(dāng)前的expr值的類型,例如2表示NUMBER,96表示CHAR等等。
          ??? 具體的所有格式列表在SQL Reference文檔中沒(méi)有找到,但是在網(wǎng)上找到了,網(wǎng)址: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視圖的定義中獲取這個(gè)方法:
          ?
          select text from dba_views where view_name = 'USER_TAB_COLS';
          ?
          ??? 2、Len
          ?
          ??? Len表示該值所占用的字節(jié)數(shù)。
          ?
          ??? 這個(gè)沒(méi)有什么好解釋的,但是有時(shí)我們也可以使用這個(gè)特性發(fā)現(xiàn)一些問(wè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對(duì)于漢字來(lái)說(shuō),需要3個(gè)字節(jié)來(lái)存儲(chǔ)1個(gè)漢字,而我們常用的ZHS16GBK只需要2個(gè)字節(jié)。
          ?
          ?
          ??? 3、Value
          ?
          ??? 最后就是具體的存儲(chǔ)值了,這里的講究就比較多了,不是幾句話就能夠講得清楚的,更何況我自己就不清楚。恩,簡(jiǎn)單得來(lái)說(shuō),這些返回的數(shù)值就是Oracle在自己內(nèi)部對(duì)前面的這個(gè)expr值的存儲(chǔ)形式。對(duì)于非漢字的普通字符串,可以理解為就是它的ASCII碼(字符集中的編碼值)。可以舉個(gè)例子證明一下:
          ?
          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
          ?
          ??? 而對(duì)于漢字的存儲(chǔ),就不太好測(cè)試了,而且也沒(méi)有搞清楚原理,應(yīng)該是直接套用字符集的漢字編碼規(guī)則的。
          ?
          ??? 對(duì)于數(shù)字的存儲(chǔ),并不像字符那么簡(jiǎn)單,而是應(yīng)用了Oracle自己的一個(gè)算法,eygle有過(guò)很詳細(xì)的說(shuō)明:
          ??? 具體的算法原理可以參見(jiàn)eygle的這篇文章:http://www.eygle.com/archives/2005/12/how_oracle_stor.html
          ?
          ?
          三、關(guān)于其他
          ?
          ??? 順帶介紹一下怎么查找 Oracle對(duì)字符集類型的編碼(dump文件的前2個(gè)字節(jié)):
          ?
          ??? SELECT NLS_CHARSET_NAME(1) FROM DUAL;? --返回?cái)?shù)值對(duì)應(yīng)的字符集名稱
          ??? SELECT NLS_CHARSET_ID('US7ASCII') FROM DUAL;? --返回字符集對(duì)應(yīng)的數(shù)值
          ?
          ?
          ?
          ?
          ?
          附:dump函數(shù)對(duì)number的存儲(chǔ)表示
          http://www.eygle.com/archives/2005/12/how_oracle_stor.html
          --------------------------------------------------------------------------------
          How Oracle Store Number internal?
          作者:eygle |English Version 【轉(zhuǎn)載時(shí)請(qǐng)以超鏈接形式標(biāo)明文章出處和作者信息及本聲明】
          鏈接:
          http://www.eygle.com/archives/2005/12/how_oracle_stor.html
          --------------------------------------------------------------------------------
          Oracle在數(shù)據(jù)庫(kù)內(nèi)部通過(guò)相應(yīng)的算法轉(zhuǎn)換來(lái)進(jìn)行數(shù)據(jù)存儲(chǔ),本文簡(jiǎn)單介紹Oracle的Number型數(shù)值存儲(chǔ)及轉(zhuǎn)換.這個(gè)內(nèi)容是為了回答留言板上的2119號(hào)問(wèn)題.
          ?
          我們可以通過(guò)DUMP函數(shù)來(lái)轉(zhuǎn)換數(shù)字的存儲(chǔ)形式,一個(gè)簡(jiǎn)單的輸出類似如下格式:
          ?
          SQL> select dump(1) from dual;
          DUMP(1)
          ------------------
          Typ=2 Len=2: 193,2
          ?
          DUMP函數(shù)的輸出格式類似:
          ?
          類型 <[長(zhǎng)度]>,符號(hào)/指數(shù)位 [數(shù)字1,數(shù)字2,數(shù)字3,......,數(shù)字20]
          ?
          各位的含義如下:
          ?
          1.類型: Number型,Type=2 (類型代碼可以從Oracle的文檔上查到)
          ?
          2.長(zhǎng)度:指存儲(chǔ)的字節(jié)數(shù)
          ?
          3.符號(hào)/指數(shù)位
          ?
          在存儲(chǔ)上,Oracle對(duì)正數(shù)和負(fù)數(shù)分別進(jìn)行存儲(chǔ)轉(zhuǎn)換:
          ?
          正數(shù):加1存儲(chǔ)(為了避免Null)
          負(fù)數(shù):被101減,如果總長(zhǎng)度小于21個(gè)字節(jié),最后加一個(gè)102(是為了排序的需要)
          ?
          指數(shù)位換算:
          ?
          正數(shù):指數(shù)=符號(hào)/指數(shù)位 - 193 (最高位為1是代表正數(shù))
          負(fù)數(shù):指數(shù)=62 - 第一字節(jié)
          ?
          4.從<數(shù)字1>開(kāi)始是有效的數(shù)據(jù)位
          ?
          從<數(shù)字1>開(kāi)始是最高有效位,所存儲(chǔ)的數(shù)值計(jì)算方法為:
          ?
          將下面計(jì)算的結(jié)果加起來(lái):
          ?
          每個(gè)<數(shù)字位>乘以100^(指數(shù)-N) (N是有效位數(shù)的順序位,第一個(gè)有效位的N=0)
          ?
          5. 舉例說(shuō)明
          ?
          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,代表為負(fù)數(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ù)庫(kù)中實(shí)際存儲(chǔ)為
          ?
          60,89,67,45,23,11
          ?
          而-123456.78901在數(shù)據(jù)庫(kù)中實(shí)際存儲(chǔ)為
          ?
          60,89,67,45,23,11,91
          ?
          可見(jiàn),如果不在最后加上102,在排序時(shí)會(huì)出現(xiàn)-123456.789<-123456.78901的情況。
          ?
          對(duì)于2119號(hào)提問(wèn),第一個(gè)問(wèn)題是:
          ?
          1.請(qǐng)問(wèn)為什么193,2各代表什么意思?
          ?
          從上面就可以看到答案了.
          ?
          2.還有NUMBER數(shù)字類型為什么有2個(gè)字節(jié)的長(zhǎng)度呢?
          ?
          對(duì)于這個(gè)問(wèn)題,我想我們應(yīng)該知道,所有數(shù)據(jù)類型最終在計(jì)算機(jī)里都以二進(jìn)制存儲(chǔ),實(shí)際上所謂的數(shù)據(jù)類型都是我們定義的.所以存儲(chǔ)只由算法決定.
          ?
          所以這個(gè)問(wèn)題是不成立的.比如:
          ?
          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
          ?

          我們會(huì)看到,雖然1100>110,但是存儲(chǔ)上1100卻只占2字節(jié),而110卻占了3個(gè)字節(jié).
          ?
          ?
          ?
          ?
          posted on 2009-06-17 23:08 decode360 閱讀(960) 評(píng)論(0)  編輯  收藏 所屬分類: 07.Oracle
          主站蜘蛛池模板: 维西| 新昌县| 沙湾县| 合作市| 舒城县| 宁津县| 靖江市| 奎屯市| 桃源县| 双桥区| 勐海县| 古浪县| 海晏县| 屯门区| 出国| 玉树县| 徐水县| 木里| 永平县| 安乡县| 吉安市| 高碑店市| 娱乐| 湘潭县| 班玛县| 婺源县| 太保市| 全椒县| 望谟县| 罗山县| 塘沽区| 西乌珠穆沁旗| 全南县| 泸州市| 祁连县| 手游| 金阳县| 贵阳市| 贡觉县| 板桥市| 曲麻莱县|