Mam tabelę z 42 kolumnami i wyzwalaczem, który powinien zrobić coś, gdy 38 z tych kolumn zostanie zaktualizowanych. Więc muszę pominąć logikę, jeśli pozostałe 4 kolumny zostaną zmienione.
Mogę użyć funkcji UPDATE () i stworzyć jeden duży IF
warunek, ale wolę zrobić coś krótszego. Za pomocą COLUMNS_UPDATED mogę sprawdzić, czy wszystkie niektóre kolumny są zaktualizowane?
Na przykład sprawdzenie, czy kolumny 3, 5 i 9 są zaktualizowane:
IF
(
(SUBSTRING(COLUMNS_UPDATED(),1,1) & 20 = 20)
AND
(SUBSTRING(COLUMNS_UPDATED(),2,1) & 1 = 1)
)
PRINT 'Columns 3, 5 and 9 updated';
Zatem wartość 20
dla kolumny 3
i 5
oraz wartość 1
dla kolumny, 9
ponieważ jest ona ustawiona w pierwszym bicie drugiego bajtu. Jeśli zmienię na to instrukcję OR
, sprawdzi, czy kolumny 3
i / 5
lub kolumna 9
są / są aktualizowane?
Jak zastosować OR
logikę w kontekście jednego bajtu?
sql-server
t-sql
trigger
gotqn
źródło
źródło
SET
liście, czy też wartości rzeczywiście się zmieniły? ZarównoUPDATE
iCOLUMNS_UPDATED()
tylko ci powiem pierwszy. Jeśli chcesz wiedzieć, czy wartości rzeczywiście się zmieniły, musisz dokonać właściwego porównaniainserted
ideleted
.SUBSTRING
do dzielenia zwracanej wartościCOLUMNS_UPDATED()
, należy użyć porównania bitowego, jak pokazano w dokumentacji . Uwaga: jeśli w jakikolwiek sposób zmienisz tabelę, kolejność wartości zwracanych przezCOLUMNS_UPDATED()
zmieni się.SET
lubUPDATE
, możesz przyjrzeć się za pomocąCHECKSUM()
lubBINARY_CHECKSUM()
, a nawetHASHBYTES()
nad danymi kolumnami.Odpowiedzi:
Możesz użyć
CHECKSUM()
jako dość prostej metodologii porównywania rzeczywistych wartości, aby sprawdzić, czy zostały one zmienione.CHECKSUM()
wygeneruje sumę kontrolną na liście przekazanych wartości, których liczba i typ są nieokreślone. Uważaj, istnieje niewielka szansa, że porównanie sum kontrolnych takich jak ta spowoduje fałszywe negatywy. Jeśli nie możesz sobie z tym poradzić, możeszHASHBYTES
zamiast tego użyć 1 .W poniższym przykładzie użyto
AFTER UPDATE
wyzwalacza, aby zachować historię zmian wprowadzonych wTriggerTest
tabeli tylko w przypadku zmiany jednej z wartości w kolumnachData1
lubData2
. W przypadkuData3
zmian nie są podejmowane żadne działania.Jeśli nalegasz na użycie funkcji COLUMNS_UPDATED () , nie powinieneś sztywno kodować wartości porządkowej danych kolumn, ponieważ definicja tabeli może się zmienić, co może unieważnić wartości zakodowane na stałe . Możesz obliczyć, jaka powinna być wartość w czasie wykonywania, korzystając z tabel systemowych. Należy pamiętać, że
COLUMNS_UPDATED()
funkcja zwraca wartość true dla danego bitu kolumny, jeśli kolumna jest modyfikowana w DOWOLNYM wierszu, na który wpływaUPDATE TABLE
instrukcja.To demo wstawia wiersze do tabeli historii, których być może nie należy wstawiać. W wierszach
Data1
zaktualizowano kolumnę dla niektórych wierszy iData3
zaktualizowano kolumnę dla niektórych wierszy. Ponieważ jest to pojedyncza instrukcja, wszystkie wiersze są przetwarzane przez pojedyncze przejście przez wyzwalacz. Ponieważ niektóre wiersze zostałyData1
zaktualizowane, co stanowi częśćCOLUMNS_UPDATED()
porównania, wszystkie wiersze widoczne dla wyzwalacza są wstawiane doTriggerHistory
tabeli. Jeśli jest to „niepoprawne” w twoim scenariuszu, być może będziesz musiał obsługiwać każdy wiersz osobno, używając kursora.TriggerResult
Tabela ma teraz jakieś potencjalnie mylących wiersze, które wyglądają tak, jakby nie należą, ponieważ pokazują one absolutnie żadnych zmian (w dwóch kolumnach w tej tabeli). W drugim zestawie wierszy na poniższym obrazku TriggerTestID 7 jest jedynym, który wygląda na zmodyfikowany. W pozostałych wierszachData3
zaktualizowano tylko kolumnę; jednak ponieważ zaktualizowano jeden wiersz w partiiData1
, wszystkie wiersze są wstawiane doTriggerResult
tabeli.Alternatywnie, jako @AaronBertrand i @srutzky wskazał, można przeprowadzić porównanie rzeczywistych danych w
inserted
ideleted
wirtualnych stołach. Ponieważ struktura obu tabel jest identyczna, możesz użyćEXCEPT
klauzuli w wyzwalaczu, aby przechwycić wiersze, w których zmieniły się precyzyjne kolumny:1 - patrz /programming/297960/hash-collision-what-are-the-ances szanse na omówienie znikomej szansy, że obliczenia HASHBYTES mogą również powodować kolizje. Preshing ma również przyzwoitą analizę tego problemu.
źródło
HASHBYTES
zamiast tego”. wprowadza w błąd. To prawda, że prawdopodobieństwo wystąpienia fałszywych negatywówHASHBYTES
jest mniejsze niżCHECKSUM
(prawdopodobieństwo zależy od wielkości zastosowanego algorytmu), ale nie można tego wykluczyć. Każda funkcja haszująca zawsze może potencjalnie powodować kolizje, ponieważ jest prawdopodobne, że zmniejszy ilość informacji. Jedynym sposobem, aby mieć pewność bez zmian jest porównanieINSERTED
iDELETED
tabele, i za pomocą_BIN2
sortowania, jeśli jest to ciąg danych. Porównywanie skrótów daje pewność różnic.