db2 報錯 sqlcode=-420 自動類型轉換的問題


今天在測試遇到一個問題,前台點擊頁面查詢數據時報錯:

[Error Code: -420, SQL State: 22018]  DB2 SQL Error: SQLCODE=-420, SQLSTATE=22018, SQLERRMC=DECFLOAT, DRIVER=4.18.60

根據sqlcode查詢錯誤原因為:-420 22018 字符串自變量值不符合函數的要求

查詢語句大概如下:

select * from tabletest where createDate < '2018-11-17' and createStatus != 0

這個問題只在測試環境出現,於是判斷是數據庫的數據問題。同時在debug時還發現當使用下面這條語句時可以查詢出數據,這進一步肯定了我的判斷。

select * from tabletest where createDate < '2018-11-15' and createStatus != 0

但取出createDate字段時並未發現異常數據。於是轉而查詢表結構,發現createStatus字段是varchar類型,而這條sql語句中 createStatus != 0 ,卻是將數值0與之作比較,取出字段createStatus后發現有值為空的情況,空值在自動類型轉換時出錯。將sql語句修改為

select * from tabletest where createDate < '2018-11-17' and createStatus != '0'

順利查出數據。

 

原因分析

問題解決后,我在db2和mysql數據庫分別新建了一張表來復現這一問題並做深入分析。

1 create table tableTest(id varchar(20) primary key not null, createDate Date, createStatus varchar(10));
2 
3 INSERT INTO tabletest (id, createDate, createStatus) VALUES ('1', '2018-11-12', '10');
4 INSERT INTO tabletest (id, createDate, createStatus) VALUES ('2', '2018-11-12', '00');
5 INSERT INTO tabletest (id, createDate, createStatus) VALUES ('3', '2018-11-13', '0');
6 INSERT INTO tabletest (id, createDate, createStatus) VALUES ('4', '2018-11-15', '');
7 INSERT INTO tabletest (id, createDate, createStatus) VALUES ('7', '2018-11-18', '48');

 首先在兩個數據庫分別執行報錯的查詢語句,結果在mysql中得到了結果,而db2報錯sqlcode=-420。

這就是一個很有意思的問題,可以猜測是兩個數據對於空值的類型轉換有不一樣的定義。改用下面的查詢語句:

select * from tabletest where createDate < '2018-11-17' and createStatus = 0

 db2依然報錯-420,而在mysql中查出了三條數據。可以看到在mysql中數據庫直接將空值轉換成0來做匹配。但這是一個很影響效率的做法,因為SQL命令中是用字符串跟數字0匹配,而SQLServer默認把字段中的先全部轉換為數字,再來做匹配。一旦數據轉換成數值時非常大的時候,還會超出范圍。

綜上,

  • 數據庫在做查詢時不是轉換SQL命令中的數值為對應字段的類型,而是將數據庫中的數據轉換成SQL命令中的類型,不但影響效率,而且容易出錯。
  • mysql會自動將空值轉換成0,而db2不做任何操作。
  • 查詢數據時最好使用字段相同的數據類型,否則可能查出的數據不正確。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM