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/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- oracle的儲存過程Oracle儲存過程
- mysql返回一個結果集的儲存過程小例子MySql儲存過程
- 【Oracle】儲存過程中將動態SQL的多行結果進行迴圈遍歷Oracle儲存過程SQL
- mssql 儲存過程呼叫另一個儲存過程中的結果的方法分享SQL儲存過程
- oracle儲存過程許可權繼承小結Oracle儲存過程繼承
- SQL SERVER儲存過程AS和GO的含義SQLServer儲存過程Go
- Oracle儲存過程Oracle儲存過程
- mysql多次呼叫儲存過程的問題MySql儲存過程
- Sqlsugar呼叫Oracle的儲存過程SqlSugarOracle儲存過程
- SAS 數值儲存方式和精度問題
- oracle儲存過程和觸發器Oracle儲存過程觸發器
- 簡單的mysql儲存過程,輸出結果集MySql儲存過程
- MySQL儲存過程的許可權問題MySql儲存過程
- Oracle儲存過程-1Oracle儲存過程
- SQL 儲存過程裡呼叫另一個儲存過程SQL儲存過程
- Oracle儲存過程乾貨(一):儲存過程基礎Oracle儲存過程
- MySQL的物理儲存結構和session過程MySqlSession
- SQL Server儲存過程模擬HTTP請求POST和GET協議SQLServer儲存過程HTTP協議
- SQL 分頁儲存過程SQL儲存過程
- SQL Server儲存過程的優缺點SQLServer儲存過程
- mysql和orcale的儲存過程和儲存函式MySql儲存過程儲存函式
- 儲存過程訪問其他使用者的表的問題儲存過程
- 原創:oracle 儲存過程Oracle儲存過程
- SQL Server 資料訪問策略:儲存過程QCSQLServer儲存過程
- 達夢儲存過程效能問題定位儲存過程
- Spark解決SQL和RDDjoin結果不一致問題(工作實錄)SparkSQL
- Sql儲存過程分頁--臨時表儲存SQL儲存過程
- SQL server儲存過程函式SQLServer儲存過程函式
- Springboot呼叫Oracle儲存過程的幾種方式Spring BootOracle儲存過程
- oracle儲存過程書寫格式Oracle儲存過程
- LightDB/PostgreSQL 相容Oracle儲存過程SQLOracle儲存過程
- MySQL儲存過程的建立和使用MySql儲存過程
- 使用JavaScript和Python實現Oracle資料庫的儲存過程?JavaScriptPythonOracle資料庫儲存過程
- Oracle服務啟動-索引-子查詢-分頁儲存過程問題Oracle索引儲存過程
- SQL Server 2005的複製儲存過程選項BYSQLServer儲存過程
- MySQL儲存過程裡動態SQL的使用UXMySql儲存過程UX
- Oracle儲存過程中跳出迴圈的寫法Oracle儲存過程
- Oracle儲存過程編譯卡死的解決方法Oracle儲存過程編譯
- Oracle 儲存過程分頁 + Sqlsugar呼叫Oracle儲存過程SqlSugar