避免在 DB2 中将 String 转换为 Integer 时出错
Avoid having error when converting String to Integer in DB2
我想 select 定义为 VARCHAR
的列,作为 INTEGER
,如下所示:
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,'','+-0123456789'))) = 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的,虽然他要处理异常处理
我想 select 定义为 VARCHAR
的列,作为 INTEGER
,如下所示:
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,'','+-0123456789'))) = 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的