【问题标题】:Checking if data violates SQL decimal constraint检查数据是否违反 SQL 十进制约束
【发布时间】:2014-12-30 21:07:45
【问题描述】:

我有一个表,它的列从 VARCHAR 更改为 DECIMAL(20,7) 数据类型。我需要找出列中哪些行具有违反DECIMAL(20,7) 数据类型的值,我相信我已经接近了。

到目前为止,我所拥有的是:

SELECT * 
FROM tableName
WHERE 
     (ISNUMERIC(columnName)  = 0 and columnName IS NOT NULL)
     OR (columnName LIKE '%,%')
     OR (LEN(columnName) > 20)

我想我主要是挂在LEN 支票上,因为我仍然会错过结果。有没有办法更深入地了解长度,以便我可以精确检查,而不仅仅是 20 的长度?

【问题讨论】:

  • SQL 服务器 2005/2008/2012
  • 当然,检查 instr 的位置。并计算其右侧的位置。如果> 7,您有问题。如果多个 .你有问题。但似乎正则表达式可以完成所有这些,我只是写它们很糟糕。
  • 如果您有权访问数据库的副本,您可以添加一个 DECIMAL(20, 7) 类型的新列,然后循环遍历并一次复制一个来自 varchar 的值,注意以任何一个为准失败的。这很粗略,但避免追究所有可能的条件。
  • 也许使用正则表达式?

标签: sql sql-server sql-server-2008 sql-server-2005 decimal


【解决方案1】:

您在评论中提到了 SQL Server 2012,对于 2012 或更高版本,请查看 TRY_PARSE 是否适合您。

declare @table table (Input varchar(50))

insert @table (Input) 
values ('20,000.0001'), ('abc'), ('1234'), ('0.12345678'), ('1234567891234.1234567')

select Input from @table
where 
    TRY_PARSE(Input as decimal(20,7)) <> TRY_PARSE(Input as decimal(21,8)) 
    or TRY_PARSE(Input as decimal(20,7)) is null

/*
   abc
   0.12345678
*/

【讨论】:

    【解决方案2】:

    我建议您删除Isnumeric 函数,该函数在很多情况下都会失败。而是添加Like 运算符和另外一个条件。仍然可能有一些空白需要填补。

    SELECT *
    FROM   tableName
    WHERE  ( columnName LIKE '%[^.0-9]%'
             AND columnName IS NOT NULL )
            OR ( columnName LIKE '%,%' )
            OR (( columnName LIKE '%.%.%' ))
            OR ( Len(columnName) > 20 ) 
    

    【讨论】:

      【解决方案3】:

      这应该适合你。

      SELECT * FROM [tablename] AS t
      WHERE LEN([columnname]) > 21
      OR LEN([columnname]) - CHARINDEX('.', [columnname]) > 7
      

      【讨论】:

        猜你喜欢
        • 2014-03-23
        • 1970-01-01
        • 1970-01-01
        • 2017-03-01
        • 2011-01-11
        • 2021-12-05
        • 1970-01-01
        • 2023-02-01
        • 2014-11-27
        相关资源
        最近更新 更多