在插入之前执行存储过程以更新每一行

Execute a stored procedure to update each row before inserting

我正在编写一个INSTEAD OF INSERT触发器来拦截插入的数据并填充column2。

我需要执行一个存储过程,将 returns 值插入 column2。
存储过程 returns 每次执行时都有不同的值(加密 prng)。

因此,如果有人插入 10 行,我的触发器应该执行存储过程 10 次,并用返回值之一填充每一行。

我听说游标应该很少用于这样的事情。
但我也不确定标准循环是否是最佳方法。

SELECTUPDATEINSERT 语句中是否有更简化的方法来完成此操作?

CREATE TRIGGER dbo.table1_instead_of_insert
ON dbo.table1
INSTEAD OF INSERT
AS BEGIN
    DECLARE @i BIGINT ;
    EXECUTE dbo.proc1 @1 ;
    --proc1 sets the value of @i to a different value each time proc1 is executed
    --(crypto prng)

    --Update the value of column2 in INSERTED, setting it to the value of @i

    --Repeat this process for each row in INSERTED,
      --with proc1 returning a different value for each row

    INSERT INTO dbo.table1 ( column1 , column2 )
        SELECT column1 , column2 FROM INSERTED ;
END
GO

试试这个:

CREATE TRIGGER dbo.table1_instead_of_insert
ON dbo.table1
INSTEAD OF INSERT
AS BEGIN

    CREATE TABLE #DataSource
    (
        [RowID] INT IDENTITY(1,1) 
       ,[Column1] VARCHAR(12) -- use your type
       ,[Column2] VARCHAR(12) -- use your type
    );

    INSERT INTO #DataSource ([Column1], [Column2])
    SELECT [Column1], [Column2]
    FROM inserted;

    DECLARE @RowID TINYINT = 1;
    DECLARE @i BIGINT ;

    WHILE(EXISTS(SELECT 1 FROM #DataSource WHERE [RowID] = @RowID))
    BEGIN;

         EXECUTE dbo.proc1 @i ;

         UPDATE #DataSource
         SET [Column2] = @i
         WHERE [RowID] = @RowID;

        SET @RowID = @RowID + 1;
    END;    

    INSERT INTO dbo.table1 ( column1 , column2 )
        SELECT column1 , column2 FROM #DataSource ;
END
GO

这很糟糕。很坏。它很容易扼杀你的表现。在执行大量插入的环境中,您将为每一行执行此存储过程。

对于数据库经验较少的开发人员来说,逐行处理是一种常见的做法。您应该尝试修改此存储过程,以便能够生成 @i 值的行 - 这样您就可以跳过循环。

你也应该检查 this link