SQL Server触发器更新和增量计数器

时间:2012-08-27 22:47:26

标签: sql sql-server database triggers

我有两张桌子。一个表中有一个字段,用于简单地保存一个计数器,另一个表有许多搜索字段,其中一个字段必须包含另一个表中的计数器值。

我正在尝试创建一个

的触发器
  1. 在第二个表中发生更新时,在第一个表中将值增加1
  2. 第一个表中的递增值将用于设置第二个表中的字段
  3. 1& 2仅在第二个表中发生更新且字段即Status等于特定值时才会发生。
  4. 处理1,2和3以获取多条记录。
  5. 1)我设法编写了这个触发器,但是a)它看起来非常慢而且b)我发现了一篇文章解释得相当不错,但正如例子所示,这只是一条记录。它确实提供了一个解决方案,如果更新了多个记录,但我的问题是如何处理每个记录的第一个表中的值递增,然后为每个记录更新每个单独的记录?

    知道为什么它很慢(好吧,使用sql server管理控制台)?

    我找到的文章可以在http://benreichelt.net/blog/2005/12/13/making-a-trigger-fire-on-column-change/

    中找到

    我根据这篇文章写的触发器如下:

    CREATE TRIGGER [dbo].[trig_DataTable] ON [dbo].[DataTable]
    FOR UPDATE
    AS
    IF UPDATE(Status)
    BEGIN
    SET NOCOUNT ON;
    
      DECLARE @newStatus NVARCHAR(50)
      DECLARE @oldStatus NVARCHAR(50)   
      DECLARE @maxRefNo INT
    
      DECLARE @id BIGINT
    
      SET @maxRefNo = (SELECT MAX(RefNo) FROM CounterTable) + 1
      UPDATE CounterTable SET RefNo = @maxRefNo
    
      SET @newStatus = (SELECT Status FROM Inserted)
      SET @oldStatus = (SELECT Status FROM Deleted)
    
      IF (@newStatus != @oldStatus) AND (@newStatus = 'Approved')
      BEGIN   
        SET @Id = (SELECT Id FROM Inserted)
        UPDATE DataTable
        SET UniqueRef = @maxRefNo
        WHERE Id = @Id
      END
    
    END
    

    关于上述问题,还有一个快速的问题!由于上述触发器仅适用于单个记录,我是否需要具有where部分?需要这个似乎没有意义。

    不是很重要因为我需要的是与上面相同的行为,但它需要处理它包含在INSERTED / DELETED表中的多个记录。

    我可以编写一个函数来获取下一个可用的数字并更新CounterTable,然后从类似的SQL中调用此函数,如文章中所述

    INSERT INTO PriceHistory(ItemId, OldPrice, NewPrice, UniqueRef)
     SELECT I.ItemId, D.Price, I.Price, dbo.GetNextRefNo()
     FROM INSERTED I INNER JOIN DELETED D ON I.ItemId = D.ItemId
     WHERE I.Price != D.Price
    

    我不确定是否诚实......我会在一秒钟内给出一个镜头,但如果你们中有任何人知道如何实现这一目标,请告诉我......会很棒!感谢。

    我希望上述内容有意义。

    干杯。

    吨。

1 个答案:

答案 0 :(得分:3)

使用以下查询:

CREATE TRIGGER [dbo].[trig_DataTable] ON [dbo].[DataTable]
FOR UPDATE
AS BEGIN
    SET NOCOUNT ON;
    DECLARE @maxRefNo INT
    DECLARE @id BIGINT

    SET @maxRefNo = ISNULL((SELECT MAX(RefNo) FROM CounterTable),0)

    UPDATE CounterTable 
    SET RefNo = @maxRefNo + (SELECT COUNT(*) 
                            FROM INSERTED A 
                            INNER JOIN DELETED D ON D.id=A.id
                            WHERE A.STATE = 'Approved'
                              AND A.STATE <> D.State)

    UPDATE DataTable
    SET UniqueRef = @maxRefNo + ROW_NUMBER() OVER (ORDER BY A.id)
    FROM INSERTED A
    INNER JOIN DELETED D ON D.id = A.id
    WHERE DataTable.Id = A.Id
        AND A.STATE = 'Approved'
        AND A.STATE <> D.State
END

当您编写触发器时,必须使用coneive触发器执行插入表中的多记录。没有人记录。