Я пытаюсь развернуть свою голову вокруг триггера ПОСЛЕ ОБНОВЛЕНИЯ.After Update Trigger puzzlement
В настоящее время в нашей БД есть триггер, содержащий курсор. По моему мнению, курсоры в триггерах обычно плохо работают, поэтому я пытаюсь избавиться от курсора.
В настоящее время запуска выглядит следующим образом:
ALTER TRIGGER [dbo].[trg_TaskMovement_Zone] ON [dbo].[Tasks_Movement]
AFTER INSERT, UPDATE
AS
BEGIN
SET NOCOUNT ON
DECLARE @rowcheck int
DECLARE @MovementID INT
DECLARE @SiteFromID INT
DECLARE @SiteToID INT
DECLARE @SiteResponsibleID INT
DECLARE @FromAddress_Postcode Varchar(20)
DECLARE @ToAddress_Postcode Varchar(20)
DECLARE zcursor CURSOR FOR SELECT ID, SiteFromID, SiteToID, SiteResponsibleID
, FromAddress_Postcode, ToAddress_Postcode FROM inserted
OPEN zcursor
SELECT @rowcheck=1
WHILE @rowcheck=1
BEGIN
FETCH NEXT FROM zcursor INTO @MovementID, @SiteFromID, @SiteToID, @SiteResponsibleID, @FromAddress_Postcode, @ToAddress_Postcode
IF (@@FETCH_STATUS = 0)
BEGIN
UPDATE Tasks_Movement
SET ZoneFromID = dbo.fn_GetZoneFromPostcode(@FromAddress_Postcode),
ZoneToID = dbo.fn_GetZoneFromPostcode(@ToAddress_Postcode)
WHERE Tasks_Movement.ID = @MovementID
UPDATE Tasks_Movement
SET SiteResponsibleID = [dbo].[fn_GetDefaultDepotResponsibleForSite](@SiteFromID)
WHERE Tasks_Movement.ID = @MovementID
AND (@SiteResponsibleID Is NULL OR @SiteResponsibleID=0)
AND (@SiteFromID Is NOT NULL AND @SiteFromID>0)
UPDATE Tasks_Movement
SET SiteResponsibleID = [dbo].[fn_GetDefaultDepotResponsibleForSite](@SiteToID)
WHERE Tasks_Movement.ID = @MovementID
AND (@SiteResponsibleID Is NULL OR @SiteResponsibleID=0)
AND (@SiteToID Is NOT NULL AND @SiteToID>0)
END
ELSE
SELECT @rowcheck=0
END
CLOSE zcursor
DEALLOCATE zcursor
END
Из того, что я могу сказать, курсор в это совершенно не нужно
Я был бы прав, считая, что следующий будет работать лучше (?):
ALTER TRIGGER [dbo].[trg_TaskMovement_Zone] ON [dbo].[Tasks_Movement]
AFTER INSERT, UPDATE
AS
BEGIN
SET NOCOUNT ON
UPDATE Tasks_Movement
SET ZoneFromID = dbo.fn_GetZoneFromPostcode(inserted.FromAddress_Postcode),
ZoneToID = dbo.fn_GetZoneFromPostcode(inserted.ToAddress_Postcode)
FROM inserted
WHERE Tasks_Movement.ID IN (SELECT id FROM inserted)
UPDATE Tasks_Movement
SET SiteResponsibleID = [dbo].[fn_GetDefaultDepotResponsibleForSite](inserted.SiteFromID)
FROM inserted
WHERE Tasks_Movement.ID IN (SELECT id FROM inserted
WHERE (inserted.SiteResponsibleID Is NULL OR inserted.SiteResponsibleID=0)
AND (inserted.SiteFromID Is NOT NULL AND inserted.SiteFromID>0))
UPDATE Tasks_Movement
SET SiteResponsibleID = [dbo].[fn_GetDefaultDepotResponsibleForSite](@SiteToID)
FROM inserted
WHERE Tasks_Movement.ID IN (SELECT id FROM inserted
WHERE (inserted.SiteResponsibleID Is NULL OR inserted.SiteResponsibleID=0)
AND (inserted.SiteToID Is NOT NULL AND inserted.SiteToID>0))
END
Пожалуйста, сообщите нам, что ** конкретная система баз данных ** это для - многие вещи зависят от поставщика. Вы используете MySQL? Postgres? SQL Server? Oracle? IBM DB2? Что-то еще? Обновите свои теги, чтобы показать, какую систему баз данных (и какую версию!) Вы используете - спасибо! –
Извините marc ... Это для SQL Server. Я обновил теги сейчас. – MrDaveM
Подход курсора медленный, когда вы переходите через большой набор строк. В вашем случае у вас есть только вставленная строка, поэтому удаление курсора не является проблемой. – NoChance