我想選擇被定義爲VARCHAR
列轉換字符串時爲整數,作爲INTEGER
像這樣具有錯誤:避免在DB2
SELECT ID, CAST(Col1 as INT) as MyOutput FROM MyTABLE
問題是,當該列具有無效格式(即不能轉換爲整數)我想將它們設置爲NULL
。有沒有辦法在DB2中執行此操作?要做到這一點
我想選擇被定義爲VARCHAR
列轉換字符串時爲整數,作爲INTEGER
像這樣具有錯誤:避免在DB2
SELECT ID, CAST(Col1 as INT) as MyOutput FROM MyTABLE
問題是,當該列具有無效格式(即不能轉換爲整數)我想將它們設置爲NULL
。有沒有辦法在DB2中執行此操作?要做到這一點
一種方法是寫自己的轉換函數來處理格式例外,如
create or replace function to_int_safe (str varchar(20))
returns int
deterministic
no external action contains sql
begin
declare continue handler for sqlstate '22018' -- on conversion error
return null;
return cast(str as int);
end
然後在查詢中使用它:
SELECT ID, to_int_safe(Col1) as MyOutput FROM MyTABLE
接下來的case語句確定是否字符串包含一個可以轉換爲整數的數字。它似乎工作到目前爲止。然而,這是複雜和太長。我的意思是它只檢查一個數字是否可以轉換爲整數,更不用說它將如何查找十進制數字。
select case when (-- no leading sign
(instr(value,'-') = 0
and instr(value,'+') = 0)
-- or one leading sign
or (left(ltrim(value),1) in ('-','+')
and instr(ltrim(value),'-',2) = 0
and instr(ltrim(value),'+',2) = 0))
-- no spaces between digits
and instr(trim(translate(value,'','+-')),' ') = 0
-- only numbers and sign
and length(trim(translate(value,'','+-'))) = 0
-- no empty strings
and length(trim(value)) <> 0
then cast(value as int)
else cast(null as int)
end
from table (
select '1 ' value from sysibm.sysdummy1
union all
select '1.' value from sysibm.sysdummy1
union all
select 'a' value from sysibm.sysdummy1
union all
select '+1' value from sysibm.sysdummy1
union all
select ' -1' value from sysibm.sysdummy1
union all
select '- 1' value from sysibm.sysdummy1
union all
select '--1' value from sysibm.sysdummy1
union all
select '1 1' value from sysibm.sysdummy1
union all
select '' value from sysibm.sysdummy1
union all
select ' ' value from sysibm.sysdummy1
union all
select cast(null as char) value from sysibm.sysdummy1
) string_numbers;
它也可以被定義爲函數。但是,這不會讓它變得更難看。它可能縮短或包含錯誤。因此,儘管他必須處理異常處理,但我更喜歡mustaccio的solution。
但你爲什麼要將varchar轉換爲int? (每次你想做這樣的演員時,問問你自己是否應該更新表格設計。) – jarlh
@jarlh最明顯的原因是「因爲寫這個查詢的人可能無法控制源數據」。 – 2015-11-04 10:40:14