Nous avons une base de données SQL Server qui a une spécification d'audit de base de données qui vérifie toutes les actions d'exécution sur la base de données.
CREATE DATABASE AUDIT SPECIFICATION [dbAudit]
FOR SERVER AUDIT [servAudit]
ADD (EXECUTE ON DATABASE::[DatabaseName] BY [public])
Nous avons constaté que certaines requêtes écriront dans le journal d'audit l'utilisation d'une fonction scalaire pour chaque ligne d'un jeu de résultats. Lorsque cela se produit, le journal se remplit avant que nous puissions l'ETL dans son lieu de repos final et nous avons une lacune dans notre journalisation.
Malheureusement, pour des raisons de conformité, nous ne pouvons pas simplement arrêter l'audit de chaque EXECUTE
déclaration.
Notre première pensée pour l'approche de ce problème est d'utiliser la WHERE
clause sur l' audit du serveur pour filtrer l'activité. Le code ressemblait à ceci:
WHERE [object_id] not in (Select object_id from sys.objects where type = 'FN' )
Malheureusement, SQL Server n'autorise pas l'opérateur relationnel IN (probablement parce qu'il ne veut pas interroger chaque fois qu'il doit écrire dans le journal d'audit).
Nous aimerions éviter d'écrire un proc stocké qui code en dur object_id
la WHERE
clause, mais c'est notre réflexion actuelle sur la meilleure façon d'aborder ce problème. Y a-t-il une autre approche que nous devrions envisager?
Nous avons remarqué que lorsque la fonction scalaire est utilisée dans un CTE récursif, elle entraîne l'écriture de la requête dans le journal d'audit pour chaque ligne du jeu de résultats.
Certaines fonctions à valeur scalaire sont fournies par un fournisseur que nous ne pouvons pas supprimer ou déplacer vers une autre base de données.
We've found that some queries will write to the audit log the use of a scalar function for every row in a result set.
- C'est l'un des effets secondaires les plus magnifiques des FDU scalaires que j'ai jamais entendu, et j'en ai beaucoup entendu.Réponses:
Il y a quelques options que j'ai pu trouver. Toutes les options traitent des variations des prédicats de filtre. REMARQUE: vous devez désactiver la vérification du serveur afin d'apporter des modifications, puis re permettre lui.
Premièrement, l'approche la plus générique consiste à filtrer tous les FDU scalaires. Vous pouvez le faire en utilisant le
class_type
champ d'audit. La documentation indique que ce champ l'estVARCHAR(2)
, mais elle ne permet pas de spécifier une chaîne. Cependant, j'ai réussi à faire fonctionner les éléments suivants:(plus d'informations sur cette enquête ici: Server Audit Mystery: le filtrage class_type obtient le message d'erreur 25713 )
L'approche suivante la plus générique n'est pas une option car il a été déclaré qu'il s'agit d'une base de données fournie par le fournisseur et donc aucune modification ne peut être apportée. Je vais donc couvrir ce dernier.
L'approche la moins générique (mais qui fonctionne définitivement) consiste à filtrer le nom de fonction spécifique:
Ou, si plusieurs noms:
Bien qu'elle ne soit pas très générique, cette approche devrait être correcte car le nombre de fonctions à filtrer devrait être assez petit, et il ne sera pas très fréquent que de nouvelles fonctions soient introduites.
Enfin, pour les autres personnes confrontées à cette situation et qui ne sont pas limitées à apporter des modifications: vous pouvez placer des fonctions dans leur propre schéma, puis filtrer uniquement ce schéma. C'est plus générique que de filtrer les fonctions individuellement. En supposant que vous créez un schéma nommé
fn
et que vous y placez la ou les fonctions:ÉGALEMENT, concernant les deux commentaires suivants dans la question:
et:
L'
IN
opérateur n'est pas le problème. Certes, ce n'est pas pris en charge, mais c'est juste un raccourci pour une liste deOR
conditions. Le vrai problème est l'utilisation de T-SQL. Seuls les littéraux - chaînes ou nombres - sont autorisés. Vous n'auriez donc pas pu exécuter une procédure stockée de toute façon. Vous ne pouvez pas non plus utiliser les fonctions intégrées.la source
=
pour être<>
dans ma réponse. Je viens aussi de le tester et cela fonctionne comme annoncé :-)