【问题标题】:Enumerate the multiple rows in a multi-update Trigger枚举多更新触发器中的多行
【发布时间】:2021-03-03 06:24:04
【问题描述】:

我有类似下表的内容:

CREATE TABLE updates (
    id INT PRIMARY KEY IDENTITY (1, 1),
    name VARCHAR (50) NOT NULL,
    updated DATETIME
);

我正在更新它:

INSERT INTO updates (name, updated)
VALUES
    ('fred', '2020-11-11),
    ('fred', '2020-11-11'),
    ...
    ('bert', '2020-11-11');

我需要编写一个更新后触发器并枚举所有添加的名称并将每个名称添加到另一个表中,但无法确定如何枚举每个名称。

编辑:-感谢那些为我指明正确方向的人,我对 SQL 知之甚少。

我需要做的是这样的事情

  • foreach 名称已插入
  • 在另一个表中查找并
  • 检索“名称”已完成的更新计数
  • 计数加 1
  • 并将其更新回另一个表中

目前我无法使用笔记本电脑,但大概可以执行以下操作:

BEGIN
  SET @count = (SELECT UCount from OTHERTAB WHERE name = ins.name)
  SET @count = @count + 1
  UPDATE OTHERTAB SET UCount = @count WHERE name = ins.name
  SELECT ins.name
  FROM inserted ins;
END

这适用于更新中的每个名称?

显然,我必须阅读基于集合的 SQL 处理。

感谢大家的帮助和指点。

【问题讨论】:

  • 提示:光标或while循环。但是,如果您只是添加到另一个表中,您几乎不需要枚举,一个简单的 SQL 插入处理数据集。官方文档说明了一切。
  • 如果您计划在 SQL 中循环,您可能已经有错误的计划。迭代是 RDBMS 中最慢的事情之一。使用基于集合的方法。
  • 您可能想在update OtherTab 时使用distinct name from inserted。由于触发器将在每个语句而不是每行触发一次,因此相同的名称可能会出现多次。
  • 我无法得到任何建议来工作 - 我已经研究出如何使用光标来做到这一点 - 这些更适合我的大脑,但我知道他们不赞成。通过将插入/更新代码放入存储过程中,我大大简化了事情。我想我应该删除这个问题并提出一个新问题,询问如何将基于光标的方法转换为基于集合的方法。
  • 鉴于我的回答确实回答了您的问题,您可能应该考虑接受它,以及提出另一个问题。它在您的特定情况下不起作用的唯一原因是问题中缺少信息。

标签: sql sql-server tsql triggers


【解决方案1】:

根据您的编辑,您可以执行以下操作...基于集合是一种心态,因此您无需提前计算计数(实际上您不能)。不清楚您是在同一张桌子还是另一张桌子上数数 - 但我相信您可以算出来。

积分:

  • 使用 Inserted 表确定要更新的行
  • 如果是第二张表,则使用子查询计算新值,考虑到 null 的可能性

如果你真的使用同一张表,那么这应该可以工作

BEGIN
    UPDATE OTHERTAB SET
      UCount = COALESCE(UCount,0) + 1 
    WHERE [name] in (
        SELECT I.[name]
        FROM Inserted I
    );
END;

但是,如果您使用的是第二张桌子,那么这应该可以:

BEGIN
    UPDATE OTHERTAB SET
      UCount = COALESCE((SELECT UCount+1 from OTHERTAB T2 WHERE T2.[name] = OTHERTAB.[name]),0) 
    WHERE [name] in (
        SELECT I.[name]
        FROM Inserted I
    );
END;

【讨论】:

    【解决方案2】:

    使用inserted 和基于集合的方法(不需要循环):

    CREATE TRIGGER trg
    ON updates
    AFTER INSERT
    AS
    BEGIN
      INSERT INTO tab2(name)
      SELECT name
      FROM inserted;
    END
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-01
      • 2018-05-24
      • 2013-12-11
      • 1970-01-01
      • 2020-12-31
      相关资源
      最近更新 更多