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

问题描述 投票:1回答:1

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

我需要执行一个存储过程,该存储过程返回要插入column2的值。每次执行时,存储过程都会返回一个不同的值(密码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
sql sql-server loops tsql sql-server-2017
1个回答
1
投票

尝试一下:

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
    );

    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

© www.soinside.com 2019 - 2024. All rights reserved.