SQL 服务器中 phone 号码的限制

Constraint for phone number in SQL Server

限制 phone 号码为 7 位数字。如何在SQL服务器中检查它是否为7位数字?

CREATE TABLE Customer
(
    C_ID INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
    C_Name VARCHAR(255) NOT NULL,
    Phone INT 
);

它适用于 Phone VARCHAR CHECK(DATALENGTH(Phone)=7)

不要将 phone 数字存储为整数。例如,一些有效数字可以以 0 开头——如果不是今天,也许将来。要进行验证检查,您可以使用 like:

CREATE TABLE Customer (
    C_ID INT NOT NULL IDENTITY(1, 1) PRIMARY KEY,
    C_Name VARCHAR(255) NOT NULL,
    Phone CHAR(7), -- you might not want to have such a precise length
    CONSTRAINT chk_phone CHECK (phone not like '%[^0-9]%') -- check that no number is not a digit 
);

或者,您可以这样写:

CONSTRAINT chk_phone CHECK (phone like '[0-9][0-9][0-9][0-9][0-9][0-9][0-9]') -- check that no number is not a digit 

您最好将phone 数字存储为varchar2char 类型。在 Oracle 中,您可以通过 正则表达式检查 phone 数字的有效性:

CREATE TABLE Customer
(
    C_ID INT NOT NULL PRIMARY KEY,
    C_Name VARCHAR(255) NOT NULL,
    Phone char(10),
    CONSTRAINT valid_phone_number 
    CHECK (REGEXP_LIKE(p_number, '^0\d{9}|\d{10}$'))
);

'^0\d{9}|\d{10}$' means phone number must start with digit 0, then followed by 9 or 10 digits (i.e 01646947314 (11 digits) or 0123456789 (10 digits) is VALID, and 123456789 or 0123456 is not valid). You can modify this code to 7 digits by dropping "|" in regular expression and change to d{7}. Hope this help you (or someone else's having the similar problem)!

根据 NANP,美国的七位 phone 号码是 NXX-XXXX,其中 N 是 2-9,X 是 0-9。此外,第二个和第三个数字不能都为 1。假设您只想存储真实的 NANP phone 数字,您可以使用以下约束:

ALTER TABLE Customer
ADD CONSTRAINT CHK_Phone_valid
CHECK (Phone >= 2000000 AND Phone <= 9999999 and Phone / 10000 % 100 <> 11)

如果要添加区号,则需要使用 bigint 和 different/additional 约束。此外,任何类型的内部 phone 号码、分机、区号、国际 phone 号码等都会有不同的要求。

作为经常在数据库中处理大量(仅 NANP)phone 数字的人,我确实发现将它们保存为数字格式是理想的,因为它更快、更小并且具有默认情况下防止各种格式问题的额外好处。尽管对于大多数用户来说,这可能都没有实际意义。

假设您有一个学生 table。为了检查接触长度,以下代码有效:

ALTER TABLE Student ADD CONSTRAINT SD_CHK check(contact like '[0-9]*10');

希望对您有所帮助

死灵法术。
如果你真的真的只想要一个强制执行 7 位数字的约束,那么你可以这样做:

DECLARE @phone TABLE 
(
     phone_id int NOT NULL PRIMARY KEY 
    ,phone_name nvarchar(255) NOT NULL 
    ,phone_number int NULL CHECK 
    (
        phone_number >= 1000000 -- or > 999999
        AND 
        phone_number <= 9999999 -- or < 10000000    
    ) 
);



INSERT INTO @phone ( phone_id, phone_name, phone_number )
SELECT 1 AS phone_id, N'Person 1' AS pn, '1000000' AS phone_number; 

INSERT INTO @phone ( phone_id, phone_name, phone_number )
SELECT 2 AS phone_id, N'Person 2' AS pn, '9999999' AS phone_number; 


INSERT INTO @phone ( phone_id, phone_name, phone_number )
SELECT 3 AS phone_id, N'Person 3' AS pn, '+1000000' AS phone_number; 

现在,如果您需要前面的零,您可以这样做:

SELECT RIGHT(('0000000') + CAST(phone_number as varchar(32)), 7) AS number FROM @phone 

但是,如果您只是通过 google-搜索寻找 phone- 数字的一般约束...

然后,我一直在思考 phone 数字的正确约束是什么。

查看 questions 723587,我能够确定 phone 号码的最大长度是 31 位数字。

鉴于我们有发送短信的需求,也就是说必须是有效号码才能发送,我想出了最好的“约束”来防止人们乱扔垃圾带有垃圾的字段是将其声明为 decimal(31, 0)。您还可以在其中放置一个检查约束以确保 phone 数字(最小数字)的最小长度。另外,您需要检查该数字是否不小于零。

如果你绝对想用 varchar 来做,那么看看 Gordon Linoff 的 post,我确定它需要在数字的开头允许一个 + 号,所以最终字段类型是 varchar (32).

如果不需要 +,那么将字段设为 varchar 就多余了。

您可以对 varchar 施加的一个约束是

DECLARE @phone TABLE 
(
     phone_id int NOT NULL PRIMARY KEY 
    ,phone_name nvarchar(255) NOT NULL
    -- ,phone_number varchar(31) NULL CHECK (phone_number NOT LIKE '%[^0-9]%') -- result of check may not be false
    -- ,phone_number varchar(31) NULL CHECK (phone_number NOT LIKE '%[^0-9+]%') -- result of check may not be false
    ,phone_number varchar(32) NULL CHECK 
    (
        (
            phone_number NOT LIKE '%[^0-9]%'
            OR 
            (
                SUBSTRING(phone_number, 1, 1) = '+' 
                AND 
                SUBSTRING(phone_number, 2, 35) NOT LIKE '%[^0-9]%'
            )
        )
        AND phone_number <> '' 
    ) 

    --CONSTRAINT chk_phone CHECK (phone_number NOT LIKE '%[^0-9]%') -- check that no number is not a digit 
);

INSERT INTO @phone ( phone_id, phone_name, phone_number )
SELECT 1 AS phone_id, N'Person 1' AS pn, '123' AS phone_number; 

INSERT INTO @phone ( phone_id, phone_name, phone_number )
SELECT 2 AS phone_id, N'Person 2' AS pn, '+123' AS phone_number; 

INSERT INTO @phone ( phone_id, phone_name, phone_number )
SELECT 3 AS phone_id, N'Person 3' AS pn, '++123' AS phone_number; 

INSERT INTO @phone ( phone_id, phone_name, phone_number )
SELECT 4 AS phone_id, N'Person 3' AS pn, '' AS phone_number; 

INSERT INTO @phone ( phone_id, phone_name, phone_number )
SELECT 5 AS phone_id, N'Person 3' AS pn, NULL AS phone_number; 

请注意,这允许 NULL 值。
要禁止它们,请将字段类型从 NULL 更改为 NOT NULL.

另外请注意,您应该始终区分数据和实际显示值。

因此我认为存储 phone 数字的最佳方式是这样的:

DECLARE @phone TABLE 
(
     phone_id int NOT NULL PRIMARY KEY 
    ,phone_name nvarchar(255) NOT NULL 
    ,phone_number decimal(31,0) NULL CHECK 
    (
        -- phone_number > 0 AND 
        phone_number > 99
    ) 
);



INSERT INTO @phone ( phone_id, phone_name, phone_number )
SELECT 1 AS phone_id, N'Person 1' AS pn, '112' AS phone_number; 

INSERT INTO @phone ( phone_id, phone_name, phone_number )
SELECT 2 AS phone_id, N'Person 2' AS pn, '+12126879970' AS phone_number; 

-- INSERT INTO @phone ( phone_id, phone_name, phone_number )
-- SELECT 3 AS phone_id, N'Person 3' AS pn, '-12126879970' AS phone_number; 

-- INSERT INTO @phone ( phone_id, phone_name, phone_number )
-- SELECT 4 AS phone_id, N'Person 4' AS pn, '++12126879970' AS phone_number; 

-- INSERT INTO @phone ( phone_id, phone_name, phone_number )
-- SELECT 5 AS phone_id, N'Person 5' AS pn, '+' AS phone_number; 

-- INSERT INTO @phone ( phone_id, phone_name, phone_number )
-- SELECT 6 AS phone_id, N'Person 6' AS pn, '0' AS phone_number; 

-- INSERT INTO @phone ( phone_id, phone_name, phone_number )
-- SELECT 7 AS phone_id, N'Person 7' AS pn, '+0' AS phone_number; 


INSERT INTO @phone ( phone_id, phone_name, phone_number )
SELECT 8 AS phone_id, N'Person 8' AS pn, '100.1' AS phone_number; 


SELECT * FROM @phone 

请注意,由于 +SOMETHING 是一个有效数字,您也可以在其中添加一个 +。
像 0.0 这样的值被截断为 0。
一个警告:这允许诸如“100.1”等值

如果您有一个格式化的 phone-数字作为使用空格 and/or 破折号的输入,只需执行 REPLACE(REPLACE('YOUR_PHONE_NUMBER', ' ', ''), '-', ''),约束将有助于防止任何不需要的格式化字符没有被进入数据库的替换捕获(例如大括号)。