2013-05-18 10 views
8

Ok. Jestem całkiem nowy w wyzwalaczach SQL i miałem z nimi problemy. Wstaw spust działa dobrze, a także spust Usuń. Na początku usuwanie w wielu wierszach usuwa tylko jeden, ale udało mi się go sobie wyobrazić :)Aktualizacja wyzwalacza SQL wielokrotnego rzędu z pojedynczej aktualizacji instrukcji SQL

Jednak nawet po intensywnych poszukiwaniach (tutaj i w Google) nie mogę znaleźć zadowalającej odpowiedzi do wyzwalacza UPDATE, który mam. Jeśli wykonam aktualizację, taką jak

UPDATE Customers Set CustomerUser = 0 Where CustomerStatus = 3 

Wówczas niestety zaktualizowany zostanie tylko jeden rekord, a drugi pozostanie niezmieniony. Oczywiście, nie jest to dobre.

Spust używam jest:

ALTER TRIGGER [dbo].[TRG_TriggerName] ON [dbo].[USER_Customers] 

FOR UPDATE 

AS 
declare @customerid int; 
declare @customervenue int; 
declare @customeruser int; 
declare @customerarea int; 
declare @customerevent int; 
declare @customerproject int; 
declare @customerstatus int; 

select @customerid=i.CustomerID from inserted i; 
select @customervenue=i.CustomerVenue from inserted i; 
select @customerarea=i.CustomerArea from inserted i; 
select @customerevent=i.CustomerEvent from inserted i; 
select @customerproject=i.CustomerProject from inserted i; 
select @customeruser=i.CustomerUser from inserted i; 
select @customerstatus=i.CustomerStatus from inserted i; 

Update USER_Instances Set InstanceArea = @customerarea, InstanceVenue = @customervenue, InstanceUser = @customeruser, InstanceStatus = @customerstatus, InstanceEvent = @customerevent, InstanceLastUpdate = GetDate() Where InstanceObject = 17 AND InstanceIdentity = @customerid 
GO 

Jak natychmiast zrealizować, to wyzwalacz jest wielki - jeśli chcesz zaktualizować tylko jeden rekord. W przeciwnym razie nie powiedzie się. Teraz - główne pytanie brzmi: - Jak złapać wszystkie rekordy, które wymagają aktualizacji, i zaktualizować je wszystkie za jednym razem.

Przykłady, które widziałem tutaj w Stack Overflow, mylą mnie lub wydają się nieskuteczne - na przykład wydaje się, że większość z nich zajmuje się aktualizowaniem JEDNEJ wartości w drugim/innym stole, a nie całą masą jak ja próbować zrobić. Te, które wydają się działać na wielu wartościach, nie mogę tego zrozumieć :(

Po około 2 godzinach poszukiwań poddaję się i mam nadzieję, że możesz mi pomóc :) Zdaję sobie sprawę, że jest to problem początkujący-początkujący i chociaż znam mój MS-SQL, wyzwalacze są czymś, czego nigdy nie używałem, aż do teraz. Tak więc każda pomoc jest bardzo mile widziane :) W

+0

Tabela "wstawione" może zawierać wiele wierszy. Radzę wszystkim, aby nie używali wyzwalaczy. Są zbyt trudne, aby je naprawić, a nawet jeśli sobie poradzisz, wynik jest bardzo trudny do utrzymania. – Andomar

+0

Cóż ... Teoretycznie mogę przeprowadzić aktualizację za pomocą instrukcji SQL po aktualizacji i tak długo jak INSERT i DELETE działają poprawnie, byłoby to możliwe drugie najlepsze rozwiązanie. Ale nadal bardzo chciałbym wiedzieć, jak zrobić to wyzwalanie w prawo ... Używam tylko jednego zestawu wyzwalaczy, ponieważ w tej sytuacji jest dokładnie to, czego potrzebuję i oferuje najlepsze rozwiązanie :) Dzięki za komentarz. – Irresistance

+0

@Irresistance Triggers są preferowanym rozwiązaniem z wielu powodów. Jak mówi Andromar, ciężko jest pisać i utrzymywać. Wpływają również negatywnie na wydajność INSERT, UPDATE i DELETE, powodują, że transakcje są bardziej skomplikowane, mogą zwiększać szansę na zakleszczenia i są prawdziwym bólem w zadaniach operacyjnych. Ale największym powodem jest to, że są one ukryte przed normalnym widokiem, dzięki czemu są skutecznie "magiczne". Wyzwalacze nieustannie wyszukują administratorów baz danych i deweloperów, ponieważ zapominają o nich, co skutkuje wieloma długimi, kłopotliwymi kwestiami wsparcia zakończonymi słowami "Czy ten stół ma jakieś wyzwalacze?" – RBarryYoung

Odpowiedz

13

Wydaje się, że trzeba coś takiego

ALTER TRIGGER [dbo].[TRG_TriggerName] ON [dbo].[USER_Customers] 
FOR UPDATE 
AS 
UPDATE USER_Instances 
    SET InstanceArea = i.CustomerArea, 
     InstanceVenue = i.CustomerVenue, 
     InstanceUser = i.CustomerUser, 
     InstanceStatus = i.CustomerStatus, 
     InstanceEvent = i.CustomerEvent, 
     InstanceLastUpdate = GetDate() 
    FROM USER_Instances JOIN inserted i 
    ON InstanceIdentity = i.CustomerID AND InstanceObject = 17 

Od inserted wirtualny tabela może zawierać wiele wierszy trzeba JOIN go prawidłowo wykonać UPDATE.

+0

You da man !! Właśnie tego potrzebowałem, a ja stawiam się za to, że nie wymyśliłem tego oczywistego i eleganckiego rozwiązania! – Irresistance

+0

@ peterm, Mam ten sam problem, proszę sprawdzić poniższy link http://stackoverflow.com/questions/26043106/how-to-determine-if-insert-or-update/26143185#26143185 – Prathyush