在表中查找具有无法转换为int的值的行

时间:2013-06-17 22:15:48

标签: sql-server casting overflow

我需要一种方法来检测MSSQL中的表中的行,其中的varchar条目无法转换为int。

我正在处理的系统在一个地方使用可编辑的varchar字段,并将其连接到另一个地方的整数列。如果varchar字段中包含无效数字(空白,带有alpha或符号,或者数字超过21亿(max int size)),则另一个查询失败,表示值xyz溢出int列,或者可能不被转换。

我想出了以下部分解决方案来查找违规记录:

select g.id, g.membernumber from groups g
left join secondary_groups sg on sg.id=g.id 
where convert(bigint, g.membernumber) > 2147483647 
or isnumeric(g.membernumber) = 0

这适用于大多数事情,但后来我意识到,如果你的varchar值超过'bigint',它可能会失败。是否有更通用的方法来定位这些类型的记录,而不是使用强制转换?如果有一个“IsInt()”的内置方法,那将是很棒的...但是...

2 个答案:

答案 0 :(得分:6)

如果您只对INT感兴趣,那么您可以使用PATINDEX(' [^ 0-9]',g.membernumber)来测试字符串是否包含任何非数字字符。然后,您将使用LEN确保字符串不超过10个字符,然后尝试将其转换为bigint。因此,WHERE条件将如下所示:

where 1 = CASE WHEN patindex('%[^0-9]%', g.membernumber) > 0 THEN 1
               WHEN LEN(g.membernumber) > 10 THEN 1
               WHEN convert(bigint, g.membernumber) > 2147483647 THEN 1
               WHEN LEN(g.membernumber) = 0 THEN 1 --Empty string causes error on convert
               ELSE 0 END

SQL Server CASE用作短路评估。这就是我在where子句

中使用CASE的原因

SQLFiddle

答案 1 :(得分:4)

从SQL Server 2012开始,您可以使用TRY_CAST表达式,该表达式在无法执行强制转换时返回NULL

select * from table
where TRY_CAST(Value as int) is null

请注意,TRY_CAST使用与CAST相同的投射规则,例如它将空白字符串转换为0.这在您的情况下不是问题,但在转换结果在SQL之外使用时应该考虑。

还有类似的TRY_CONVERT表达式,其语法与CONVERT相同,但需要将DB兼容级别更改为120或更高,而TRY_CAST也适用于100。 / p>