如何在更新触发器中插入?

时间:2017-11-11 10:39:13

标签: sql sql-server

我有一个UPDATE触发器,当一个记录插入表中但希望在触发触发器的同时创建INSERT时发生。

原始INSERT将记录放入BatchQueue表中,当发生这种情况时,将触发触发器以更新第二个表[Call]。

我希望能够在BatchQueue表中添加一条记录,该记录与插入的初始记录基本相似,但在时间列和另一列上有所不同。我可以在原始插入物上进行技术操作但是需要做一个WHEN或IF,仅当SFlags = 11

原始INSERT语句:

BEGIN
    INSERT INTO BatchQueue (TimeToExecute, Operation, 
    Parameter,RuleID, FilterID, SFlags)
        SELECT @TimeToExecute, @Operation, @Parameter, @RuleID, @FilterID, 
        @SFlags FROM Call WHERE [ID]=@Parameter AND Active=0
               AND (OnlineCount>0 OR OnlineScreenCount>0 
       OR (Flags&POWER(2,26)=POWER(2,26)))  
 END

这是我想要的插页:

BEGIN
   INSERT INTO [dbo].[BatchQueue]
   VALUES(DateAdd(mi,2,getutcdate()),1,Call.ID,2,null,9,0,0,0)
   WHEN Call.SFlags = 11
END

触发声明:

BEGIN
IF @@ROWCOUNT > 0
BEGIN
   SET NOCOUNT ON
   UPDATE Call SET StoreReqCount = StoreReqCount + CallCount.actionCount
   FROM Call, (SELECT Parameter, [actionCount] = COUNT(*) FROM inserted 
   GROUP BY Parameter ) AS CallCount
   WHERE Call.ID = CallCount.Parameter
END

有人可以建议如何做到最好吗?我希望我澄清了。重申一下,要么将第二个INSERT添加到第一个INSERT,条件为SFlags = 11,要么使用触发器插入。哪个更好?

编辑:

尝试以下方法:

   SELECT @StoreActionID = [ID] FROM BatchQueue 
   WHERE Parameter=@Parameter AND RuleID=@RuleID AND 
    SFlags=@SFlags
   IF @StoreActionID IS NOT NULL
   BEGIN
     UPDATE BatchQueue SET FilterID = @FilterID WHERE [ID] = 
     @StoreActionID
   END
ELSE
BEGIN
   INSERT INTO BatchQueue (TimeToExecute, Operation, Parameter, 
      RuleID, FilterID, SFlags)
        SELECT @TimeToExecute, @Operation, @Parameter, @RuleID, 
     @FilterID, @SFlags FROM Call WHERE [ID]=@Parameter AND Active=0
               AND (OnlineCount>0 OR OnlineScreenCount>0 OR 
     (Flags&POWER(2,26)=POWER(2,26))) --bit26 indicates META-DATA-ONLY
END
-- ADDED ADDITIONAL INSERT TO INSERT ACTION BASED ON STOREFLAGS 
BEGIN
    IF @SFlags = 11
    BEGIN 
        INSERT INTO BatchQueue (TimeToExecute, Operation, Parameter, 
        RuleID, FilterID, SFlags)
        SELECT @TimeToExecute, @Operation, @Parameter, @RuleID, 
        @FilterID, 9 FROM Call WHERE [ID]=@Parameter AND Active=0
               AND (OnlineCount>0 OR OnlineScreenCount>0 OR 
        (Flags&POWER(2,26)=POWER(2,26))) --bit26 indicates META-DATA-ONLY
    END        
END

1 个答案:

答案 0 :(得分:1)

您可以采取的一个好选择是编写存储过程,并在存储过程中包含原始INSERT语句,然后将特殊INSERT插入到与第一个INSERT相同的表中。但是,只有在第一次INSERT成功时才执行特殊的INSERT。

让UPDATE通过您现有的触发器发生。如果成功使用它,您不希望打扰触发器。

此外,如果您可以在事务中包装这两个INSERT语句,那将是一件好事。

这将满足您的要求。

将以下T-SQL代码放入存储的文件中

SET NOCOUNT ON;
BEGIN TRY

 Declare @insertedID int;

  --original INSERT
  INSERT INTO BatchQueue (TimeToExecute, Operation,
  Parameter, RuleID, FilterID, SFlags)
    SELECT
      @TimeToExecute,
      @Operation,
      @Parameter,
      @RuleID,
      @FilterID,
      @SFlags
    FROM Call
    WHERE [ID] = @Parameter
    AND Active = 0
    AND (OnlineCount > 0
    OR OnlineScreenCount > 0
    OR (Flags & POWER(2, 26) = POWER(2, 26));

  Set @insertedID = scope_identity() ;

  ---- INSERT if a row is successfully inserted
  IF @@ROWCOUNT > 0
  BEGIN

    INSERT INTO [dbo].[BatchQueue]
      SELECT DATEADD(mi, 2, GETUTCDATE()), 1, @parameter, 2, NULL, 9, 0, 0, 0)  
      WHERE @SFlags = 11;

  END

  --commit tran
  IF @@trancount > 0
  BEGIN
    COMMIT TRAN
  END

END TRY

BEGIN CATCH
  --get error details, which you can log to some table
  DECLARE @ErrorMessage nvarchar(4000);
  DECLARE @ErrorSeverity int;
  DECLARE @ErrorState int;

  SELECT
    @ErrorMessage = ERROR_MESSAGE(),
    @ErrorSeverity = ERROR_SEVERITY(),
    @ErrorState = ERROR_STATE();

  --roll back tran
  IF @@trancount > 0
  BEGIN
    ROLLBACK TRAN
  END

END CATCH