Nous avons une base de données SQL Server qui possède une spécification d'audit de base de données que les audits exécutent toutes les actions 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 écrivent sur le journal d'audit l'utilisation d'une fonction scalaire pour chaque ligne d'un ensemble 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, en raison de 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 consiste à utiliser WHERE
clause sur le Audit de 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 (probablement parce qu'il ne veut pas interroger chaque fois qu'il doit écrire sur le journal d'audit).
Nous aimerions éviter d'écrire un procédé stocké quels codes dur le object_id
Dans la clause WHERE
, mais c'est notre pensée actuelle sur la meilleure façon d'aborder ce problème. Existe-t-il une approche alternative que nous devrions considérer?
Nous avons remarqué que lorsque la fonction scalaire est utilisée dans un CTE récursif, il provoque la requête d'écrire sur le journal d'audit pour chaque ligne du jeu de résultats.
Certaines fonctions valorisées sont fournies par un fournisseur que nous ne pouvons pas supprimer ni passer à une autre base de données.
Il y a quelques options que j'ai pu utiliser. Toutes les options traitent des variations de prédicats de filtre. Remarque: Vous devez Désactiver Audit de serveur afin de modifier, puis de re- Activer ça.
Premièrement, l'approche la plus générique est de filtrer tous les UDF scalaires. Vous pouvez le faire en utilisant le champ d'audit class_type
. La documentation indique que ce champ est VARCHAR(2)
, mais cela ne permet pas de spécifier une chaîne. Cependant, j'ai reçu ce qui suit pour travailler:
ALTER SERVER AUDIT [servAudit]
WHERE ([class_type] <> 20038); -- EXECUTE Scalar UDF
(Plus d'informations sur cette enquête ici: Audit de serveur Mystery: Filtrage Class_Type Obtient une erreur MSG 2571 )
La prochaine approche la plus générique n'est pas une option car elle a été indiquée qu'il s'agissait d'une base de données fournie par le fournisseur et, partant, aucun changement ne peut être apporté. Donc, je vais couvrir ce dernier.
L'approche la moins générique (mais celle qui fonctionne définitivement) est de filtrer le nom de la fonction spécifique:
ALTER SERVER AUDIT [servAudit]
WHERE ([object_name]<>'function_name');
Ou, si des noms multiples:
ALTER SERVER AUDIT [servAudit]
WHERE ([object_name]<>'function_name1' AND [object_name]<>'function_name2');
Bien que cela ne soit pas très générique, cette approche devrait être une amende car le nombre de fonctions à filtrer devrait être assez faible et ne sera pas très souvent que de nouvelles fonctions sont introduites.
Enfin, à d'autres personnes qui font face à cette situation et ne sont pas limitées de la modification: vous pouvez placer des fonctions dans leur propre schéma, puis filtrer ce schéma. Ceci est plus générique que de filtrer les fonctions individuellement. En supposant que vous créez un schéma nommé fn
et placez la fonction (s) la fonction (s):
ALTER SERVER AUDIT [servAudit]
WHERE ([schema_name]<>'fn');
En outre, en ce qui concerne les deux commentaires suivants dans la question:
Malheureusement, SQL Server n'autorise pas l'opérateur relationnel (probablement parce qu'il ne veut pas interroger chaque fois qu'il doit écrire sur le journal d'audit).
et:
Nous aimerions éviter de rédiger un procédé stocké quels codes dur l'objet_id dans la clause WHERE
L'opérateur IN
n'est pas le problème. Vrai, ce n'est pas pris en charge, mais il ne s'agit que de sténographie pour une liste des conditions OR
. Le problème réel est l'utilisation de T-SQL. Seuls les cordes ou chiffres de littéraux - sont autorisés. Donc, vous n'auriez pas pu exécuter une procédure stockée de toute façon. Vous pouvez également utiliser les fonctions intégrées.