死灵术。
如果你真的只是想要一个强制执行 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 搜索到这里寻找一般电话号码的约束条件...
那么,我一直在思考电话号码的正确限制是什么。
查看questions 723587,我能够确定电话号码的最大长度为31位。
鉴于我们需要发送 SMS,这意味着它必须是一个有效号码才能发送,我认为防止人们在现场乱扔垃圾的最佳“约束”是将其声明为十进制(31, 0)。您还可以在其中放置一个检查约束以确保电话号码的最小长度(最小号码)。另外,您需要检查该数字是否不小于零。
如果你绝对想用 varchar 来做,那么看看 Gordon Linoff 的帖子,我确定它需要在数字的开头允许一个 + 号,所以最终字段类型是 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。
另外,请注意,您应该始终区分数据和实际显示值。
因此,我认为存储电话号码的最佳方式是:
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' 等值。
如果您有一个使用空格和/或破折号的格式化电话号码作为输入,只需执行REPLACE(REPLACE('YOUR_PHONE_NUMBER', ' ', ''), '-', ''),该约束将有助于防止替换未捕获的任何不需要的格式字符进入数据库(比如大括号)。