Serwisanci dostępni teraz · czynne całą dobę, także w weekendy i świętaWarszawa i okolice · dojazd bezpłatny
Darmowa diagnoza laptopa

Darmowa diagnoza laptopa

Dojazd do klienta bezpłatnie

Dojazd do klienta bezpłatnie

Laptopy zastępcze bezpłatnie

Laptopy zastępcze bezpłatnie

Odbiór i zwrot sprzętu bezpłatnie

Odbiór i zwrot sprzętu bezpłatnie

Zmienne w wyzwalaczu

Termin Definicja
Zmienne w wyzwalaczu

Zmienne w wyzwalaczu obejmują m.in. tabele inserted i deleted, dostępne wyłącznie w kontekście jego wykonania.

Rola tabel inserted i deleted w wyzwalaczu

W języku Transact-SQL używanym przez Microsoft SQL Server wyzwalacz DML otrzymuje specjalny kontekst zawierający logiczne tabele inserted i deleted. Nie są to zwykłe, trwale zapisane tabele użytkownika i nie można ich traktować jak obiektów przechowywanych w bazie. Istnieją tylko podczas wykonywania konkretnego wyzwalacza, a ich zawartość opisuje wiersze objęte bieżącą instrukcją INSERT, UPDATE albo DELETE. Wyzwalacz może odczytywać te dane w zapytaniach, lecz nie może bezpośrednio zmieniać zawartości tabel logicznych.

W przypadku instrukcji INSERT w tabeli inserted znajdują się nowe wiersze, które zostały dodane do tabeli bazowej, natomiast tabela deleted nie zawiera wierszy. Przy instrukcji DELETE sytuacja jest odwrotna: usuwane, dotychczasowe wiersze są dostępne w deleted, a inserted pozostaje pusta. Instrukcja UPDATE jest logicznie traktowana jako usunięcie poprzedniej wersji wierszy i wstawienie ich nowej wersji. Dlatego przed zmianą należy szukać w deleted, a wartości po zmianie w inserted.

Różnica między UPDATE, INSERT i DELETE

Najczęstszy błąd polega na napisaniu wyzwalacza tak, jakby każda instrukcja modyfikowała tylko jeden rekord. W SQL Server pojedyncze polecenie może zmienić, usunąć lub dodać wiele wierszy. Z tego powodu inserted i deleted należy obsługiwać jako zbiory, a nie jako pojedyncze zmienne skalarne. Konstrukcje takie jak przypisanie jednej wartości z tabeli logicznej do zmiennej mogą prowadzić do pominięcia części danych, jeżeli instrukcja obejmuje więcej niż jeden wiersz.

Poprawna logika wyzwalacza zwykle opiera się na zapytaniu zbiorowym, na przykład INSERT INTO Historia (Id, StaraWartosc, NowaWartosc) SELECT d.Id, d.Wartosc, i.Wartosc FROM deleted AS d JOIN inserted AS i ON i.Id = d.Id;. Taki schemat pasuje do aktualizacji, ponieważ oba zbiory zawierają odpowiadające sobie wersje zmienionych rekordów. Dla dodawania danych można odczytywać wyłącznie inserted, a dla usuwania wyłącznie deleted. Do rozpoznania rodzaju operacji można użyć funkcji UPDATE('NazwaKolumny'), ale dla instrukcji INSERT i DELETE jej interpretacja wymaga ostrożności, dlatego często stosuje się także właściwości funkcji wyzwalacza, takie jak COLUMNS_UPDATED(), tylko w zakresie zgodnym z konkretnym scenariuszem.

Walidacja danych i skutki działania wyzwalacza

W wyzwalaczu można porównywać wartości z inserted i deleted, aby wykrywać niedozwolone zmiany, zapisywać historię albo synchronizować dane w innych tabelach. Dla operacji UPDATE porównanie kolumn pozwala sprawdzić, czy wartość rzeczywiście się zmieniła, zamiast reagować na każdą instrukcję aktualizacji. Trzeba jednak pamiętać o wartościach NULL. Wyrażenie porównujące i.Kolumna <> d.Kolumna nie wykrywa wszystkich zmian, ponieważ porównania z NULL mają wynik nieznany. W praktyce konieczne jest jawne uwzględnienie przypadków, w których jedna albo obie wartości są puste.

Wyzwalacz uruchamia się w ramach tej samej transakcji co instrukcja, która go wywołała. Jeżeli wyzwalacz zgłosi błąd lub wykona ROLLBACK, operacja modyfikująca może zostać cofnięta razem z działaniami wykonanymi wcześniej w tej transakcji. Ma to znaczenie dla kontroli integralności, ale również dla wydajności i blokad. Zapytania wykonywane w wyzwalaczu powinny być przygotowane dla wielu wierszy i powinny korzystać z odpowiednich indeksów. Nieuzasadnione odpytywanie dużych tabel dla każdego elementu z inserted albo deleted może wydłużyć transakcję i zwiększyć czas oczekiwania innych operacji.

Ograniczenia kontekstu i bezpieczne testowanie

Tabele inserted i deleted są dostępne tylko wewnątrz kodu wyzwalacza, dlatego nie można odwołać się do nich z niezależnego zapytania uruchomionego po zakończeniu jego działania. Ich zawartość należy odczytać podczas wykonywania wyzwalacza. W wyzwalaczu typu AFTER dane w tabeli bazowej zostały już zmodyfikowane, ale cała transakcja nadal może zostać wycofana. Wyzwalacz typu INSTEAD OF zastępuje domyślną operację i sam musi zdecydować, czy oraz w jaki sposób wykonać właściwy zapis. W obu przypadkach znaczenie zbiorów logicznych wynika z operacji wywołującej.

Sprawdzenie wyzwalacza powinno obejmować osobne testy dla pojedynczego wiersza, wielu wierszy, aktualizacji bez faktycznej zmiany wartości, wartości NULL oraz naruszenia warunku integralności. Warto także zweryfikować zachowanie przy błędzie i wycofaniu transakcji. Diagnostyka problemu wymaga prześledzenia instrukcji wywołującej, definicji wyzwalacza, kluczy używanych do łączenia inserted z deleted oraz zapytań modyfikujących tabele pomocnicze. Błędne założenie, że kontekst zawsze zawiera jeden rekord, może powodować niepełną historię zmian, nieprawidłowe wartości kontrolne albo odrzucanie poprawnych operacji wielowierszowych.

+48 22 100 48 29Zadzwoń teraz · serwisant w 1 godzinę