如何将表格中的字段限制为15或16位数。我有这张桌子:
create table Person(
,UserID varchar(30)
,Password varchar(30) not null
,CCtype varchar(8)
,CCNumber numeric
,primary key(UserID)
,constraint CK_CCvalidity check
(
(CCType is null or CCNumber is null)
or
(
(CCType = 'Amex' or CCType = 'Discover' or CCType = 'MC' or CCType = 'VISA')
and
(CCNumber >= 15 and CCNumber <= 16)
)
)
);
但实际上这会检查值15和16,而不是数字位数。此外,我们可以假设数字可以保持000 ...作为第一个数字。
感谢您的帮助
答案 0 :(得分:4)
CCNumber
永远不应该是数字。这将导致一个痛苦的世界。
它应该是varchar(X)
,其中X是13 - 24位数。
信用卡号通常由4或5组表示 用空格或短划线分隔的数字或简单地用空格或分隔符分隔的数字。
[注:美国运通:15位数;签证:13或16位]
回应你的评论:
ALTER TABLE dbo.Person
ADD CONSTRAINT CK_Person_CCNumber
CHECK (LEN(CCNumber) = 16 OR LEN(CCNumber) = 15);
但可能更好:
ALTER TABLE dbo.Person
ADD CONSTRAINT CK_Person_CCNumber
CHECK (LEN(CCNumber) >= 13 AND LEN(CCNumber) <= 15);
并添加一个约束以确保它是一个有效的信用卡号码(网上有很多例子)。
答案 1 :(得分:0)
您可以创建一个函数来从varchar中删除非数字字符,例如this one:
CREATE Function [fnRemoveNonNumericCharacters](@strText VARCHAR(1000))
RETURNS VARCHAR(1000)
AS
BEGIN
WHILE PATINDEX('%[^0-9]%', @strText) > 0
BEGIN
SET @strText = STUFF(@strText, PATINDEX('%[^0-9]%', @strText), 1, '')
END
RETURN @strText
END
现在,如果您只想允许数字并想要检查长度,可以添加两个Check Constraints,如下所示:
Create Table Person
(
Id int not null primary key,
CCNumber varchar(30),
CONSTRAINT CK_Person_CCNumber_Length CHECK (LEN(CCNumber) BETWEEN 15 AND 16),
CONSTRAINT CK_Person_CCNumber_IsNumeric CHECK (LEN(dbo.[fnRemoveNonNumericCharacters](CCNumber)) = LEN(CCNumber))
)
First Constraint将检查字段的长度为15或16。
第二个将检查该字段是否为数字(删除非数字的字段长度等于原始字段的长度)
您也可以只在一个ANDed Check Constraint中执行此操作。
答案 2 :(得分:0)
将信用卡号码存储为...号码可以保证有一天会把你射中。例如,您开始遇到带有前导零的信用卡号码的那一天。它们可能包含十进制数字,但它们不是数字。他们是文字。
未来规划:当有人开始用信件发行信用卡号码时会发生什么?
所以,试试这个:
create table dbo.some_table
(
...
credit_card_type varchar(8) null ,
credit_card_number varchar(32) null ,
constraint some_table_ck01 check (
( credit_card_type is not null
and credit_card_number is not null
)
OR ( credit_card_type is null
and credit_card_number is null
)
) ,
constraint some_table_ck02 check (
credit_card_type in ( 'amex' , 'discover' , 'mc' , 'visa' )
) ,
constraint some_table_ck03 check (
credit_card_number not like '%[^0-9]%'
) ,
constraint some_table_ck04 check (
len(credit_card_number) = case credit_card_type
when 'amex' then 15
when 'discover' then 16
when 'mc' then 16
when 'visa' then 16
else -1 -- coerce failure on invalid/unknown type
end
) ,
)
go
insert some_table values( null , null ) -- succeeds
insert some_table values( 'amex' , null ) -- violates check constraint #1
insert some_table values( null , '1' ) -- violates check constraint #1
insert some_table values( 'acme' , '1' ) -- violates check constraint #2
insert some_table values( 'amex' , 'A1B2' ) -- violates check constraint #3
insert some_table values( 'amex' , '12345' ) -- violates check constraint #4
insert some_table values( 'amex' , '123456789012345' ) -- success!
go
但正如其他人所说,您需要修复数据模型。信用卡是与客户分开的实体。它与客户有依赖关系(卡的存在取决于拥有它的客户的存在)。您可以使用以下数据模型。此
create table credit_card_type
(
int id not null primary key clustered ,
description varchar(32) not null unique ,
... -- other columns describing validation rules here
)
create table credit_card
(
customer_id int not null ,
type int not null ,
number varchar(32) not null ,
expiry_date date not null ,
primary key ( customer_id , number , type , expiry_date ) ,
unique ( number , customer_id , type , expiry_date ) ,
foreign key customer references customer(id) ,
foreign key type references credit_card_type(id) ,
)
此外:您使用强加密加密卡号,不是吗?