Sprawdzanie zmian w tabeli SQL Server?
Jak mogę monitorować bazę danych SQL Server pod kątem zmian w tabeli bez użycia wyzwalaczy lub modyfikowania struktury bazy danych w jakikolwiek sposób? Moje preferowane środowisko programistyczne to . Net i C#.
Chciałbym móc obsługiwać dowolny SQL Server 2000 SP4 lub nowszy. Moja aplikacja to wizualizacja danych dla produktu innej firmy. Nasza baza klientów jest w tysiącach, więc nie chcę stawiać wymagań, aby zmodyfikować stronę trzecią stół sprzedawcy przy każdej instalacji.
Przez "zmiany w tabeli" mam na myśli zmiany danych tabeli, a nie zmiany struktury tabeli.
Ostatecznie chciałbym, aby zmiana wywołała Zdarzenie w mojej aplikacji, zamiast sprawdzać zmiany w interwale.
Najlepszym sposobem działania biorąc pod uwagę moje wymagania (brak wyzwalaczy lub modyfikacji schematu, SQL Server 2000 i 2005) wydaje się użycie funkcji BINARY_CHECKSUM
w T-SQL. Sposób, w jaki planuję implementacja jest następująca:
Co X sekund uruchom następujące zapytanie:
SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*))
FROM sample_table
WITH (NOLOCK);
I porównać to z przechowywaną wartością. Jeśli wartość się zmieniła, przejdź przez tabelę wiersz po wierszu używając zapytania:
SELECT row_id, BINARY_CHECKSUM(*)
FROM sample_table
WITH (NOLOCK);
I porównać zwrócone sumy kontrolne z zapisanymi wartościami.
8 answers
Spójrz na polecenie sumy kontrolnej:
SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*)) FROM sample_table WITH (NOLOCK);
Zwróci ten sam numer za każdym razem, gdy zostanie uruchomiony, o ile zawartość tabeli nie ulegnie zmianie. Zobacz mój post na ten temat, aby uzyskać więcej informacji:
Oto jak go użyłem do odbudowy zależności bufora po zmianie tabel:
ASP.NET 1.1 zależność bufora bazy danych (bez wyzwalaczy)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-28 03:44:42
niestety suma kontrolna nie zawsze działa poprawnie, aby wykryć zmiany. Jest to tylko prymitywna suma kontrolna i brak obliczeń CRC. Dlatego nie można go użyć do wykrycia wszystkich zmian, np. zmiany symetryczne powodują tę samą sumę kontrolną!
Np. rozwiązanie z CHECKSUM_AGG(BINARY_CHECKSUM(*))
dostarcza zawsze 0 dla wszystkich 3 tabel o różnej treści!
SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*)) FROM
(
SELECT 1 as numA, 1 as numB
UNION ALL
SELECT 1 as numA, 1 as numB
) q
-- delivers 0!
SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*)) FROM
(
SELECT 1 as numA, 2 as numB
UNION ALL
SELECT 1 as numA, 2 as numB
) q
-- delivers 0!
SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*)) FROM
(
SELECT 0 as numA, 0 as numB
UNION ALL
SELECT 0 as numA, 0 as numB
) q
-- delivers 0!
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-29 02:34:15
Dlaczego nie chcesz użyć wyzwalaczy? Są dobrą rzeczą, jeśli używasz ich poprawnie. Jeśli używasz ich jako sposobu na wyegzekwowanie integralności odniesienia, to wtedy przechodzą z dobrego na złe. Ale jeśli używasz ich do monitorowania, nie są one tak naprawdę uważane za tabu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-26 17:38:44
Jak często trzeba sprawdzać zmiany i jak duże (pod względem wielkości wiersza) są tabele w bazie danych? Jeśli użyjesz metody CHECKSUM_AGG(BINARY_CHECKSUM(*))
zasugerowanej przez Johna, skanuje ona każdy wiersz podanej tabeli. Podpowiedź NOLOCK
pomaga, ale w dużej bazie danych wciąż trafiasz w każdy wiersz. Będziesz również musiał przechowywać sumę kontrolną dla każdego wiersza, aby powiedzieć, że jeden się zmienił.
Mogliby zaimplementować API, które zapewnia mechanizm powiadamiania aplikacji akcesoriów o zmianie danych. Może to być tak proste, jak zapisanie do tabeli powiadomień, która wyświetla tabelę i który wiersz został zmodyfikowany. Można to zaimplementować za pomocą wyzwalaczy lub kodu aplikacji. Z twojej strony, ti nie ma znaczenia, twoja jedyna troska będzie okresowo skanować tabelę powiadomień. Wydajność bazy danych byłaby znacznie mniejsza niż skanowanie każdego wiersza w poszukiwaniu zmian.
Najtrudniejsze byłoby przekonanie dostawcy aplikacji do wdrożenia tej funkcji. Ponieważ może to być obsługiwane w całości przez SQL za pomocą wyzwalaczy, możesz wykonać dla nich większość pracy, pisząc i testując wyzwalacze, a następnie dostarczając kod do dostawcy aplikacji. Mając dostawcę obsługi wyzwalaczy, zapobiega sytuacja, w której dodanie wyzwalacza przypadkowo zastępuje WYZWALACZ dostarczony przez dostawcę.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-14 12:19:25
Ma zadanie DTS (lub zadanie uruchamiane przez usługę windows), które działa w danym przedziale czasowym. Przy każdym uruchomieniu pobiera informacje o podanej tabeli za pomocą tabel system INFORMATION_SCHEMA i zapisuje te dane w repozytorium danych. Porównuje zwrócone dane dotyczące struktury tabeli z danymi zwróconymi w poprzednim czasie. Jeśli jest inaczej, to wiesz, że struktura się zmieniła.
Przykładowe zapytanie zwracające informacje dotyczące wszystkich kolumny w tabeli ABC (najlepiej wypisując tylko kolumny z tabeli INFORMATION_SCHEMA, które chcesz, zamiast używać * select * * jak to robię tutaj):
select * from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = 'ABC'
Będziesz monitorować różne kolumny i widoki INFORMATION_SCHEMA w zależności od tego, jak dokładnie zdefiniujesz "zmiany w tabeli".
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-01 14:06:28
Niestety, nie sądzę, aby w SQL2000 można było to zrobić w czysty sposób. Jeśli zawęzisz swoje wymagania do SQL Server 2005 (i nowszych), to jesteś w biznesie. Możesz użyć klasy SQLDependency
w System.Data.SqlClient
. Zobacz powiadomienia o zapytaniach w SQL Server (ADO.NET).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-25 20:42:28
Zgaduj tutaj: jeśli nie chcesz modyfikować tabel stron trzecich, czy możesz utworzyć widok, a następnie uruchomić ten widok?
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-05 01:12:37
Sprawdź ostatnią datę zatwierdzenia. Każda baza danych ma historię, kiedy każdy commit jest tworzony. Uważam, że to Norma zgodności z kwasem.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-24 04:58:25