<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Decode360's Blog

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

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 ::  :: 管理 ::
      397 隨筆 :: 33 文章 :: 29 評論 :: 0 Trackbacks
    從DUMP函數說開去
    ?
    ?
    ??? 因為最近研究字符集,所以對于Oracle內部的一些存儲模式產生了一些興趣,據說DUMP這個函數的功能非常強大,所以專門研究了一下。當然研究的都比較初級,只是了解一下。具體哪里可以用到暫時還不知道 -_-||| ,另外對字符集的轉換等一些函數也了解一下:
    ?
    ?
    一、函數用法
    ?
    ??? 函數的標準格式是:DUMP(expr[,return_fmt[,start_position][,length]])
    ?
    ??? 基本參數時4個,最少可以填的參數時0個,當完全沒有參數時,直接返回null。另外3個參數也都有各自的默認值,一個一個來看:
    ?
    ??? expr:這個參數是要進行分析的表達式(數字或字符串等,可以是各個類型的值)
    ??? return_fmt:指返回參數的格式,這個參數有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表示該值所占用的字節數。
    ?
    ??? 這個沒有什么好解釋的,但是有時我們也可以使用這個特性發現一些問題,例如:
    ?
    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個字節來存儲1個漢字,而我們常用的ZHS16GBK只需要2個字節。
    ?
    ?
    ??? 3、Value
    ?
    ??? 最后就是具體的存儲值了,這里的講究就比較多了,不是幾句話就能夠講得清楚的,更何況我自己就不清楚。恩,簡單得來說,這些返回的數值就是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
    ?
    ??? 而對于漢字的存儲,就不太好測試了,而且也沒有搞清楚原理,應該是直接套用字符集的漢字編碼規則的。
    ?
    ??? 對于數字的存儲,并不像字符那么簡單,而是應用了Oracle自己的一個算法,eygle有過很詳細的說明:
    ??? 具體的算法原理可以參見eygle的這篇文章:http://www.eygle.com/archives/2005/12/how_oracle_stor.html
    ?
    ?
    三、關于其他
    ?
    ??? 順帶介紹一下怎么查找 Oracle對字符集類型的編碼(dump文件的前2個字節):
    ?
    ??? SELECT NLS_CHARSET_NAME(1) FROM DUAL;? --返回數值對應的字符集名稱
    ??? SELECT NLS_CHARSET_ID('US7ASCII') FROM DUAL;? --返回字符集對應的數值
    ?
    ?
    ?
    ?
    ?
    附:dump函數對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在數據庫內部通過相應的算法轉換來進行數據存儲,本文簡單介紹Oracle的Number型數值存儲及轉換.這個內容是為了回答留言板上的2119號問題.
    ?
    我們可以通過DUMP函數來轉換數字的存儲形式,一個簡單的輸出類似如下格式:
    ?
    SQL> select dump(1) from dual;
    DUMP(1)
    ------------------
    Typ=2 Len=2: 193,2
    ?
    DUMP函數的輸出格式類似:
    ?
    類型 <[長度]>,符號/指數位 [數字1,數字2,數字3,......,數字20]
    ?
    各位的含義如下:
    ?
    1.類型: Number型,Type=2 (類型代碼可以從Oracle的文檔上查到)
    ?
    2.長度:指存儲的字節數
    ?
    3.符號/指數位
    ?
    在存儲上,Oracle對正數和負數分別進行存儲轉換:
    ?
    正數:加1存儲(為了避免Null)
    負數:被101減,如果總長度小于21個字節,最后加一個102(是為了排序的需要)
    ?
    指數位換算:
    ?
    正數:指數=符號/指數位 - 193 (最高位為1是代表正數)
    負數:指數=62 - 第一字節
    ?
    4.從<數字1>開始是有效的數據位
    ?
    從<數字1>開始是最高有效位,所存儲的數值計算方法為:
    ?
    將下面計算的結果加起來:
    ?
    每個<數字位>乘以100^(指數-N) (N是有效位數的順序位,第一個有效位的N=0)
    ?
    5. 舉例說明
    ?
    SQL> select dump(123456.789) from dual;
    DUMP(123456.789)
    -------------------------------
    Typ=2 Len=6: 195,13,35,57,79,91
    ?

    <指數>:?? 195 - 193 = 2
    <數字1>??? 13 - 1??? = 12 *100^(2-0) 120000
    <數字2>??? 35 - 1??? = 34 *100^(2-1) 3400
    <數字3>??? 57 - 1??? = 56 *100^(2-2) 56
    <數字4>??? 79 - 1??? = 78 *100^(2-3) .78
    <數字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
    ?

    <指數>???? 62 - 60 = 2(最高位是0,代表為負數)
    <數字1> 101 - 89 = 12 *100^(2-0) 120000
    <數字2> 101 - 67 = 34 *100^(2-1) 3400
    <數字3> 101 - 45 = 56 *100^(2-2) 56
    <數字4> 101 - 23 = 78 *100^(2-3) .78
    <數字5> 101 - 11 = 90 *100^(2-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的情況。
    ?
    對于2119號提問,第一個問題是:
    ?
    1.請問為什么193,2各代表什么意思?
    ?
    從上面就可以看到答案了.
    ?
    2.還有NUMBER數字類型為什么有2個字節的長度呢?
    ?
    對于這個問題,我想我們應該知道,所有數據類型最終在計算機里都以二進制存儲,實際上所謂的數據類型都是我們定義的.所以存儲只由算法決定.
    ?
    所以這個問題是不成立的.比如:
    ?
    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字節,而110卻占了3個字節.
    ?
    ?
    ?
    ?
    posted on 2009-06-17 23:08 decode360 閱讀(952) 評論(0)  編輯  收藏 所屬分類: 07.Oracle
    主站蜘蛛池模板: 久久精品中文字幕免费| 亚洲日韩VA无码中文字幕 | 亚洲一区二区三区国产精华液| 美女无遮挡拍拍拍免费视频| 亚洲人成在线观看| 最近最新中文字幕完整版免费高清| 亚洲精品国产成人| 亚洲成aⅴ人片久青草影院| 免费在线观看一级片| 亚洲毛片基地4455ww| 亚洲最大AV网站在线观看| 日韩视频在线精品视频免费观看 | 成人免费a级毛片| 最新亚洲成av人免费看| 亚洲高清有码中文字| 久久亚洲AV永久无码精品| 国产免费不卡v片在线观看| 国产乱妇高清无乱码免费| 亚洲日韩av无码中文| 亚洲v高清理论电影| 四只虎免费永久观看| 亚欧免费视频一区二区三区| 一级女人18片毛片免费视频| 亚洲kkk4444在线观看| 国产日韩亚洲大尺度高清| 四虎永久在线精品免费影视| h视频在线观看免费完整版| 国产精品成人免费观看| 久久亚洲国产欧洲精品一| 亚洲欧洲日产v特级毛片| 亚洲人成网站看在线播放| 99热在线免费播放| 97性无码区免费| 久久亚洲中文字幕精品一区四 | 国产免费牲交视频| 日韩免费在线观看| 亚洲av鲁丝一区二区三区| 国产天堂亚洲国产碰碰| 亚洲精品V欧洲精品V日韩精品| 特级毛片aaaa免费观看| 亚洲欧美国产欧美色欲|