SQL Server - Like / Pattern Matching

时间:2014-04-08 05:52:08

标签: sql sql-server regex

我正在尝试对关键字段实施检查约束。键字段由3个字符的前缀组成,然后附加数字字符(可以手动提供,但默认是从序列中获取整数值,然后将其转换为nvarchar)。关键字段定义为nvarhcar(9)。

我正在为多个表执行此操作,但下面是一个具体示例来演示: 表名:公司 关键字段:IDCompany 关键字段前缀:CMP

有效密钥的示例 -

CMP1
CMP01
CMP10000
CMP999999

无效键的示例 -

CMPdog1
steve
1CMP1
1
999999999

我提出的检查限制是:

IDCompany LIKE 'CMP%[0-9]'

然而,这被CMPdog1等打败了。

我应该使用什么作为检查约束来强制执行未知数量的数字字符?

我可以做以下事情:

IDCompany LIKE 'CMP[0-9]' OR IDCompany LIKE 'CMP[0-9][0-9]' OR .... through to 6 characters

但是,这似乎是一种笨重的做法,是否有更聪明的东西?

编辑2:这实际上不起作用,它不排除负数:

EDIT 1:
This solution ended up working for me:

IDCompany nvarchar(9) NOT NULL CONSTRAINT DEF_Company_IDCompany DEFAULT 'CMP' + CAST((NEXT VALUE FOR dbo.sq_Company) AS nvarchar) CONSTRAINT CHK_Company_IDCompany CHECK (IDCompany LIKE 'CMP%[0-9]' AND ISNUMERIC(SUBSTRING(IDCompany,4,LEN(IDCompany)-3))=1)

编辑3:解决方案 - 正如下面Szymon的帖子所提出的那样。

全部谢谢!

4 个答案:

答案 0 :(得分:2)

你可以这样做:

where LEFT(IDCompany, 3) = 'CMP'
    and isnumeric(RIGHT(IDCompany, len(IDCompany) - 3)) = 1
    and IDCompany not like '%[.,-]%'

第一部分检查它是以CMP开始的

下一部分是确保其余部分是数字,但不包括负数和十进制数。

答案 1 :(得分:2)

好吧,我会重新考虑你的表的设计并创建3列:

  • 前缀,CHAR(3),默认为' CMP'以及只允许CMP'组合
  • id ,INTEGER
  • companyid ,NVARCHAR(9),计算的持久列,作为前2列的总和。最有可能是索引。

答案 2 :(得分:1)

不幸的是,SQL Server不支持正则表达式。

因此,只有两种方法可以解决您的问题:

  1. 使用CLR函数来使用正则表达式。您可以找到更多信息here

  2. 或者像你建议的那样伪造长WHERE条款:

    IDCompany喜欢'CMP [0-9]'或IDCompany喜欢'CMP [0-9] [0-9]'或......

答案 3 :(得分:1)

试试这个:

isnumeric(substring(IDCompany,4,len(IDCompany)))=1 and IDCompany not like '%[.,-]%'

这是如何工作的:前三个字符是固定的,所以我们只需要从第四个字符开始检查。所以我们得到了所需的子串。然后,我们使用isNumeric来检查子字符串是否完全是数字。示例here

编辑:正如Allan的评论所指出的,我们需要额外检查以确保数字字符串中使用的字符(如逗号或点)不是输入字符串的一部分。