[MSSQL2005] Trigger AFTER INSERT, czy INSTEAD OF?

0

Cześć, mam problem jak poniżej. Zaznaczam, że niebywale zależy mi na optymalizacji.

Więc jest sobie tabela events.
Dla ułatwienia powiedzmy, że zawiera 3 pola: ID(klucz główny), spr i ignored.

Zaznaczam, że taka struktura jest tylko dla ułatwienia, w rzeczywistości wygląda inaczej i nie mogę zastosować klucza głównego na kilku kolumnach.

Teraz, jeśli robię insert do tej tabeli, muszę zorientować się, czy jest już taki rekord, który ma wartość w polu SPR taką samą, jak właśnie wstawiany. Jeśli ma, to wstawianemu rekordowi muszę ustawić pole ignored = 1, jeśli nie ma, to ignored = 0.

Myślałem nad użyciem triggerów, jednakże MSSQL 2005 niestety nie ma triggera BEFORE INSERT.
Więc zostaje mi AFTER INSERT lub INSETAD OF.

I teraz jeśli użyję AFTER INSERT to muszę znać ID wstawionego rekordu. Rozumiem, że z poziomu triggera mogę je pobrać za pomocą zmiennej @@IDENTITY, tak?

Następnie musiałbym wykonać update na tabeli events, żeby zmienić pole ignored.

Jeśli chciałbym użyć trigger insetad of, musiałbym stworzyć jeszcze jedną tabelę. Np: PRE_EVENTS i na tej tabeli założyć trigger.'

Teraz jeśli ktoś robi insert na PRE_EVENTS, porównuję go z zawartością tabeli events i robię insert do tabeli events z odpowiednią wartością pola IGNORED.

Rozwiązanie mojego problemu widzę właśnie w taki sposób.

Oczywiście mogę to zrobić w procedurze składowanej JAKOŚ(a i tak będę musiał taką procedurę napisać), tylko to się wiąże chyba ze sprawdzaniem każdego rekordu z każdym rekordem.
Procedurę muszę mieć po to, żeby móc wykonać operację w dowolnym momencie, nie tylko podczas insertu.

Tak więc pytanie jest następujące. Czy dobrze myślę? Która opcja triggera będzie lepsza? AFTER INSERT, czy INSTEAD OF?

0

a nie może być

insert into events(spr, ignored) select wstawiana_wartosc_spr, case count(*)  when 0 then 0 else 1 end from events where wstawiana_wartosc_spr = spr
0
Misiekd napisał(a)

a nie może być

insert into events(spr, ignored) select wstawiana_wartosc_spr, case count(*)  when 0 then 0 else 1 end from events where wstawiana_wartosc_spr = spr

Nie może, bo insert do tej tabeli ma być jak najprostszy. Jest to związane z pewnymi założeniami.

0
ALTER TRIGGER EventsSpr
ON dbo.Events
AFTER INSERT
AS
  UPDATE dbo.Events
  SET ignored = 1
  FROM inserted i
  WHERE i.spr in (SELECT e.spr FROM dbo.Events e WHERE e.ID <> i.ID)
  AND i.ID = dbo.Events.ID;
0
AdamPL napisał(a)
ALTER TRIGGER EventsSpr
ON dbo.Events
AFTER INSERT
AS
  UPDATE dbo.Events
  SET ignored = 1
  FROM inserted i
  WHERE i.spr in (SELECT e.spr FROM dbo.Events e WHERE e.ID <> i.ID)
  AND i.ID = dbo.Events.ID;

No tak właśnie robię.
Tylko doszedłem do pewnych wniosków. Jako, że mój przykład był dużym uproszczeniem, okazuje się, że jeśli jest robiony hurtowy insert(np. insert z select), wtedy muszę utworzyć kursor z danymi z tabeli inserted. I pytanie, czy zabronić hurtowych insertów, czy utworzyć kursor? Oczywiście szybkość przede wszystkim.

0

Jeżeli w hurtowym insercie mogą się zdarzać wpisy z powtarzającymi się spr to wystarczy zmienić kod w ten sposób:

ALTER TRIGGER [dbo].[EventsSpr]
ON [dbo].[Events]
AFTER INSERT
AS
  UPDATE dbo.Events
  SET ignored = 1
  FROM inserted i
  WHERE i.spr in (SELECT e.spr FROM dbo.Events e WHERE e.ID < i.ID)
  AND i.ID = dbo.Events.ID;

0 użytkowników online, w tym zalogowanych: 0, gości: 0