oracle dump詳解

xypincle發表於2017-04-19

  1. dump函式(number型別) 筆記
  2. dump 函式能檢視錶中列在datafile儲存內容。
  3. Oracle的NUMBER型別最多由三個部分構成,這三個部分分別是最高位表示位、資料部分、符號位。其中負數包含符號位,正數不會包括符號位(10進位制即102)。另外,數值0比較特殊,它只包含一個數值最高位表示位80(16進位制),沒有資料部分。

  4. 用法:DUMP(expr[,number_format[,start_position][,length]])

  5. 用法說明: dump(col_name,8|10|16|17) ,其中8|10|16|17 為number_format,分別為8進位制,10進位制(預設值),16進位制,單字元。
  6.  
  7. The syntax is:
  8. DUMP(expr[,return_fmt[,start_position[,length]]])
  9. The argument return_fmt specifies the format of the return value and can have any of the following values:
  10. 8 returns result in octal notation.
  11. 10 returns result in decimal notation.
  12. 16 returns result in hexadecimal notation.
  13. 17 returns result as single characters.
  14. By default, the return value contains no character set information. To retrieve the character set name of expr, specify any of the preceding format values, plus 1000. For example, a return_fmt of 1008 returns the result in octal, plus provides the character set name of expr.
  15. The arguments start_position and length combine to determine which portion of the internal representation to return. The default is to return the entire internal representation in decimal notation.
  16. If expr is null, then this function returns a null.


  17. DUMP函式的輸出格式類似:

  18. 型別 <[長度]>,符號/指數位 [數字1,數字2,數字3,......,數字20]

  19. 各位的含義如下:

  20. 1.型別: Number型,Type=2 (型別程式碼可以從Oracle的文件上查到,見結尾)

  21. 2.長度:指儲存的位元組數

  22. 3.符號/指數位

  23. 在儲存上,Oracle對正數和負數分別進行儲存轉換:

  24. 正數:加1儲存(為了避免Null),在實際演算法中就是要減1,必須>128
  25. 負數:被101減,如果總長度小於21個位元組,最後加一個102(是為了排序的需要),必須<128

  26. 指數位換算:

  27. 正數:指數=符號/指數位 - 193 (第一位元組)
  28. 負數:指數=62 - 第一位元組

  29. 4.<數字1>開始是有效的資料位

  30. <數字1>開始是最高有效位,所儲存的數值計算方法為:

  31. 將下面計算的結果加起來:

  32. 每個<數字位>乘以100^(指數-N) (N是有效位數的順序位,第一個有效位的N=0)

  33. ===numbe型別例子====
  34. 例1:(區別正數和負數)
  35. SQL> select dump(0) from dual;                                                  

  36. DUMP(0)
  37. --------------------------------
  38. Typ=2 Len=1: 128
  39. ##
  40. 例1中可以看見,為什麼>128斷定為正數,而<128 斷定為負數(10進位制)

  41. ## 16進位制分析正數和負數
  42. SQL> select dump(0,16) from dual;                                               

  43. DUMP(0,16)
  44. ------------------------------
  45. Typ=2 Len=1: 80--------------------(只有高位)

  46. 1 row selected.

  47. DUMP(0) 的結果是0x80,在前面已經提到,0只有高位表示位,沒有資料位。由於0的特殊,既不屬於正數,也不屬於負數,因此使用高位表示位用80表示就足夠了, 不會和其它資料衝突,Oracle出於節省空間的考慮將後面資料部分省掉了。但是為什麼Oracle選擇0x80表示0呢?我們知道正數和負數互為相反 數,每個正數都有一個對應的負數。因此如果我們要使用編碼表示數值,則表示正數和負數的編碼應該各佔一半,這樣才能保證使Oracle表示資料範圍是合理的。而0x80的二進位制編碼是1000 0000,正好是一個位元組編碼最大值的一半,因此,Oracle選擇0x80來表示0,是十分有道理的。


  48. @@@@

  49. 例2:(正數)
  50. SQL> select dump(1,10) from dual;                                               

  51. DUMP(1,10)
  52. ------------------------------------
  53. Typ=2 Len=2: 193,2
  54.                        |   |
  55.                     高位,資料部分


  56. 1 row selected.  

  57. ##
  58. SQL> select dump(1) from dual;                                                                                                                                                   

  59. DUMP(1)
  60. ------------------------------------
  61. Typ=2 Len=2: 193,2

  62. 1 row selected.
  63. ##
  64. 例2中可以看見dump(1,10)和dump(1) 輸出結果一樣:Typ=2 Len=2: 193,2
  65. 型別是number,2位元組,因為正數所以>128,因為正數所以儲存時候都+1

  66. <指數>:   193 - 193 = 0
  67. <數字1>      2 - 1    = 1 *100^(0-0)
  68.                              = 1

  69. @@@@@@@@
  70. 例3:(正數指數變化)
  71. SQL> select dump(99) from dual;                                                

  72. DUMP(99)
  73. ----------------------------------------
  74. Typ=2 Len=2: 193,100

  75. 1 row selected.


  76. ##

  77. SQL> select dump(100) from dual;                                                

  78. DUMP(100)
  79. ------------------------------------
  80. Typ=2 Len=2: 194,2

  81. 1 row selected.

  82. 例3對比就知道,第一位元組指數從193變化到194

  83. @@@@@@@@@@@

  84. 例4:(負數)
  85. SQL> select dump(-98) from dual;                                                

  86. DUMP(-98)
  87. ------------------------------------------
  88. Typ=2 Len=3: 62,3,102
  89.                      |   |    |
  90.                 高位,資料部分,符號位
  91.                         




  92. 1 row selected.
  93. <指數>     62 - 62 = 0
  94. <數字1> 101 -   3 = 98 *100^(0-0)
  95.                           = 98

  96. ##
  97. SQL> select dump(-99) from dual;                                                

  98. DUMP(-99)
  99. ------------------------------------------
  100. Typ=2 Len=3: 62,2,102

  101. 1 row selected.

  102. <指數>     62 - 62 = 0
  103. <數字1> 101 -   2 = 99 *100^(0-0)
  104.                           = 99




  105. ###
  106. SQL> select dump(-100) from dual;                                               

  107. DUMP(-100)
  108. ----------------------------------------------
  109. Typ=2 Len=3: 61,100,102

  110. 1 row selected

  111. 最後加102是目的:
  112. 實際儲存中-98 為62,3   
  113.                -99 為62,2     
  114.                -100為61,100

  115. 得知-98>-99>-100

  116. 但是如果
  117. SQL> select dump(-98.001) from dual;                                            

  118. DUMP(-98.001)
  119. --------------------------------------------------------
  120. Typ=2 Len=5: 62,3,101,91,102

  121. 1 row selected.

  122. 透過這個得知 沒有102:-98.001為 62,3,101,91  >-98 為62,3

  123.                       有102:-98.001為 62,3,101,91,102
  124.                                  -98     為   62,3,102


  125. 所以加102目的是排序的需要!


  126. 例5:(數字位演算法)
  127. SQL> select dump(7654321) from dual;                                            

  128. DUMP(7654321)
  129. ------------------------------------------------------
  130. Typ=2 Len=5: 196,8,66,44,22

  131. 1 row selected.

  132. <指數>:   196 - 193 = 3
  133. <數字1>    8  - 1    = 7 *100^(3-0) 7000000
  134. <數字2>    66 - 1    = 65 *100^(3-1) 650000
  135. <數字3>    44 - 1    = 43 *100^(3-2) 4300
  136. <數字4>    22 - 1    = 21 *100^(3-3) 21

  137. ##
  138. SQL> select dump(87654321) from dual;                                          

  139. DUMP(87654321)
  140. --------------------------------------------------------
  141. Typ=2 Len=5: 196,88,66,44,22

  142. 1 row selected.



  143. <指數>:   196 - 193 = 3
  144. <數字1>    88  - 1    = 87 *100^(3-0) 87000000
  145. <數字2>    66 - 1    = 65 *100^(3-1) 650000
  146. <數字3>    44 - 1    = 43 *100^(3-2) 4300
  147. <數字4>    22 - 1    = 21 *100^(3-3) 21




  148. ×××××××××××××××
  149. 型別程式碼(參考)
  150. 程式碼 資料型別 oracle 版本
  151. 1 varchar2   7
  152. 2 number    7
  153. 8 long    7
  154. 12 date    7
  155. 23 raw    7
  156. 24 long raw   7
  157. 69 rowid    7
  158. 96 char    7
  159. 112 clob    8
  160. 113 blob    8
  161. 114 bfile    8
  162. 180 timestamp   9i
  163. 181 timestamp with timezone  9i
  164. 182 interval year to month  9i
  165. 183 interval day to second  9i
  166. 208 urowid    8i
  167. 231 timestamp with local timezone 9i
  168.  
  169.  
  170. ****************************************************************
  171. ****************************************************************
  172. Oracle在資料庫內部透過相應的演算法轉換來進行資料儲存,本文簡單介紹Oracle的Number型數值儲存及轉換.
  173. 我們可以透過DUMP函式來轉換數字的儲存形式,一個簡單的輸出類似如下格式:
  174. SQL> select dump(1) from dual;
  175. DUMP(1)
  176. ------------------
  177. Typ=2 Len=2: 193,2
  178. DUMP函式的輸出格式類似:
  179. 型別 <[長度]>,符號/指數位 [數字1,數字2,數字3,......,數字20]
  180. 各位的含義如下:
  181. 1.型別: Number型,Type=2 (型別程式碼可以從Oracle的文件上查到)
  182. 2.長度:指儲存的位元組數
  183. 3.符號/指數位
  184. 在儲存上,Oracle對正數和負數分別進行儲存轉換:
  185. 正數:加1儲存(為了避免Null)
  186. 負數:被101減,如果總長度小於21個位元組,最後加一個102(是為了排序的需要)
  187. 指數位換算:
  188. 正數:指數=符號/指數位 - 193 (最高位為1是代表正數)
  189. 負數:指數=62 - 第一位元組
  190. 4.<數字1>開始是有效的資料位
  191. <數字1>開始是最高有效位,所儲存的數值計算方法為:
  192. 將下面計算的結果加起來:
  193. 每個<數字位>乘以100^(指數-N) (N是有效位數的順序位,第一個有效位的N=0)
  194. 5. 舉例說明

  195. SQL> select dump(123456.789) from dual;
  196. DUMP(123456.789)
  197. -------------------------------
  198. Typ=2 Len=6: 195,13,35,57,79,91

  199. <指數>:   195 - 193 = 2
  200. <數字1>    13 - 1    = 12 *100^(2-0) 120000
  201. <數字2>    35 - 1    = 34 *100^(2-1) 3400
  202. <數字3>    57 - 1    = 56 *100^(2-2) 56
  203. <數字4>    79 - 1    = 78 *100^(2-3) .78
  204. <數字5>    91 - 1    = 90 *100^(2-4) .009
  205.                             123456.789

  206. SQL> select dump(-123456.789) from dual;
  207. DUMP(-123456.789)
  208. ----------------------------------
  209. Typ=2 Len=7: 60,89,67,45,23,11,102

  210. <指數>     62 - 60 = 2(最高位是0,代表為負數)
  211. <數字1> 101 - 89 = 12 *100^(2-0) 120000
  212. <數字2> 101 - 67 = 34 *100^(2-1) 3400
  213. <數字3> 101 - 45 = 56 *100^(2-2) 56
  214. <數字4> 101 - 23 = 78 *100^(2-3) .78
  215. <數字5> 101 - 11 = 90 *100^(2-4) .009
  216.                                123456.789(-)
  217. 現在再考慮一下為什麼在最後加102是為了排序的需要,-123456.789在資料庫中實際儲存為
  218. 60,89,67,45,23,11
  219. -123456.78901在資料庫中實際儲存為
  220. 60,89,67,45,23,11,91
  221. 可見,如果不在最後加上102,在排序時會出現-123456.789<-123456.78901的情況。
  222. NUMBER數字型別為什麼有2個位元組的長度呢?
  223. 對於這個問題,我想我們應該知道,所有資料型別最終在計算機裡都以二進位制儲存,實際上所謂的資料型別都是我們定義的.所以儲存只由演算法決定.
  224. 所以這個問題是不成立的.比如:

  225. SQL> select dump(110) from dual;
  226. DUMP(110)
  227. ---------------------
  228. Typ=2 Len=3: 194,2,11
  229. SQL> select dump(1100) from dual;
  230. DUMP(1100)
  231. -------------------
  232. Typ=2 Len=2: 194,12

  233. 我們會看到,雖然1100>110,但是儲存上1100卻只佔2位元組,而110卻佔了3個位元組.

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28878983/viewspace-2137517/,如需轉載,請註明出處,否則將追究法律責任。

相關文章