存储一个信用卡号码作为...号码保证有朝一日在脚下拍摄你。例如您开始遇到带有前导零的信用卡号码的那一天。它们可能由十进制数字组成,但它们不是号码。他们是文字。
未来计划:当有人开始用信件发出信用卡号码时会发生什么?
所以,试试这个:
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' , '123456789') -- 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) ,
)
另外:你加密使用强大的加密卡号,不是吗?
与您的问题无关,但用户和信用卡之间的一对多关系可能会更好。另外,请确保您遵守存储信用卡数据的所有相关安全准则。 –