【问题标题】:SQL Server - Cast invalid value to intSQL Server - 将无效值转换为 int
【发布时间】:2013-12-22 11:35:11
【问题描述】:

如果输入数据损坏,有什么方法可以处理 SQL 强制转换?

假设我有一列数据类型为 NVarchar(10),并希望将此列转换为 int

我们还假设某些nvarchar 值已损坏,因此无法将它们转换为int

有什么方法可以默默地忽略这些,将它们默认为 0 或类似的?

【问题讨论】:

  • SQL Server 2012 现在具有 TRY_PARSETRY_CASTTRY_CONVERT 函数,可以完全满足您的需求。但这些仅限于 2012(及更新版本)。
  • 是否有任何后备方案?例如以某种方式首先匹配数字的案例?

标签: sql-server tsql casting


【解决方案1】:
DECLARE @t TABLE (Numbers VARCHAR(20))
INSERT INTO @t
VALUES
('30a'),('30'),('100'),
('100a'),('200'),('200a')

SELECT CASE 
         WHEN ISNUMERIC(Numbers) = 1 
          THEN CAST(Numbers AS INT) ELSE NULL END AS Number
FROM @t

ISNUMERIC 函数返回 1 当它是一个整数值时你可以使用这个函数。

结果

Number
NULL
30
100
NULL
200
NULL

它将投射integer values to INT and ignore the values that cannot be cast to Int

【讨论】:

  • Isnumeric() 函数不起作用,因为它会为其他一些不是数字的字符返回 true。这是demoMSDN 链接了解更多详情
  • ISNUMERIC 在大多数情况下很有用,但请记住某些值不会被函数捕获。例如,有时您会得到中间带有 e 的值,即使我们不想要这些值。
  • 是的,我要提到这一点,就好像您的值中有 e 一样,它会将其视为剩余整数的幂。 222e2 被视为 222^2
  • 不只是e,请check this example 它有$ 1,还有ISNUMERIC() 返回true
【解决方案2】:

PatIndex()函数试试这个:

select id, val
from t
where  patindex('%[^0-9]%',val) = 0

注意:上面的查询是过滤掉损坏的值,如果您需要将它们带入 0 值,请使用case expression,如下所示。

select id, case when patindex('%[^0-9]%',val) = 0 
                then convert(int, val) 
           else 0 end val
from t 

Fiddle demo for both queries

【讨论】:

    【解决方案3】:

    我会成为不受欢迎的人并建议REGEX,因为ISNUMERIC 虽然有时很有用,但并不能抓住一切。 This answer on SO 很好地涵盖了一些 REGEX 概念,例如:

    一个数字

    可能是其中最简单的一个:

    WHERE Column LIKE '[0-9]'
    

    如需了解更多详情,请参阅 Phil Factor 和 Robyn Pae 的 useful REGEX workbench

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-07
      相关资源
      最近更新 更多