触发多个更新

时间:2014-01-27 16:42:01

标签: sql sql-server triggers

当记录更新时,会发生一个触发器,它会分配新记录,一个重要的生成号码(通过存储过程)。

工作正常。

但是,如果批量更新记录,INSERTED表不仅包含触发器无法处理的一条记录。

如何循环或sql语句,将计算值应用于每个INSERTED(更新)行。

SELECT @id = id FROM INSERTED --  Could contain multiple rows, but (wrongly) only applies to one

IF (@id IS NOT NULL)
BEGIN
    DECLARE @No bigint
    EXEC assignNo @No = @No OUTPUT

    UPDATE myTable SET No = @No
    WHERE id = @id
END

2 个答案:

答案 0 :(得分:4)

以下是我试图通过我的质疑来解决的问题。如果您的中央IDENTITY生成器有一个额外的无用列,这可以避免插入DEFAULT VALUES的行,difficult, cumbersome and downright unintuitive to do with more than one row(也许不可能在SQL Server 2005上)。因此,假装此生成器表如下所示:

CREATE TABLE dbo.OtherTable(OtherTableID INT IDENTITY(1,1), UselessColumn BIT);

你插入的真实表格如下:

CREATE TABLE dbo.MyTable(ID INT IDENTITY(1,1), [No] INT, foo VARCHAR(32));

我们可以创建一个INSTEAD OF INSERT触发器,将多行插入dbo.OtherTable,捕获生成的IDENTITY值的,然后最终将这些值与实际数据,将每个生成的值任意分配给一行。

CREATE TRIGGER dbo.trMyTable
ON dbo.MyTable
INSTEAD OF INSERT
AS
BEGIN
  SET NOCOUNT ON;

  DECLARE @newIDs TABLE(ID INT IDENTITY(1,1), [No] INT);

  INSERT dbo.OtherTable(UselessColumn) 
  OUTPUT inserted.OtherTableID INTO @newIDs([No])
  SELECT NULL FROM inserted;

  INSERT dbo.MyTable([No],foo)
  SELECT n.[No], i.foo FROM @newIDs AS n 
  INNER JOIN 
  (
    SELECT *, rn = ROW_NUMBER() OVER (ORDER BY foo) FROM inserted
  ) AS i ON i.rn = n.ID;
END
GO

INSTEAD OF INSERT触发器更好的原因是因为它避免了双重操作(插入一堆行,然后全部更新)。显然,您的列数多于foo;这只是一个简单的演示。

如果您还需要对批量更新执行类似的操作,则必须更新具有更多要求的问题(并包括诸如目标表上的主键之类的信息)。

答案 1 :(得分:0)

这是我的解决方案。

我使用otherTable中的IDs插入我的INSERTED以生成数字。另外,我附加了一个datetime字符串,使其更加独特,因为单独搜索id在此表中并不是唯一的。

然后,我使用myTable中的IDs更新INSERTED,并使用唯一No + {在otherTable中找到最大id {1}}字符串标识符。这将被分配到正确的记录,并在批量插入/更新中工作。

datetime