原谅我,如果这个问题在 SO 上的另一张票中得到解决……我一直在寻找,但似乎找不到完全正确的解决方案……
我正在创建一个表。“Creditor”列一直是数字,除了最后一个字符可能是破折号。
这意味着像“1234-”、“92846293”等示例是有效的,而“12354-53”、“12345K”是无效的。字符串长度不是固定的(除了它是 varchar(50))。
我不知道如何创建检查约束。
请帮忙!
原谅我,如果这个问题在 SO 上的另一张票中得到解决……我一直在寻找,但似乎找不到完全正确的解决方案……
我正在创建一个表。“Creditor”列一直是数字,除了最后一个字符可能是破折号。
这意味着像“1234-”、“92846293”等示例是有效的,而“12354-53”、“12345K”是无效的。字符串长度不是固定的(除了它是 varchar(50))。
我不知道如何创建检查约束。
请帮忙!
您没有说明您的 DBMS。对于 PostgreSQL,这将是:
alter table foo
add constraint check_creditor check (creditor ~ '^([0-9]+)\-?$');
对于 Oracle,这将是:
alter table foo
add constraint check_creditor check (regexp_like(creditor, '^([0-9]+)\-?$'))
如果您的 DBMS 支持正则表达式,您将需要使用 DBMS 的语法来检查这一点。正则表达式本身'^([0-9]+)\-$'
很可能是相同的。
谢谢您的回复。
这个提议'%[^0-9]%'
让我大开眼界,因为我以前不认识^
接线员。
我做了两个版本的所需约束。一种使用“仅”AND、OR、子字符串和非数字。没有花哨的索引或排除。太长了。另一个版本由 AND、OR、子字符串和 insmuric 组成,但包含了建议的 ^ 操作。看起来好看了很多。
然后,最后,我采用了第三种解决方案 :-) 在数据库中添加了一个 bool 列 RequiresCreditorValidation,并在我的 C# 代码中实现了一个正则表达式。
对于希望从结果检查中受益的其他人,他们在这里。从“丑陋”的开始:
CHECK ((val NOT IN ('+','-') AND (ISNUMERIC(val) = 1) OR
(ISNUMERIC(SUBSTRING(val, 1, DATALENGTH(val) -1))) = 1) AND
((SUBSTRING(val, (DATALENGTH(val)),1) LIKE '[0-9]') OR
(SUBSTRING(val, DATALENGTH(val),1) = '-')) AND
(SUBSTRING(val, 1, 1) NOT IN ('+','-')) )
第二个:
CHECK ( (SUBSTRING(val, 1, DATALENGTH(val) - 1) NOT LIKE '%[^0-9]%') AND
(SUBSTRING(val, DATALENGTH(val),1) LIKE '%[0-9-]') AND (DATALENGTH(val) > 0)
AND SUBSTRING(val, 1,1) NOT IN ('+','-') )
然后是正则表达式:
var allButLast = kreditorId.Substring(0, kreditorId.Length - 1);
if (Regex.Match(allButLast, "[^0-9]").Success)
return false;
if (!kreditorId.EndsWith("-"))
if (Regex.Match(kreditorId, "[^0-9]").Success)
return false;
return true;
感谢大家的良好,合格和快速的答复。
对于 SQL Server:
测试 1:除最后一个之外的所有字符都是数字(或者,不存在非数字字符):
CHECK ( SUBSTRING(Creditor, 1, LEN(Creditor) - 1) NOT LIKE '%[^0-9]%' )
测试 2:最后一个字符是数字或破折号:
CHECK ( SUBSTRING(Creditor, LEN(Creditor), 1) LIKE '%[0-9-%]' )
以上假设Creditor
不能是空字符串,即
CHECK ( LEN(Creditor) > 0 )
只是为了好玩:
CHECK ( REVERSE(CAST(REVERSE(Creditor) + REPLICATE(0, 50) AS CHAR(50)))
LIKE REPLICATE('[0-9]', 49) + '[0-9-]' )