Триггер SQL после удаления для работы с удалением нескольких строк - PullRequest
1 голос
/ 12 августа 2011

У меня есть таблица со столбцом «порядок», который должен поддерживать непрерывный диапазон уникальных чисел. Я пытаюсь создать триггер, который срабатывает после удаления строк, который обновляет столбец «порядок», так что числа остаются смежными.

Я знаю, что многие люди будут утверждать, что столбец "order" должен быть только непрерывным, а не непрерывным, однако существует много интерфейсного 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

1 Ответ

3 голосов
/ 12 августа 2011

Перепишите свой интерфейс. Предпочитать тратить больше времени на разработку за меньшее время выполнения .

Сохранение непрерывности столбца заказа путем обновления всех неупорядоченных строк в таблице крайне неэффективно (удалить элемент 1 => обновить 100000000элементы), приводящие к потенциально огромным операциям обновления, приведут к огромному конфликту, потому что обновления изменяют много строк, так что они удовлетворяют почти при любом чтении, и, в конечном счете, некорректно при параллельности (вы получите пробелыи перекрывается в любом случае ).Не делай этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...