【问题标题】:Execute a stored procedure to update each row before inserting在插入之前执行存储过程以更新每一行
【发布时间】:2019-10-11 05:17:51
【问题描述】:

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

我需要执行一个存储过程,该过程返回要插入 column2 的值。
存储过程每次执行都会返回不同的值(crypto 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

【问题讨论】:

  • 所以...这个存储过程在每次执行时都会生成一个值,对吗?如果是这样,您可能应该寻找一种更改它的方法,以便它生成多个值并将它们作为表返回。顺便说一句,AFAIK,插入的伪表是只读的。

标签: sql sql-server loops tsql sql-server-2017


【解决方案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
    );

    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

【讨论】:

  • 当你忙着写这个答案时,我正在想办法接受你的建议,哈哈。我摆脱了存储过程,我将直接在 INSERT:SELECT 语句中生成值,没有循环。
  • 您的临时表永远不会有行,因此循环永远不会运行。你忘了填充它吗?你继承了 OP 代码中的错误——变量 i 永远不会改变,因为它没有“OUTPUT”限定符。您还添加了一个不明显的假设 - 插入的行数将始终小于 256(因为 tinyint)。
猜你喜欢
  • 2012-10-13
  • 1970-01-01
  • 1970-01-01
  • 2017-03-28
  • 2014-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多