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

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

Je voudrais être en mesure de soutenir SQL Server 2000 SP4 ou plus récent. Mon application est une visualisation de données sur le produit d'une autre société. Notre clientèle se compose de milliers de personnes. Je ne veux donc pas avoir à modifier la table des fournisseurs tiers à chaque installation.

Par "changements à une table" , je veux dire des changements aux données de la table, pas des changements à la structure de la table.

En fin de compte, je voudrais que la modification déclenche un événement dans mon application, au lieu de devoir vérifier les changements à un intervalle.


Le meilleur plan d'action compte tenu de mes besoins (aucun déclencheur ou modification de schéma, SQL Server 2000 et 2005) semble être d'utiliser la fonction BINARY_CHECKSUM dans T-SQL . La façon dont je prévois de mettre en œuvre est la suivante:

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

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

Et comparez cela à la valeur stockée. Si la valeur a changé, passez la table par ligne en utilisant la requête:

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

Et comparez les sommes de contrôle retournées aux valeurs stockées.

0
ajouté édité
Vues: 18
Ils n'arrivaient pas à mettre un horodatage de dernière modification sur leurs rangs, n'est-ce pas?
ajouté l'auteur zmbq, source

8 Réponses

Pourquoi ne voulez-vous pas utiliser des déclencheurs? Ils sont une bonne chose si vous les utilisez correctement. Si vous les utilisez pour appliquer l'intégrité référentielle, c'est-à-dire quand elles vont de bonnes à mauvaises. Mais si vous les utilisez pour la surveillance, ils ne sont pas vraiment considérés comme tabous.

0
ajouté

Wild devinez ici: Si vous ne voulez pas modifier les tables des tiers, pouvez-vous créer une vue et ensuite mettre un déclencheur sur cette vue?

0
ajouté

Avoir un travail DTS (ou un travail qui est démarré par un service Windows) qui s'exécute à un intervalle donné. Chaque fois qu'il est exécuté, il obtient des informations sur la table donnée en utilisant le INFORMATION_SCHEMA tables et enregistre ces données dans le référentiel de données. Comparez les données renvoyées concernant la structure de la table avec les données renvoyées l'heure précédente. Si c'est différent, alors vous savez que la structure a changé.

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

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

Vous surveilleriez différentes colonnes et vues INFORMATION_SCHEMA en fonction de la manière dont vous définissez exactement les "modifications apportées à une table".

0
ajouté
La question concerne les changements dans les données de table et information_schema contient le schéma (définitions de colonnes) de la table.
ajouté l'auteur too, source

À quelle fréquence devez-vous vérifier les changements et quelle est la taille (en termes de taille de ligne) des tables de la base de données? Si vous utilisez la méthode CHECKSUM_AGG (BINARY_CHECKSUM (*)) proposée par John, elle analysera chaque ligne de la table spécifiée. L'indice NOLOCK est utile, mais sur une base de données volumineuse, vous continuez à frapper toutes les lignes. Vous aurez également besoin de stocker la somme de contrôle pour chaque ligne afin que vous disiez que l'un a changé.

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

Ils pourraient implémenter une API qui fournit un mécanisme pour notifier les applications accessoires que les données ont changé. Cela pourrait être aussi simple que d'écrire dans une table de notification qui répertorie quelles tables et quelles lignes ont été modifiées. Cela pourrait être mis en œuvre au moyen de déclencheurs ou d'un code d'application. De votre côté, ti n'aurait pas d'importance, votre seule préoccupation serait de scanner la table de notification sur une base périodique. L'impact sur les performances de la base de données serait beaucoup moins que l'analyse de chaque ligne pour les changements.

La partie la plus difficile serait de convaincre le fournisseur de l'application d'implémenter cette fonctionnalité. Comme cela peut être géré entièrement via SQL via des déclencheurs, vous pouvez faire le gros du travail en écrivant et en testant les déclencheurs, puis en apportant le code au fournisseur de l'application. En faisant en sorte que le fournisseur prenne en charge les déclencheurs, il empêche la situation dans laquelle l'ajout d'un déclencheur remplace par inadvertance un déclencheur fourni par le fournisseur.

0
ajouté

Jetez un oeil à la commande CHECKSUM:

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

Cela retournera le même nombre chaque fois qu'il est exécuté tant que le contenu de la table n'a pas changé. Voir mon message sur ceci pour plus d'informations:

CHECKSUM

Here's how I used it to rebuild cache dependencies when tables changed:
ASP.NET 1.1 database cache dependency (without triggers)

0
ajouté
Les checksums peuvent et vont échouer finalement. Si votre système accepte que deux ensembles de données différents aboutissent à la même somme de contrôle, alors vous allez bien. Pour cette raison, j'ai dû abandonner les sommes de contrôle dans la plupart de nos systèmes ...
ajouté l'auteur LPains, source

Malheureusement, je ne pense pas qu'il existe un moyen propre de le faire dans SQL2000. Si vous limitez vos besoins à SQL Server 2005 (et plus tard), vous êtes en affaires. Vous pouvez utiliser la classe SQLDependency dans System.Data.SqlClient . Voir Notifications de requête dans SQL Server (ADO.NET) .

0
ajouté

Vérifiez la dernière date de validation. Chaque base de données a un historique de quand chaque validation est faite. Je crois que c'est une norme de conformité ACID.

0
ajouté

Unfortunately CHECKSUM does not work always properly to detect changes. It is only a primitive checksum and no CRC calculation. Therefore you can't use it to detect all changes, e. g. symmetrical changes result in the same CHECKSUM!

Par exemple. la solution avec CHECKSUM_AGG (BINARY_CHECKSUM (*)) délivre 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!
0
ajouté
Ce n'est pas vraiment une réponse, c'est "votre suggestion ne fonctionne pas".
ajouté l'auteur kristianp, source
Cela peut être corrigé pour les données dupliquées en utilisant le mot-clé DISINCT avant le BINARY_CHECKSUM. Il y a quelques autres pièges abordés ici mais pas vraiment commun scénarios.
ajouté l'auteur pblack, source