【问题标题】:How to write trigger for multiple row update?如何为多行更新编写触发器?
【发布时间】:2012-02-29 04:59:14
【问题描述】:

我编写了一个更新触发器,当我只更新一行时它可以正常工作,但当我更新多行时会出错。

错误:

消息 512,级别 16,状态 1,过程 Sale_OnUpdate,第 14 行子查询返回超过 1 个值。 当子查询跟随 =、!=、、>= 或子查询用作表达式时,这是不允许的。

这里是触发器

ALTER  TRIGGER [dbo].[Sale_OnUpdate]    ON  [dbo].[Sale] 
   AFTER Update

AS 
Declare @ID as decimal
Declare @User as varchar(250)
Declare @Status as varchar(250)

set @ID = (Select ID from Inserted)
set @User = (Select UpdatedByUser from Inserted)
set @Status = Isnull((Select Status from Inserted),'')

BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

   INSERT INTO [dbo].[Log]
           (
           [RecordID]
           ,[Date]
           ,[Time]
           ,[UserName]
           ,[TableName]
           ,[Action]
           )
     VALUES
           (
           @ID
           ,GetDate()
           ,GetDate()
           ,@User
           ,'Sale'
           ,'Update,' + @Status
           )
END

我应该做些什么改变使它适用于多行。

【问题讨论】:

    标签: sql sql-server sql-server-2008 tsql triggers


    【解决方案1】:
    ALTER  TRIGGER [dbo].[Sale_OnUpdate]    ON  [dbo].[Sale] 
       AFTER Update
    AS 
    BEGIN
        -- SET NOCOUNT ON added to prevent extra result sets from
        -- interfering with SELECT statements.
        SET NOCOUNT ON;
    
       INSERT INTO [dbo].[Log]
               (
               [RecordID]
               ,[Date]
               ,[Time]
               ,[UserName]
               ,[TableName]
               ,[Action]
               )
         SELECT
               ID
               ,GetDate()
               ,GetDate()
               ,UpdatedByUser
               ,'Sale'
               ,'Update,' + Isnull(Status,'')
         from Inserted
    END
    

    【讨论】:

    • 但我想记录这三个字段(ID、用户、状态)。
    • @MujassirNasir 这正是修改后的触发器的作用(除了使用 UpdatedByUser 而不是 User,如您原来的问题中所述)。仔细检查 SELECT 子句。
    【解决方案2】:

    试试这个

    ALTER TRIGGER [dbo].[Sale_OnUpdate] ON [dbo].[Sale] 
      AFTER Update
    
    AS 
    as 
    if update (qty) 
    
    
    BEGIN
      -- SET NOCOUNT ON added to prevent extra result sets from interfering with SELECT statements.
      SET NOCOUNT ON;
    /* check value of @@rowcount */ 
        if @@rowcount = 1 
    
      INSERT INTO [dbo].[Log]
        ([RecordID]
       , [Date]
       , [Time]
       , [UserName]
       , [TableName]
       , [Action])
      SELECT id,
             GETDATE(),
             GETDATE(),
             updatedbyuser,
             'Sale',
             'Update,' + ISNULL(status, '')
    
        else
        /* when rowcount is greater than 1, 
           use a group by clause */ 
        begin 
        INSERT INTO [dbo].[Log]
        ([RecordID]
       , [Date]
       , [Time]
       , [UserName]
       , [TableName]
       , [Action])
      SELECT i.id,
             GETDATE(),
             GETDATE(),
             i.updatedbyuser,
             'Sale',
             'Update,' + ISNULL(i.status, '')
        FROM INSERTED i
        and inserted.title_id = deleted.title_id
       end
    
    END
    

    【讨论】:

      【解决方案3】:

      用途:

      ALTER TRIGGER [dbo].[Sale_OnUpdate] ON [dbo].[Sale] 
        AFTER Update
      
      AS 
      
      BEGIN
        -- SET NOCOUNT ON added to prevent extra result sets from interfering with SELECT statements.
        SET NOCOUNT ON;
      
        INSERT INTO [dbo].[Log]
          ([RecordID]
         , [Date]
         , [Time]
         , [UserName]
         , [TableName]
         , [Action])
        SELECT i.id,
               GETDATE(),
               GETDATE(),
               i.updatedbyuser,
               'Sale',
               'Update,' + ISNULL(i.status, '')
          FROM INSERTED i
      
      END
      

      【讨论】:

      • 但我想记录这三个字段(ID、用户、状态)。
      • @MujassirNasir:那不是你的问题。
      • 我试过了,我知道它有效,但我想写触发器来记录每一个动作。
      • @MujassirNasir:据我所知,提出单独的问题没有限制。
      • @MujassirNasir:你所说的“每一个动作”是什么意思? OMGPonis 触发器记录的记录数与 Sales 中更新的记录数相同。这不是你需要的吗?
      【解决方案4】:

      我也有类似的问题,这里的想法是INSERTED表有很多记录,所以如果你想分析每个值,你需要通过示例使用游标来迭代表:

      Loop through INSERTED table

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多