【发布时间】:2019-04-01 16:32:01
【问题描述】:
我正在尝试在 SQL Server Management Studio 中创建一个触发器,当在同一个表中更新了单独的列时,该触发器会将列值增加 1。
当更新脚本运行时,我们要更新的列的值变为 NULL
我的示例是,当我更改客户的地址时,我希望在每次更改地址时增加一列,即 NoOfAddressess = 1、2、3 等...
这是我正在编写的 SQL 代码
ALTER TRIGGER trg_customeraudit
ON tblCustomer
AFTER UPDATE, DELETE, INSERT
AS
INSERT INTO dbo.CustomerDetailsAudit
VALUES (CURRENT_USER, CURRENT_TIMESTAMP,
(SELECT CustomerID FROM inserted),
(SELECT CustomerAddress FROM deleted),
(SELECT CustomerAddress FROM inserted),
(SELECT CustomerPostcode FROM deleted),
(SELECT CustomerPostcode FROM inserted),
(SELECT NumberOfChangedAddresses FROM dbo.CustomerDetailsAudit)
)
IF ((SELECT CustomerAddress FROM inserted) =
(SELECT CustomerAddress FROM deleted) OR
(SELECT CustomerPostcode FROM deleted) =
(SELECT CustomerPostcode FROM inserted))
BEGIN
RAISERROR ('You must enter both a new postcode and address',16,10)
ROLLBACK TRANSACTION
END
ELSE
BEGIN
PRINT 'Transaction successful'
WHERE CustomerID = (SELECT CustomerID from inserted)
END
IF UPDATE (CustomerName)
BEGIN
RAISERROR ('You cannot change the customer name', 16, 10)
ROLLBACK
END
【问题讨论】:
-
您好,欢迎来到 Stack Overflow。你有什么问题?
-
您的触发器有 MAJOR 缺陷,您似乎认为它会被 每行调用一次 - 事实并非如此。触发器将每条语句触发一次,因此如果您的
INSERT导致此触发器触发插入 25 行,您将触发触发器一次和@987654323 @ 伪表将包含 25 行。您的代码将从Inserted中选择这 25 行中的哪一行?它是不确定的,您将获得任意行,而您将忽略所有其他行。您需要重写触发器以考虑到这一点! -
如果您的语句影响多行,那么像
SELECT CustomerID FROM inserted这样的语句将从 5、10 或inserted中的 25 个条目,忽略所有其他条目。无法保证会选择哪一个 - 所以基本上,只要没有人一次插入、更新或删除多行,所有这些代码都可以工作。如果发生这种情况,此代码将不执行您期望的操作!你需要完全重写你的代码 -
你只是突然自找麻烦,不知何故用户或程序开始更新多行......
-
如果您绝对确定不会超过一行,那么请添加对行数的检查并使用
RaIsError或Throw明确告知那些后来发现他们试图执行不可接受的声明的人。 (if ( select Count(*) from inserted ) > 1 RaIsError( 'FooTable_Insert: No more than one row may be processed.', 25, 42 ) with log)
标签: sql-server tsql triggers