我正在尝试对关键字段实施检查约束。键字段由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的帖子所提出的那样。
全部谢谢!
答案 0 :(得分:2)
你可以这样做:
where LEFT(IDCompany, 3) = 'CMP'
and isnumeric(RIGHT(IDCompany, len(IDCompany) - 3)) = 1
and IDCompany not like '%[.,-]%'
第一部分检查它是以CMP开始的
下一部分是确保其余部分是数字,但不包括负数和十进制数。
答案 1 :(得分:2)
好吧,我会重新考虑你的表的设计并创建3列:
答案 2 :(得分:1)
不幸的是,SQL Server不支持正则表达式。
因此,只有两种方法可以解决您的问题:
使用CLR函数来使用正则表达式。您可以找到更多信息here
或者像你建议的那样伪造长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的评论所指出的,我们需要额外检查以确保数字字符串中使用的字符(如逗号或点)不是输入字符串的一部分。