查询是 - 没有用户应该能够更改产品表的价格。向用户显示msg shold。所有改变价格的尝试都应保存在临时表中。
如何使用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
答案 0 :(得分:2)
我不会将此写为尝试回滚错误更改的AFTER触发器,而是将其视为INSTEAD OF触发器,将任何尝试更新记录到价格但允许更新其他列。
ALTER TRIGGER tr_Products_U ON dbo.ProductDemo INSTEAD OF UPDATE
AS
IF UPDATE(ListPrice)
BEGIN
PRINT 'Can''t Change Price'
INSERT INTO #UpdateLIstPrices
SELECT 'Tried to update the price of ' + d.Name
+ ' [ProductID :' + CONVERT(VARCHAR(10), d.ProductId) + '] '
+ ' from '
+ CONVERT(VARCHAR(10), d.ListPrice)
+ ' to ' + CONVERT(VARCHAR(10), i.ListPrice)
FROM inserted i
INNER JOIN deleted d
ON i.ProductID = d.ProductID
END
ELSE
BEGIN
UPDATE pd
SET Name = i.Name
/*, other columns as needed */
FROM inserted i
INNER JOIN dbo.ProductDemo pd
ON i.ProductID = pd.ProductID
END
RETURN
GO
答案 1 :(得分:1)
您可以通过将UPDATE
包装在TRY / CATCH块中来避免错误消息。这还允许您报告您不想抑制的错误。例如,您可能想尝试这样做:
BEGIN TRY
UPDATE ProductDemo
SET ListPrice = 100.00
WHERE ProductID = 3
END TRY
BEGIN CATCH
IF ERROR_NUMBER() <> 3609
BEGIN
DECLARE @errormessage nvarchar(500)
DECLARE @errorstate INT
DECLARE @errorseverity INT
SET @errormessage = 'Error ' + CAST(error_number() AS nvarchar) + ': ' + error_message()
SET @errorstate = error_state()
SET @errorseverity = error_severity()
RAISERROR (@errormessage, @errorseverity, @errorstate)
END
END CATCH
触发器确实存在另一个问题。它没有预料到使用单个UPDATE
语句更新多行的情况。将inserted
和deleted
表中的列保存到变量时,除了结果集中返回的最后一行之外,您将丢失所有行的信息。您可以使用单个SELECT
语句替换SET
,INSERT
和INSERT INTO... SELECT FROM
语句来避免这种情况。
PRINT 'Can''t Change Price'
INSERT INTO #UpdateLIstPrices
SELECT 'Tried to update the price of ' + d.Name
+ ' [ProductID :' + CONVERT(VARCHAR(10), d.ProductId) + '] '
+ ' from '
+ CONVERT(VARCHAR(10), d.ListPrice)
+ ' to ' + CONVERT(VARCHAR(10), i.ListPrice)
FROM inserted i
INNER JOIN deleted d ON i.ProductID = d.ProductID