【问题标题】:How to make an equivalent INSTEAD OF trigger from an AFTER trigger?如何从 AFTER 触发器制作等效的 INSTEAD OF 触发器?
【发布时间】:2020-07-31 00:43:54
【问题描述】:

我有一个 AFTER 触发器,我正在尝试将其用于等效的 INSTEAD OF 触发器。我有点理解如何执行 INSTEAD OF 触发器来代替触发操作,但转换它让我有点迷茫。

这是我的 AFTER 触发器:

go
CREATE TRIGGER tgr_priceValidation    
ON Products_Copy
FOR INSERT, DELETE AS
BEGIN
    IF exists (select UnitPrice from Products_copy where UnitPrice NOT BETWEEN 0.50 AND 500.00)
    BEGIN
        RAISERROR(
            ' No product is allowed to have a unit price out of the range between $0.50 and $500.00', 
            16, 
            1
        )
       ROLLBACK TRANSACTION
    END
END
go

上述触发器强制执行价格范围规则,要求每个价格都在 0.50 到 500 美元之间。

【问题讨论】:

  • 如果价格不在范围内,您是要阻止整个插入,还是应该仍然允许插入有效记录?
  • 等一下。首先,哪种DELETE 语句会导致您的行中出现UnitPrice 超出定义范围的行?接下来,您真的需要为每个INSERT 扫描整个 表吗?即使UPDATE 会产生超出范围的值,您也会忽略它?
  • 努力吧。首先,更正您的后触发器中的错误。您应该参考虚拟插入和删除表,而不是定义触发器的表(可能 - 但这是没有很好要求的猜测)。接下来,尝试编写代替触发器。有什么不同吗?好吧,instead-of 触发器必须实际对表执行操作(插入、更新、删除)。

标签: sql sql-server tsql database-trigger


【解决方案1】:

不要为此使用触发器。只需使用check 约束:

alter table products_copy add constraint chk_products_copy_unitprice
    check (unitPrice not between 0.50 and 500.00);

作为奖励,这将适用于 updates 以及 inserts。

【讨论】:

    【解决方案2】:

    您似乎可以只使用检查约束而不是触发器:

    alter table products_copy 
        add constraint chk_products_copy_unit_price_range 
        check (unitprice between 0.50 and 500.00); 
    

    这比使用触发器更简单、更高效 - 唯一的区别是您不会收到自定义错误消息。

    【讨论】:

    • 我知道这样做不切实际,但我被要求创建一个等效的 INSTEAD OF 触发器。不允许检查约束。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多