SQL服务器数字字段的数字限制

时间:2014-01-20 23:52:02

标签: sql sql-server tsql

如何将表格中的字段限制为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 ...作为第一个数字。

感谢您的帮助

3 个答案:

答案 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) ,

)

此外:您使用强加密加密卡号,不是吗?