【问题标题】:MSSQL Check if column is all digits or emptyMSSQL 检查列是否全为数字或为空
【发布时间】:2019-04-02 11:47:33
【问题描述】:

我在表中有一个 varchar 字段。我必须检查哪些行包含除数字(0-9)之外的任何内容。不允许使用任何其他字符(. 等)。

ISNUMERIC 没有帮助,因为字符串可能比任何可转换为 SQL-Server 中的数字数据类型的字符串都长。

关于如何做到这一点的任何想法?

非常感谢!

【问题讨论】:

  • 为什么首先将数字存储为字符串?
  • 你想做什么?如果该字段应该包含一个数字,它应该是一个数字类型。另一方面,这些数字可能是发票号码或其他业务领域。在任何情况下,SQL 都不是字符串操作的好语言。如果您想检测无效数据,最好使用外部程序来查找无效行。如果您想创建例如触发器,那么最好创建一个使用例如Int.Parse 或正则表达式的SQLCLR UDF。可能还有其他方法,但都不会很快
  • @PanagiotisKanavos 有时一串数字有前导零但不是固定长度。这不适合作为整数数据类型。
  • @HABO 我在评论和回答中解释了这一点。如果它有前导零,则它不是数字。这是一个业务字段,其值仅包含数字。增值税号就是这样的情况
  • 它是您正确假设的业务领域。我几乎没有能力修改正在使用数据的程序本身,所以我需要在另一端找到无效数据。不幸的是,遗留代码。

标签: sql-server tsql


【解决方案1】:

假设“空”表示NULL

Field NOT LIKE '%[^0-9]%'
    OR Field IS NULL

获取仅包含数字或为空的值的示例:

declare @test table (Field varchar(32))

INSERT @test
VALUES
    (NULL),
    ('121414'),
    ('88977665'),
    ('234234f'),
    ('347238748d9')

select * from @test
where Field not like '%[^0-9]%'
    OR Field is null

字段

121414

88977665

获取包含非数字字符且不为空的值的示例:

declare @test table (Field varchar(32))

INSERT @test
VALUES
    (NULL),
    ('121414'),
    ('88977665'),
    ('234234f'),
    ('347238748d9')

select * from @test
where Field like '%[^0-9]%'
    AND Field is NOT null

字段

234234f

347238748d

【讨论】:

  • 谢谢。不幸的是,使用这个,我没有得到任何结果集,即使那里有像“40340,033680998078”这样的数据,它显然有一些不是数字的字符。
  • @Stefan Wolf 不要从最终声明中删除。查询应该是 Where Field like '%[^0-9]%'
  • 哦,我的英文还不错——题中你的标题和信息不一样,反正我已经更正了我的答案
【解决方案2】:

您可以尝试PATINDEX 查找并拒绝包含非数字字符的值:

declare @t table (field varchar(40))
insert into @t (field)
values
('40340,033680998078'),
('40340'),
('033680998078')

select *
from @t
where patindex('%[^0-9]%',field)=0

此查询不能利用任何索引,必须扫描整个表。最好一开始就避免在该字段中存储非数字字符。

一般来说,如果一个字段包含数字数据,它应该使用数字类型,而不是 varchar。它应该是intbigintnumeric(...,0)

另一方面,该字段可能是存储例如发票编号、机票或增值税号的业务字段。

在这种情况下,人们会想要使用CHECK 约束来确保无法在表中插入无效值。这可以使用 PATINDEX :

declare @t table 
( 
    field varchar(40) CHECK (patindex('%[^0-9]%',field)=0)
);

这个检查约束将允许:

insert into @t (field)
values
('40340'),
('033680998078')

但拒绝:

insert into @t (field)
values
('40340,033680998078')

【讨论】:

  • 这很好用——我发现了缺少的东西。每个字段的末尾都有一个不可见的换行符。替换它 - 现在工作正常!
猜你喜欢
  • 1970-01-01
  • 2015-06-05
  • 2019-12-16
  • 2011-11-04
  • 1970-01-01
  • 1970-01-01
  • 2017-08-19
  • 1970-01-01
  • 2017-09-05
相关资源
最近更新 更多