程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> Oracle數據庫 >> Oracle教程 >> ORACLE NUMBER類型Scale為0引發的問題,oraclescale

ORACLE NUMBER類型Scale為0引發的問題,oraclescale

編輯:Oracle教程

ORACLE NUMBER類型Scale為0引發的問題,oraclescale


今天遇到了一個很有意思的NUMBER類型Scale引發的問題,我用一個簡單的測試用例來展示一下這個案例。假如有個TEST的表,有個字段類型為NUMBER,我插入下面兩條數據

CREATE TABLE TEST
(
     Category VARCHAR(12),
     QTY  NUMBER
)
 
INSERT INTO TEST
SELECT 'M', 12 FROM DUAL UNION ALL
SELECT 'C', 0.99999999999999999 FROM DUAL;
 
COMMIT;

此時直接查詢表TEST,發現QTY字段值為1,

使用下面SQL語句統計時,SUM_QTY的值也是1

但是如果在游標裡面獲取該值的時候,你會發現字段QTY的值為原來的值.99999999999999999

DECLARE  CURSOR c_test
IS
   SELECT Category, SUM(QTY) AS SUM_QTY FROM TEST
   GROUP BY Category;
   
   c_row c_test%rowtype;
   
 begin 
       for c_row in c_test loop
           dbms_output.put_line('the result is ' || c_row.SUM_QTY);
       end loop;
 end;

the result is .99999999999999999

the result is 12

為什麼會有這個奇怪的現象呢? 其實我們遇到這個案例時是按這個順序反著的,最後發現是插入的值是0.999999999. 當然這個過程是非常糾結的。遠非我們例子裡面那樣輕松簡單。要解釋這個問題,要從NUMBER類型說起,NUMBER (p, s) 聲明一個定點數 p(precision)為精度,s(scale)表示小數點右邊的數字個數,精度最大值為38,scale的取值范圍為-84到127。Number(p) 表示聲明一個整數相當於Number(p, 0), 如果不指定p和s,NUMBER類型,它的默認精度值為38, 默認的scale值為0. 所以出現在SELECT語句中,一個值為.99999999999999999 的顯示為1,但是在游標中,它獲取的是這個字段的真實值,沒有經過轉化。所以出現了這個稀奇古怪的問題。雖然事後理順過後覺得非常簡單,但是當時不了解情況下,覺得非常不可思議,非常納悶!

 

另外附上定點數的精度(p)和刻度(s)遵循以下規則:
 當一個數的整數部分的長度 > p-s 時,Oracle就會報錯
 當一個數的小數部分的長度 > s 時,Oracle就會捨入。
 當s(scale)為負數時,Oracle就對小數點左邊的s個數字進行捨入。
 當s > p 時, p表示小數點後第s位向左最多可以有多少位數字,如果大於p則Oracle報錯,小數點後s位向右的數字被捨入

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved