2011-08-12 121 views
1

我有一個「訂單」列,需要保持一個連續範圍的唯一號碼的表。我想創建的是一個觸發器,在刪除更新「order」列的行後觸發,以便數字保持連續。SQL刪除後刪除使用多行刪除

我知道很多人會爭辯說,「訂單」列只需要連續,而不是連續的,但是有很多前端JavaScript和其他SQL,用於訂購/重新排序依賴於爲了連續。我寧願簡單地讓這個觸發器工作,而不必重寫,當然我願意提供建議;)

觸發器我對單行刪除工作正常,但是當多行刪除發生時,只有第一行被刪除,剩下的沒有拋出錯誤。

我認爲這個問題可能是遞歸,因爲它更新了它從表中觸發的表,但它只是一個刪除觸發器,所以我不認爲這是問題所在。關閉RECURSIVE_TRIGGERS並未解決問題。

下面的代碼:

CREATE TABLE [dbo].[Item] 
(
[ItemID] INT NOT NULL IDENTITY(1, 1), 
[ItemOrder] INT NOT NULL, 
[ItemName] NVARCHAR (50) NOT NULL 
) 
GO 

SET QUOTED_IDENTIFIER ON 
GO 
SET ANSI_NULLS ON 
GO 

CREATE TRIGGER [dbo].[trItem_odr] ON [dbo].[Item] 
    AFTER DELETE 
AS 
    BEGIN 
     SET NOCOUNT ON ; 

     DECLARE @MinOrder INT 

     SELECT @MinOrder = MIN(ItemOrder) 
     FROM DELETED 

     DECLARE @UpdatedItems TABLE 
      (
      ID INT IDENTITY(0, 1) 
        PRIMARY KEY, 
      ItemID INT 
      ) 

     INSERT INTO @UpdatedItems (ItemID) 
       SELECT ItemID 
       FROM dbo.Item 
       WHERE ItemOrder > @MinOrder 
         AND ItemID NOT IN (SELECT ItemID 
              FROM  DELETED) 
       ORDER BY ItemOrder 


     UPDATE dbo.Item 
     SET  ItemOrder = (SELECT ID + @MinOrder 
          FROM @UpdatedItems 
          WHERE ItemID = Item.ItemID) 
     WHERE ItemID IN (SELECT ItemID 
          FROM  @UpdatedItems) 

    END 
GO 

ALTER TABLE [dbo].[Item] ADD CONSTRAINT [PK_Item] PRIMARY KEY CLUSTERED ([ItemID]) 
GO 
ALTER TABLE [dbo].[Item] ADD CONSTRAINT [IX_Item_1] UNIQUE NONCLUSTERED ([ItemName]) 
GO 
CREATE UNIQUE NONCLUSTERED INDEX [IX_Item_2] ON [dbo].[Item] ([ItemOrder]) 
GO 

INSERT INTO [dbo].[Item] ([ItemOrder], [ItemName]) 
SELECT 1, N'King Size Bed' UNION ALL 
SELECT 2, N'Queen size bed' UNION ALL 
SELECT 3, N'Double Bed' UNION ALL 
SELECT 4, N'Single Bed' UNION ALL 
SELECT 5, N'Filing Cabinet' UNION ALL 
SELECT 6, N'Washing Machine' UNION ALL 
SELECT 7, N'2 Seater Couch' UNION ALL 
SELECT 8, N'3 Seater Couch' UNION ALL 
SELECT 9, N'1 Seater Couch' UNION ALL 
SELECT 10, N'Flat Screen TV' UNION ALL 
SELECT 11, N'Fridge' UNION ALL 
SELECT 12, N'Dishwasher' UNION ALL 
SELECT 13, N'4 Seater couch' UNION ALL 
SELECT 14, N'Lawn Mower' UNION ALL 
SELECT 15, N'Dining table' 
GO 

回答

3

重寫你的前端。 傾向於交易更多的開發時間以減少運行時間

通過更新表中所有亂序行來保持訂單列的連續性是非常低效的(移除項目1 =>更新100000000個項目)導致潛在的巨大更新操作,將產生巨大的爭用,因爲更新修改一個很多行,所以他們滿足幾乎所有的讀取,並最終,在併發下不正確(你最終會有差距和重疊無論如何)。不要這樣做。

+0

確實很好。這張桌子從來沒有預計會有超過200排左右的排,所以沒有想到嘎吱嘎吱會太糟糕。我同意這不是一個好的做法,並且比它的價值更麻煩,thx。 – Ruxta