【发布时间】:2021-12-24 04:02:52
【问题描述】:
我想在插入表格之前触发以清除非数字字符中的电话号码。
电话桌是这样的:
rowId PhoneNumber DepartmentId ...
1 12345678 4 ...
2 23456789 5 ...
3 34255467 6 ...
我创建了这个触发器:
CREATE TRIGGER tr_insertPhone ON [Phone]
instead of INSERT as
begin
declare @Phone nvarchar(50)
declare @DepartmentId int
...
select @Phone = (select PhoneNumber from inserted)
select @DepartmentId = (select DepartmentId from inserted)
...
WHILE PATINDEX('%[^0-9]%',@Phone)>0
set @Phone=STUFF(@Phone,PATINDEX('%[^0-9]%',@Phone),1,'')
if (len(@Phone)>7) and (len(@Phone)<14)
INSERT INTO [Phone](PhoneNumber,DepartmentId,..) values (@Phone,@DepartmentId,..)
end
但在插入时出现错误:
Msg 512, Level 16, State 1, Procedure tr_insertPhone, Line 10 [Batch Start Line 1]
SQL Server Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as as expression.
我做错了什么?
【问题讨论】:
-
您假设,在您的触发器中,
INSERT只影响一行。这是不正确的;它可以影响 0+ 行。此外,TRIGGER的影响应该尽可能小,而WHILE将与此远离。我建议你在这里完全重新考虑你的方法。您实际上试图解决的问题是什么? -
SQL Server 有语句触发器,而不是行触发器。您必须假设
inserted有多行。您可以将清理逻辑分解为标量 UDF 并执行基于集合的 INSERT,或者在inserted上打开游标并对每一行进行操作。 -
我的 gole 非常简单,制作一个触发器,在插入之前检查和清理每个电话号码(从非数字字符中清除它,并且只有在它有 7-14 个数字时才插入)。
-
CHECK CONSTRAINT阻止错误输入会更好吗,@rotem ...?尽管假设电话号码仅由数字组成是错误的。您将如何存储国际号码、区号(某些国家/地区将它们放在括号中 (()))或所需的分机号码? -
再次,
CHECK CONSTRAINT。如果您想变得聪明,请在您的表示层中添加进一步的验证。
标签: sql sql-server triggers