将更新尝试保存在更新触发器的临时表中
查询是 - 任何用户都不应能够更改产品表的价格。应向用户显示一条消息。此外,所有更改价格的尝试都应保存在临时表中。
如何使用 Sql server 2005 中的更新触发器解决此问题? 我已经尝试如下。它按预期工作,但也显示错误 -
事务在触发器中结束。该批次已中止。
ALTER TRIGGER tr_Products_U ON dbo.ProductDemo AFTER UPDATE
AS
DECLARE @Data VARCHAR(200),
@sProductName NVARCHAR(40),
@mOldPrice MONEY,
@mNewPrice MONEY,
@ProductId int
IF UPDATE(ListPrice)
BEGIN
SELECT
@ProductId = d.ProductID,
@sProductName = d.Name,
@mOldPrice = d.ListPrice,
@mNewPrice = i.ListPrice
FROM
inserted i INNER JOIN deleted d ON i.ProductID = d.ProductID
SET @Data = 'Tried to update the price of ' + @sProductName
+ ' [ProductID :' + CONVERT(VARCHAR(10), @ProductId) + '] '
+ ' from '
+ CONVERT(VARCHAR(10), @mOldPrice)
+ ' to ' + CONVERT(VARCHAR(10), @mNewPrice)
print 'Can''t Change Price'
ROLLBACK TRAN
INSERT INTO #UpdateLIstPrices
VALUES (@Data);
END
RETURN
GO
The query is -
No user should be able to change prices of the products Table. A msg shold be displayed to the user. also all attempts to change the price should be saved in temp table.
How to solve this using update trigger in Sql server 2005?
I have tried as below. It is working as expected but also showing an error -
The transaction ended in the trigger. The batch has been aborted.
ALTER TRIGGER tr_Products_U ON dbo.ProductDemo AFTER UPDATE
AS
DECLARE @Data VARCHAR(200),
@sProductName NVARCHAR(40),
@mOldPrice MONEY,
@mNewPrice MONEY,
@ProductId int
IF UPDATE(ListPrice)
BEGIN
SELECT
@ProductId = d.ProductID,
@sProductName = d.Name,
@mOldPrice = d.ListPrice,
@mNewPrice = i.ListPrice
FROM
inserted i INNER JOIN deleted d ON i.ProductID = d.ProductID
SET @Data = 'Tried to update the price of ' + @sProductName
+ ' [ProductID :' + CONVERT(VARCHAR(10), @ProductId) + '] '
+ ' from '
+ CONVERT(VARCHAR(10), @mOldPrice)
+ ' to ' + CONVERT(VARCHAR(10), @mNewPrice)
print 'Can''t Change Price'
ROLLBACK TRAN
INSERT INTO #UpdateLIstPrices
VALUES (@Data);
END
RETURN
GO
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我不会将其编写为尝试回滚错误更改的 AFTER 触发器,而是将其作为 INSTEAD OF 触发器来处理,该触发器记录对价格的任何尝试更新,但允许更新其他列。
Rather than writing this as an AFTER trigger that tries to rollback the bad change, I would approach this as an INSTEAD OF trigger that logs any attempted update to price but allows updates to other columns.
您可以通过将
UPDATE
包装在 TRY/CATCH 块中来避免出现错误消息。这还允许您报告您不想抑制的错误。例如,您可能想尝试以下操作:触发器确实存在另一个问题。它没有预料到使用单个
UPDATE
语句更新多行的情况。将inserted
和deleted
表中的列保存到变量时,您将丢失除结果集中返回的最后一行之外的所有行的信息。您可以通过将SELECT
、SET
和INSERT
语句替换为单个INSERT INTO...SELECT FROM
来避免这种情况。代码>声明。You can avoid the error message by wrapping your
UPDATE
in a TRY/CATCH block. This will also allow you to report errors that you do not want to suppress. For example, you may want to try this:You do have another issue with the trigger. It doesn't anticipate the situation where multiple rows are updated with a single
UPDATE
statement. When you save columns from theinserted
anddeleted
tables to variables, you will lose information from all rows except the last rows returned in the result set. You can avoid this situation by replacing yourSELECT
,SET
andINSERT
statements with a singleINSERT INTO... SELECT FROM
statement.