Blog de Philip Doxakis    LinkedIn    GitHub    RSS

Audit Trail made simple

Mais qu'est-ce qu'il s'est passé ?

L'audit trail

Conserver l'audit trail, c'est conservé une trace du changement. Selon le milieu où l'on travaille, on peut être amené à devoir maintenir un log des opérations. Cela peut être fait avec un différent niveau de précision. À titre d'exemple, on pourrait vouloir conserver qui a fait une certaine opération et également une raison au changement.

Réflexion

Une manière simple, mais complexe en pratique est d'utiliser une double table à chaque table pour conserver ce qui a changé suite à une mise à jour d'une entrée. L'avantage est au niveau de la facilité d'accès. Par contre, cela devient lourd à gérer et en plus, lorsque cela est géré dans l'application, cela implique beaucoup de ligne de code.

Après mûre réflexion et suite à des recherches sur le sujet, je suis venu à utiliser une approche plus simple et moins dépendante de l'application. Essentiellement, cela se résume par l'utilisation de Trigger SQL sur les tables de la base de données et d'utiliser des conventions. C'est une approche générique puisqu'elle fait appel à du SQL dynamique. Je me suis basé sur l'article: appuyez ici pour le consulter

Il utilise une approche intéressante. Par contre, ce que je trouve dommage c'est qu'il s'agit d'un audit trail purement au niveau de la base de données. Cela ne prend pas en compte des données comme: Qui a réellement fait le changement? Pourquoi a-t-il fait cela?

L'approche choisie

J'ai modifié légèrement le script de l'article pour mes besoins. Afin de conserver les informations supplémentaires, il suffit de conserver pour chaque table une colonne nommée EditedBy (ou semblable) et un champ LastReasonForChange.

Pour obtenir la trace de qui a fait quoi: Il suffit d'obtenir l'entrée du champ EditedBy à la même date d'une modification ou inférieur. Ce qui est bien de cette approche, c'est qu'elle n'a pas de dépendance. S'il nous venait l'envie d'archiver une partie de la table Audit, dans ce cas, si l'on ne trouve pas d'entrée alors on ne peut pas déterminer qui a fait le changement. Il faudrait vérifier dans les archives. De plus, cette approche supporte la modification du schéma de la base de données. Cela n'a pas d'influence, car le Trigger SQL analyse la structure de la table à chaque fois.

So what?

Vous remarquerez certainement que le format de la colonne PK est particulier. C'est structuré ainsi afin de permettre la gestion des clés primaires pour les tables associatives. Chaque enregistrement représente un changement. Par exemple, changer 2 champs représente 2 entrées dans l'audit avec une date de modification identique (voir le champ UpdateDate). Donc, à présent, toutes les opérations d'insertion, de modification et de suppression seront ajoutées automatiquement dans la table d'audit. (Même si l'on passe par Microsoft SQL Server Management Studio.)

Mise à jour : 13 janvier 2016

Le script, sur lequel je m'étais basé, ne gère pas bien la suppression de colonne dans la base de données. En effet, l'appel à la fonction COLUMNS_UPDATED() est problématique avec les valeurs envoyées à la fonction. Pour détecter, un changement de type "Update", il faut appliquer un masque. Le masque est créé à partir du champ column_id. Il se basait sur le champ ORDINAL_POSITION. Autrement dit, il se basait sur la position actuelle de la colonne dans la table. L'identifiant d'une colonne ne représente pas nécessairement la position de la colonne dans le cas de suppression de colonne. Alors, il pouvait y avoir des changements qui n'étaient pas conservés dans la table d'audit.

Enfin, le script a été corrigé et simplifié au maximum. Il suffit de l'exécuter et c'est terminer. S'il y a une nouvelle table, on l'exécute à nouveau tout simplement.

Le script est à présent sur GitHub : appuyez ici pour le consulter