Vérifiez les modifications apportées à une table SQL Server?

voix
122

Comment puis - je surveiller une base de données SQL Server pour des modifications à une table sans l' aide de déclencheurs ou de modifier la structure de la base de données de quelque façon? Mon environnement de programmation préféré est .NET et C #.

Je voudrais être capable de supporter tout SQL Server 2000 SP4 ou plus récent. Mon application est une visualisation de données boulonné pour le produit d' une autre société. Notre base de clients est dans les milliers, donc je ne veux pas avoir à mettre dans les exigences que nous modifions à chaque installation de table du fournisseur tiers.

Par « modifications à une table » , je veux dire les modifications des données de table, pas de modifications à la structure de la table.

En fin de compte, je voudrais que le changement de déclencher un événement dans ma demande, au lieu d'avoir à vérifier les changements à un intervalle.


Le meilleur plan d'action étant donné mes besoins (aucun déclencheur ou modification de schéma, SQL Server 2000 et 2005) semble être d'utiliser la BINARY_CHECKSUMfonction T-SQL . La façon dont je l' intention de mettre en œuvre est le suivant:

Toutes les X secondes exécuter la requête suivante:

SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*))
FROM sample_table
WITH (NOLOCK);

Et les comparer à la valeur enregistrée. Si la valeur a changé, passer par la ligne de table en ligne à l'aide de la requête:

SELECT row_id, BINARY_CHECKSUM(*)
FROM sample_table
WITH (NOLOCK);

Et comparer les checksums retournés contre les valeurs stockées.

Créé 01/08/2008 à 13:35
source utilisateur
Dans d'autres langues...                            


8 réponses

voix
90

Jetez un oeil à la commande CHECKSUM:

SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*)) FROM sample_table WITH (NOLOCK);

Cela renverra le même nombre chaque fois qu'il est exécuté aussi longtemps que le contenu de la table n'a pas changé. Voir mon post à ce sujet pour plus d'informations:

SOMME

Voici comment je l' ai utilisé pour reconstruire les dépendances de cache lorsque les tables ont changé: la
dépendance de cache de base de données ASP.NET 1.1 (sans déclencheurs)

Créé 02/08/2008 à 06:20
source utilisateur

voix
30

Malheureusement CHECKSUM ne fonctionne pas toujours correctement pour détecter les changements . Il est seulement une somme de contrôle primitive et aucun calcul CRC. Par conséquent , vous ne pouvez pas l' utiliser pour détecter tous les changements, les changements symétriques par exemple le résultat de la même CHECKSUM!

Par exemple. la solution CHECKSUM_AGG(BINARY_CHECKSUM(*))offre toujours 0 pour les 3 tables avec un contenu différent!


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!

Créé 30/03/2011 à 13:07
source utilisateur

voix
25

Pourquoi ne voulez-vous pas utiliser des déclencheurs? Ils sont une bonne chose si vous les utilisez correctement. Si vous les utilisez comme un moyen de faire respecter l'intégrité référentielle qui est quand ils vont de bon à mauvais. Mais si vous les utilisez pour la surveillance, ils ne sont pas vraiment considérés comme tabous.

Créé 01/08/2008 à 14:07
source utilisateur

voix
19

À quelle fréquence avez - vous besoin de vérifier les modifications et la taille (en termes de taille de ligne) sont les tables de la base de données? Si vous utilisez la CHECKSUM_AGG(BINARY_CHECKSUM(*))méthode proposée par John, il va scanner chaque ligne de la table spécifiée. L' NOLOCKindice aide, mais sur une grande base de données, vous frappez encore chaque ligne. Vous aurez également besoin de stocker la somme de contrôle pour chaque ligne afin que vous dire qu'on a changé.

Avez-vous envisagé d'aller à ce sous un angle différent? Si vous ne voulez pas modifier le schéma pour ajouter des déclencheurs, (ce qui en fait un sens, ce n'est pas votre base de données), avez-vous envisagé de travailler avec le fournisseur de l'application qui ne fait la base de données?

Ils pourraient mettre en œuvre une API qui fournit un mécanisme de notification des applications accessoires que les données ont changé. Il pourrait être aussi simple que d'écrire à une table de notification qui indique à quelle table et quelle ligne ont été modifiés. Cela pourrait être mis en œuvre par les déclencheurs ou le code d'application. De votre côté, ti ne serait pas question, votre seule préoccupation serait parcourir la table de notification sur une base périodique. La performance a frappé sur la base de données serait beaucoup moins de parcourir toutes les lignes pour les changements.

La partie la plus difficile serait de convaincre le fournisseur d'application pour mettre en œuvre cette fonctionnalité. Étant donné que cela peut être tout à fait à travers les poignées SQL via les déclencheurs, vous pouvez faire le gros du travail pour eux en écrivant et en testant les déclencheurs et portant le code au fournisseur de l'application. En ayant le soutien des fournisseurs les éléments déclencheurs, il empêche la situation où votre ajout d'un élément déclencheur remplace par inadvertance un déclencheur fourni par le vendeur.

Créé 03/08/2008 à 14:59
source utilisateur

voix
18

Avoir un emploi DTS (ou un emploi qui a commencé par un service Windows) qui fonctionne à un intervalle donné. Chaque fois qu'il est exécuté, il obtient des informations sur la table donnée en utilisant le système INFORMATION_SCHEMA tables et enregistre ces données dans le référentiel de données. Comparer les données renvoyées en ce qui concerne la structure de la table avec les données renvoyées le temps précédent. Si elle est différente, alors vous savez que la structure a changé.

Exemple requête pour renvoyer des informations concernant toutes les colonnes dans ABC table (liste idéalement juste les colonnes de la table INFORMATION_SCHEMA que vous voulez, au lieu d'utiliser * sélectionner ** comme je le fais ici):

select * from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = 'ABC'

Vous veillerez différentes colonnes et vues INFORMATION_SCHEMA selon la façon dont vous définissez exactement « des modifications à une table ».

Créé 01/08/2008 à 15:06
source utilisateur

voix
17

Malheureusement, je ne pense pas qu'il y ait une manière propre à faire en SQL2000. Si vous réduisez vos besoins à SQL Server 2005 (et versions ultérieures), alors vous êtes dans les affaires. Vous pouvez utiliser la SQLDependencyclasse System.Data.SqlClient. Voir notifications de requête dans SQL Server (ADO.NET) .

Créé 06/08/2008 à 02:54
source utilisateur

voix
13

conjecture sauvage ici: Si vous ne voulez pas modifier les tables de tiers, vous pouvez créer une vue, puis mettre un déclencheur sur ce point de vue?

Créé 05/08/2008 à 02:12
source utilisateur

voix
7

Vérifiez la dernière date de validation. Chaque base de données a une histoire quand chaque livraison est faite. Je crois que son une norme de conformité ACID.

Créé 24/07/2014 à 05:58
source utilisateur

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more