Muszę napisać Wstawianie, aktualizację wyzwalacza w tabeli A, która usunie wszystkie wiersze z tabeli B, której jedna kolumna (powiedzmy Desc) ma wartości takie jak wartość wstawiona / zaktualizowana w kolumnie tabeli A (powiedz Col1). Jak bym go pisał, aby móc obsługiwać zarówno przypadki aktualizacji, jak i wstawiania. Jak określić, czy wyzwalacz jest wykonywany dla aktualizacji lub wstawienia.
źródło
źródło
Wiele z tych sugestii nie jest branych pod uwagę, jeśli uruchomisz instrukcję usuwania, która niczego nie usuwa.
Załóżmy, że próbujesz usunąć, gdzie identyfikator jest równy jakiejś wartości, której nie ma w tabeli.
Twój wyzwalacz nadal jest wywoływany, ale w tabelach usuniętych lub wstawionych nie ma nic.
Użyj tego dla bezpieczeństwa:
Specjalne podziękowania dla @KenDog i @Net_Prog za ich odpowiedzi.
Zbudowałem to na podstawie ich skryptów.
źródło
Używam następujących, poprawnie wykrywam również instrukcje delete, które niczego nie usuwają:
źródło
Po wielu poszukiwaniach nie mogłem znaleźć dokładnego przykładu pojedynczego wyzwalacza SQL Server, który obsługuje wszystkie (3) trzy warunki akcji wyzwalacza INSERT, UPDATE i DELETE. W końcu znalazłem wiersz tekstu, który mówił o fakcie, że gdy nastąpi DELETE lub UPDATE, wspólna tabela DELETED będzie zawierała zapis dla tych dwóch akcji. Na podstawie tych informacji stworzyłem następnie małą procedurę Action, która określa, dlaczego wyzwalacz został aktywowany. Ten typ interfejsu jest czasami potrzebny, gdy istnieje zarówno wspólna konfiguracja, jak i określona akcja, która ma zostać wykonana na wyzwalaczu INSERT vs UPDATE. W takich przypadkach utworzenie oddzielnego wyzwalacza dla UPDATE i INSERT stałoby się problemem konserwacyjnym. (tj. czy oba wyzwalacze zostały poprawnie zaktualizowane pod kątem niezbędnej poprawki wspólnego algorytmu danych?)
W tym celu chciałbym podać następujący fragment kodu zdarzenia z wieloma wyzwalaczami do obsługi INSERT, UPDATE, DELETE w jednym wyzwalaczu dla Microsoft SQL Server.
źródło
Uważam, że zagnieżdżone ifs są trochę zagmatwane i:
;)
źródło
źródło
Spróbuj tego..
źródło
chociaż podoba mi się również odpowiedź opublikowana przez @Alex, oferuję tę odmianę powyższego rozwiązania @ Graham
używa to wyłącznie istnienia rekordów w tabelach INSERTED i UPDATED, w przeciwieństwie do używania COLUMNS_UPDATED dla pierwszego testu. Zapewnia również paranoiczną ulgę programistom, wiedząc, że rozważano ostateczny przypadek ...
otrzymasz NOOP z oświadczeniem takim jak:
źródło
END
jest nieprawidłowo wcięty! (powodując pytanie, gdzie pierwszyBEGIN
jest zamknięty)To może być szybszy sposób:
źródło
Potencjalny problem z dwoma oferowanymi rozwiązaniami polega na tym, że w zależności od sposobu ich zapisu zapytanie aktualizujące może zaktualizować zero rekordów, a zapytanie wprowadzające może wstawić zero rekordów. W takich przypadkach zestawy wstawionych i usuniętych rekordów będą puste. W wielu przypadkach, jeśli zarówno wstawione, jak i usunięte zestawy rekordów są puste, możesz po prostu wyjść z wyzwalacza bez robienia czegokolwiek.
źródło
Znalazłem mały błąd w Grahams, poza tym fajnym rozwiązaniem:
Powinien być IF COLUMNS_UPDATED () < > 0 - wstaw lub zaktualizuj
zamiast> 0 prawdopodobnie dlatego, że górny bit jest interpretowany jako SIGNED bit znaku liczby całkowitej ... (?). Więc w sumie:
źródło
To działa dla mnie:
Ponieważ nie wszystkie kolumny mogą być aktualizowane na raz, możesz sprawdzić, czy dana kolumna jest aktualizowana za pomocą czegoś takiego:
źródło
źródło
Lubię rozwiązania, które są „eleganckie informatycznie”. Moje rozwiązanie tutaj trafia w pseudotabele [wstawione] i [usunięte] raz, aby uzyskać ich statusy i umieszcza wynik w zmiennej bitowej. Następnie każdą możliwą kombinację INSERT, UPDATE i DELETE można łatwo przetestować w całym wyzwalaczu za pomocą wydajnych obliczeń binarnych (z wyjątkiem mało prawdopodobnej kombinacji INSERT lub DELETE).
Zakłada, że nie ma znaczenia, jaka była instrukcja DML, jeśli żadne wiersze nie zostały zmodyfikowane (co powinno zadowolić zdecydowaną większość przypadków). Więc chociaż nie jest tak kompletne jak rozwiązanie Romana Pekara, jest bardziej wydajne.
Dzięki takiemu podejściu mamy możliwość jednego wyzwalacza „FOR INSERT, UPDATE, DELETE” na tabelę, co daje nam A) pełną kontrolę nad kolejnością akcji i b) jedną implementację kodu na akcję, która ma wiele akcji. (Oczywiście każdy model wdrożenia ma swoje wady i zalety; będziesz musiał ocenić swoje systemy indywidualnie pod kątem tego, co naprawdę działa najlepiej).
Zwróć uwagę, że instrukcje „istnieje (wybierz * z« wstawione / usunięte »)” są bardzo wydajne, ponieważ nie ma dostępu do dysku ( https://social.msdn.microsoft.com/Forums/en-US/01744422-23fe-42f6 -9ab0-a255cdf2904a ).
źródło
Szybkie rozwiązanie MySQL
Przy okazji: używam MySQL PDO.
(1) W tabeli z automatycznym zwiększaniem wartości po prostu pobierz najwyższą wartość (nazwa mojej kolumny = id) z kolumny zwiększonej, gdy każdy skrypt zostanie uruchomiony jako pierwszy:
(2) Uruchom zapytanie MySQL w normalny sposób i rzutuj wynik na liczbę całkowitą, np .:
(3) Po zapytaniu „INSERT INTO ... ON DUPLICATE KEY UPDATE” pobierz ostatnio wstawiony identyfikator w preferowany sposób, np .:
(4) Porównaj i zareaguj: Jeśli lastInsertId jest wyższy niż najwyższy w tabeli, prawdopodobnie jest to INSERT, prawda? I wzajemnie.
Wiem, że to szybkie i może brudne. I to jest stary post. Ale, hej, szukałem rozwiązania przez długi czas, a może i tak ktoś uzna mój sposób za przydatny. Wszystkiego najlepszego!
źródło
po prostu prosty sposób
źródło
W pierwszym scenariuszu przypuszczałem, że twoja tabela ma kolumnę IDENTITY
W drugim scenariuszu nie trzeba używać kolumny IDENTITTY
źródło
JEŚLI jego aktualizacja
jeśli jego wstawienie
źródło
Używam tych
exists (select * from inserted/deleted)
zapytań przez długi czas, ale to wciąż za mało dla pustych operacji CRUD (gdy nie ma rekordów winserted
ideleted
tabelach). Po dokładnym zbadaniu tego tematu znalazłem bardziej precyzyjne rozwiązanie:Można również użyć,
columns_updated() & power(2, column_id - 1) > 0
aby sprawdzić, czy kolumna została zaktualizowana, ale nie jest to bezpieczne w przypadku tabel z dużą liczbą kolumn. Użyłem nieco złożonego sposobu obliczania (zobacz pomocny artykuł poniżej).Ponadto to podejście nadal będzie niepoprawnie klasyfikować niektóre aktualizacje jako wstawienia (jeśli aktualizacja ma wpływ na każdą kolumnę w tabeli) i prawdopodobnie sklasyfikuje wstawienia, w których tylko wartości domyślne są wstawiane jako usunięte, ale są one królem rzadkich operacji (w leasingu w moim systemie są). Poza tym w tej chwili nie wiem, jak ulepszyć to rozwiązanie.
źródło
źródło
robię to:
1 -> włóż
2 -> usuń
3 -> aktualizacja
źródło
źródło