在 SQL 中触发导致错误 "Product_Reorder is not a recognized SET option"

Trigger in SQL causing error "Product_Reorder is not a recognized SET option"

CREATE OR ALTER TRIGGER CheckQuantity
ON dbo.Products 
AFTER UPDATE
AS
BEGIN
    UPDATE dbo.Products
    SET Product_ReOrder = 1 
    FROM Inserted i
    WHERE i.Product_ID = dbo.Products.Product_ID
      AND i.Product_QOH < 5;

我没有收到语法错误

syntax error near ;

这是指代码末尾的;

不是 100% 确定您要做什么 - 您也没有给我们太多可以继续的东西!

假设你的意思是你想在你的table中设置一个名为Product_ReOrder如果另一列 Product_QOH 小于 5,则为 1 - 正确吗?

在这种情况下 - 使用类似这样的触发器:

CREATE OR ALTER TRIGGER CheckQuantity
ON dbo.Products 
AFTER UPDATE
AS
BEGIN
    UPDATE dbo.Products
    SET Product_ReOrder = 1 
    FROM Inserted i
    WHERE i.PrimaryKeyColumn = dbo.Products.PrimaryKeyColumn
      AND i.Product_QOH < 5;
END

触发器将在 UPDATE 之后触发,并且 Inserted 将包含 所有 行(可以并且 是多行!)已更新 - 所以我假设您想检查这些行的数量。

我正在将基数 table (dbo.Products) 加入到 Inserted 伪 table 上 table 的主键列(其中我们不知道它是什么 - 所以你需要根据需要调整它),如果 Products_QOH 值小于 5,我将 Product_ReOrder 列设置为 1。

你的代码行

Select @QOH = (select Product_QOH from inserted)

有一个致命缺陷假设只更新了一行 - 有时可能是这种情况 - 但你不能依赖那!您的触发器 必须能够 处理正在更新的多行 - 因为触发器仅被调用 一次 ,即使使用命令更新了 10 行 -然后 Inserted 将包含所有这 10 个更新的行。这样做 select 是危险的 - 你会得到 一个任意的 行,而你将忽略所有其他行....

这就是你要找的吗?

我不清楚您在编写这段代码时在想什么,或者您基于什么模板,但是有很多语法错误

看来您可能想要这样的东西:

  • update() 函数只告诉我们该列是否出现在 update 语句中,而不告诉我们是否有任何实际更改。
  • 我们需要检查我们是否被递归调用,以便退出。
  • 我们还会检查是否根本没有更改任何行,并尽早退出
  • 请注意如何比较 inserteddeleted 以查看是否有任何行实际更改。这也可以正确处理多行。
  • 然后我们需要重新加入 Products 以更新它。
create or alter trigger CheckQuantity
on Products 
after update
as
    set nocount on;

    if not(update(Products_QOH))
       or trigger_nestlevel(object_id(N'dbo.CheckQuantity'),'AFTER','DML') > 1
       or not exists (select 1 from inserted)
         return;  -- early bail-out

    update p
    set Product_ReOrder = 1
    from Products p
    join (
        select i.YourPrimaryKey, i.Products_QOH
        from inserted i
        where i.Product_QOH < 5
        except
        select d.YourPrimaryKey, d.Products_QOH
        from deleted d
    ) i on i.YourPrimaryKey = p.YourPrimaryKey;

但是,我完全不明白你为什么要使用触发器。

我强烈建议您为此使用计算列:

ALTER TABLE Products
    DROP COLUMN Product_ReOrder;

ALTER TABLE Products
    ADD Product_ReOrder AS (CASE WHEN Product_QOH < 5 THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END);