>我正在尝试对关键字段实现检查约束。键字段由 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在下面的帖子中所建议的那样。
谢谢大家!
做这样的事情:
where LEFT(IDCompany, 3) = 'CMP'
and isnumeric(RIGHT(IDCompany, len(IDCompany) - 3)) = 1
and IDCompany not like '%[.,-]%'
第一部分检查它是否以 CMP 开头
下一部分是确保其余部分是数字,但不包括负数和十进制数。
好吧,我会重新考虑您的表格设计并创建 3 列:
- 前缀 CHAR(3),默认值为"CMP",约束仅允许"CMP"组合
- id, 整数
- 公司 ID, NVARCHAR(9),一个计算的持久列,作为前 2 列的总和。最有可能带有索引。
不幸的是,SQL Server不支持正则表达式。
因此,只有两种方法可以解决您的问题:
-
使用 CLR 函数使用正则表达式。您可以在此处找到更多信息
-
或者像你建议的那样使用长
IDCompany LIKE 'CMP[0-9]' 或WHERE
条款:IDCompany LIKE 'CMP[0-9][0-9]' 或 ....
试试这个:
isnumeric(substring(IDCompany,4,len(IDCompany)))=1 and IDCompany not like '%[.,-]%'
工作原理:前三个字符是固定的,所以我们只需要从第 4 个字符开始检查。所以我们得到所需的子字符串。然后,我们使用isNumeric
来检查子字符串是否完全是数字。这里的例子
编辑:正如艾伦在评论中指出的那样,我们需要额外的检查,以确保逗号或点等数字字符串中使用的字符不是输入字符串的一部分。