[MSSQL] Trigger

0

Mam tabelę (bezsensowną, stworzoną tylko dla przykładu i celów edukacyjnych ;)) - 3 kolumny (a, b, wynik). Chcę aby A i B były zsumowane i wyświetlone w kolumnie wynik. Mam taki trigger:

CREATE TRIGGER [dbo].[SUMUJ]
ON [dbo].[Dodawanie]
FOR INSERT
AS

DECLARE @a int
DECLARE @b int
DECLARE @wynik int
SELECT @a = (select a from inserted)
SELECT @b = (select b from inserted)
SELECT @wynik = (@a + @b)

Teraz nie wiem jakim poleceniem czy tez sposobem umieścić wartość @wynik w kolumnie Wynik. Próbowałem po prostu dodać instrukcję Insert, ale efekt był inny od zamierzonego :(

pzdr.

0

Przydalby sie jakis identyfikator wierszy (klucz glowny), zeby mozna bylo rozpoznac, ktore wiersze (wyniki) aktualizowac. Pamietaj, ze taki trigger dziala po tym jak juz dane sa wrzucone. Mozesz zrobic na przyklad cos takiego.

CREATE TRIGGER [dbo].[SUMUJ]
ON [dbo].[Dodawanie]
FOR INSERT
AS

update dodawanie set wynik = a+b where id in (select id from inserted)

Wiem, ze to hipotetyczna tabela, ale pamietaj, ze takie rozwiazanie (kolumna zalezna od dwoch pozostalych) to zazwyczaj zbedna redundancja.

0

Witam

Nie chce mi się wierzyć, że nie ma możwliości w MSSQL zrobienia tego w normalniejszy sposób niż wykonywanie update'a w triggerze ?

W większości SZDB w triggerze jest dostęp do dodawanego/aktualizowanego rekordu, więc wystarczy zrobić trigger on insert, update i dać w nim

NEW.wynik = NEW.a + NEW.b

Ale MSSQL'a nie znam wcale więc się mogę mylić.

0

A dlaczego to nie jest normalny sposob? Tu jest oczywiste postepowanie: masz tabele wlasciwa z dodanymi juz wierszami i tabele inserted tylko z tymi wierszami, ktore zostaly dodane. I teraz wolnoc Tomku w swoim domku, rob z nimi co chcesz, ale korzystajac z polecen sql, jak to na baze przystalo...

0

To ja chyba czegoś nie rozumiem ... Pytanie dotyczy 1 tabeli czy 2 ? Jeśli jest to 1 tabela z 3 kolumnami, to mój sposób z oczywistych względów będzie najlepszy. Nie ma sesnu wykonywać update'a bo to niepotrzebnie konsumuje zasoby, już pomijam fakt, że jak zrobisz trigger'a na tabeli dla UPDATE, i w niej na niej samej robisz UPDATE, to mogą być różne efekty.
Zresztą takie pole to najlepiej zrobić jako kalkulowane i się będzie obliczać samo.

Jeśli rzecz dotyczy 2 tabel, to nie przejmujcie się tym co napisałem : )

0
  1. Moze i bedzie najlepszy, ale dla mnie mija sie z idea sql. To takie pojscie na skroty. Jestem ciekaw jak w takim wypadku zadziala ta 'wiekszosc szdb' tak naprawde - czy nie bedzie zmuszona tak czy inaczej zupdatetowac wartosci w tabeli? Bo przeciez do tego sie do podstawienie sprowadza.

  2. To trigger dla inserta, nikt nie mowil o trigerze dla update - choc wygladalby podobnie, ale nie jestem pewien co z zapetleniem

  3. Co do sensu istnienia takiego pola w jednej tabeli to juz pisalem ;)

0
johny_bravo napisał(a)
  1. Moze i bedzie najlepszy, ale dla mnie mija sie z idea sql. To takie pojscie na skroty.

No nie wiem, nie jestem ekspertem, ale wydaje mi się że ta moja opcja jest słuszna. Poza tym nie nazwał bym tego pójściem na skróty lecz wybraniem, szybszego, czytelniejszego, bardziej zwięzłego, logiczniejszego rozwiązania. Dodam że dla mnie użycie trigerrów w sposób jaki to pokazałem jest właśnie czystą ide'ą SQL - jest wykorzystaniem trigger'a zgodnie z jego przeznaczeniem. Po to są w nim właśnie dostępne wartości NEW i OLD.

johny_bravo napisał(a)

Jestem ciekaw jak w takim wypadku zadziala ta 'wiekszosc szdb' tak naprawde - czy nie bedzie zmuszona tak czy inaczej zupdatetowac wartosci w tabeli? Bo przeciez do tego sie do podstawienie sprowadza.

Mi się zdaje, że jak przy dodawaniu/edycji rekordów system odpala trigger'y to one operują na danych przed dodaniem, a nie na tej zadadzie, że doda a potem robi update na tej tabeli.

johny_bravo napisał(a)
  1. To trigger dla inserta, nikt nie mowil o trigerze dla update - choc wygladalby podobnie, ale nie jestem pewien co z zapetleniem

Głowy nie daje, ale takie zapętlenie może wystąpić. Ogólnie może to doprowadzić do czegoś zwanego zdajesie mutacją tabeli.

0
b0bik napisał(a)

Mi się zdaje, że jak przy dodawaniu/edycji rekordów system odpala trigger'y to one operują na danych przed dodaniem, a nie na tej zadadzie, że doda a potem robi update na tej tabeli.

W mssql dane sa najpierw dodawane, pozniej odpalany trigger - chyba, ze to trigger typu instead of, wtedy zastepujemy domyslne wstawianie, ale nie pamietam czy w mssql taki typ jest.

A ogolnie to chodzilo mi o to czy w przypadku update'a i Twojej 'sztuczki' efekt i wykonanie nie jest identyczne? Baza i tak musi zaktualizowac dane w tabeli - wiec 'zasobozernosc' bedzie taka sama. Kwestia tylko 'mnemonicznosci' Twojego rozwiazania.

0
johny_bravo napisał(a)

W mssql dane sa najpierw dodawane, pozniej odpalany trigger - chyba, ze to trigger typu instead of, wtedy zastepujemy domyslne wstawianie, ale nie pamietam czy w mssql taki typ jest.

Jak mówiłem MSSQL'a nie znam, ale wydaje mi się że to troche dziwne. Bo jak jest w przypadku, jeśli trigger jest BEFORE INSERT, i np poprawia jakieś dane ? albo nadaje polu ID wartość z generatora ? przecieŻ constraint'y nie pozwolą dodać rekordu z NULL'em w polu PRIMARY KEY. Ale nie będę się kłócić, bo to jest tylko gdybanie.

Kropka - ide do domu : )

0

Takiego nie ma w mssql, wiec mozna uzyc instead of i samemu sobie dodac jak juz wszystko sie sprawdzi co tam sie chce.

A poza tym to chyba schodzimy z tematu ;)

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