SQL和儲存過程的結果不一致——小議Oracle的number精度問題
今天看到一個有趣的問題,SQL得到的查詢結果和儲存過程不一致。
原始問題參加:http://www.itpub.net/showthread.php?s=&threadid=763283
首先模擬一下這個問題:
SQL> CREATE OR REPLACE PROCEDURE P_TEST (P_IN NUMBER, P_OUT OUT NUMBER) IS
2 BEGIN
3 SELECT LOG(2, P_IN) INTO P_OUT FROM DUAL;
4 DBMS_OUTPUT.PUT_LINE(P_OUT);
5 END P_TEST;
6 /
過程已建立。
SQL> SET SERVEROUT ON
SQL> VAR NUM NUMBER
SQL> EXEC P_TEST(4096, :NUM)
11.99999999999999999999999999999999999994
PL/SQL 過程已成功完成。
SQL> SELECT LOG(2, 4096) FROM DUAL;
LOG(2,4096)
------------
12
SQL> PRINT NUM
NUM
------------
12
問題似乎很奇怪,為什麼儲存過程和SQL直接查詢得到的結果不一致?其實問題就是由於資料精度造成的。
看看下面幾個例子就會明白了:
SQL> SELECT DUMP(LOG(2, 4096)) FROM DUAL;
DUMP(LOG(2,4096))
-------------------------------------------------------------------------------
Typ=2 Len=21: 193,12,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,95
SQL> SELECT TO_CHAR(LOG(2, 4096)) FROM DUAL;
TO_CHAR(LOG(2,4096))
----------------------------------------
11.9999999999999999999999999999999999999
從目前的結果可以看到,Oracle實際上得到並非是12,而是一個近似值。實際上是SQLPLUS工具幫我們做了一個四捨五入。
透過DUMP或轉化為字元型別,或者直接在伺服器端列印,都會顯示正確的結果。
為了避免SQLPLUS的干擾,可以簡單的將NUMW設定為40,就可以看到真實的結果:
SQL> SHOW NUMW
numwidth 12
SQL> SET NUMW 40
SQL> SELECT LOG(2, 4096) FROM DUAL;
LOG(2,4096)
----------------------------------------
11.9999999999999999999999999999999999999
LOG函式對精度要求很高,懷疑Oracle中的LOG函式在處理過程中出現了精度不足的問題,因此導致最終的結果不是12。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4227/viewspace-69256/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 在儲存過程A中呼叫儲存過程B的結果儲存過程
- Oracle 儲存過程返回結果集|轉|Oracle儲存過程
- Oracle 儲存過程返回結果集 (轉)Oracle儲存過程
- Java呼叫Oracle儲存過程的問題JavaOracle儲存過程
- mysql返回一個結果集的儲存過程小例子MySql儲存過程
- mssql 儲存過程呼叫另一個儲存過程中的結果的方法分享SQL儲存過程
- Hibernate呼叫oracle儲存過程的問題Oracle儲存過程
- MySQL儲存過程中的sql_mode問題MySql儲存過程
- JAVA + Oracle儲存過程返回查詢結果集JavaOracle儲存過程
- ORACLE中儲存過程的許可權問題Oracle儲存過程
- 儲存過程問題。。儲存過程
- 【Oracle】儲存過程中將動態SQL的多行結果進行迴圈遍歷Oracle儲存過程SQL
- 儲存過程結果進行查詢 select 存過過程儲存過程
- 一個儲存過程的問題!儲存過程
- oracle的儲存過程Oracle儲存過程
- SQL總結(五)儲存過程SQL儲存過程
- Oracle Pl/SQL 之 儲存過程OracleSQL儲存過程
- 簡單的mysql儲存過程,輸出結果集MySql儲存過程
- 從sybase的儲存過程轉向oracle的儲存過程儲存過程Oracle
- oracle儲存過程許可權繼承小結Oracle儲存過程繼承
- oracle儲存過程!解決網友問題Oracle儲存過程
- mysql多次呼叫儲存過程的問題MySql儲存過程
- SAS 數值儲存方式和精度問題
- SQL SERVER儲存過程AS和GO的含義SQLServer儲存過程Go
- Oracle SQL Developer Debug儲存過程OracleSQLDeveloper儲存過程
- oracle動態sql儲存過程示例OracleSQL儲存過程
- oracle的儲存過程格式Oracle儲存過程
- oracle儲存過程(procedure)中執行動態SQL小記Oracle儲存過程SQL
- 兩種SQL分頁方法儲存過程和遊標儲存過程SQL儲存過程
- MySQL儲存過程的許可權問題MySql儲存過程
- SQL Server系統儲存過程和引數總結SQLServer儲存過程
- MySQL的物理儲存結構和session過程MySqlSession
- 編寫和優化SQL Server的儲存過程優化SQLServer儲存過程
- SQL中儲存過程和函式的區別SQL儲存過程函式
- Oracle儲存過程Oracle儲存過程
- SQL儲存過程示例SQL儲存過程
- SQL Server 儲存過程SQLServer儲存過程
- 【SQL Server】--儲存過程SQLServer儲存過程