web-dev-qa-db-ja.com

SQL Server監査データからスカラー値のユーザー定義関数の使用を除外する方法

SQL Serverデータベースがあり、データベースに対するすべての実行アクションを監査するデータベース監査仕様があります。

CREATE DATABASE AUDIT SPECIFICATION [dbAudit]
FOR SERVER AUDIT [servAudit]
ADD (EXECUTE ON DATABASE::[DatabaseName] BY [public])

一部のクエリは、結果セットのすべての行に対してスカラー関数の使用を監査ログに書き込むことがわかりました。これが発生すると、ログがETLして最終的な休憩場所に入る前にログがいっぱいになり、ログにギャップが生じます。

残念ながら、コンプライアンス上の理由により、すべてのEXECUTEステートメントの監査を単純に停止することはできません。

この問題へのアプローチについて私たちが最初に考えたのは、 Server AuditWHERE句を使用してアクティビティを除外することです。コードは次のようになります。

WHERE [object_id] not in (Select object_id from sys.objects where type = 'FN' )

残念ながら、SQL ServerはリレーショナルIN演算子を許可していません(おそらく監査ログに書き込む必要があるたびにクエリを実行したくないためです)。

WHERE句にobject_idをハードコードするストアドプロシージャの作成は避けたいのですが、これが、この問題に取り組むための最良の方法に関する現在の考え方です。考慮すべき代替アプローチはありますか?

スカラー関数が再帰CTEで使用されている場合、結果セットのすべての行のクエリが監査ログに書き込まれることに気付きました。

ベンダーが提供するスカラー値関数がいくつかあり、削除したり、代替データベースに移動したりすることはできません。

12
Mark Iannucci

私が働くことができたいくつかのオプションがあります。すべてのオプションは、さまざまなフィルター述部を扱います。 注:変更を加えるには、サーバー監査を無効にする必要があります。その後、再度enableそれ。

まず、最も一般的なアプローチは、すべてのスカラーUDFをフィルターで取り除くことです。これは、_class_type_監査フィールドを使用して行うことができます。ドキュメントは、このフィールドがVARCHAR(2)であることを示していますが、文字列を指定することはできません。しかし、私は以下を機能させました:

_ALTER SERVER AUDIT [servAudit]
WHERE ([class_type] <> 20038); -- EXECUTE Scalar UDF
_

(その調査の詳細はこちら: Server Audit Mystery:Filtering class_type gets Error Msg 2571

次の最も一般的なアプローチはオプションではありません。これは、これがベンダー提供のデータベースであり、変更を加えることができないと述べられているためです。それを最後にカバーします。

最も一般的ではない方法(ただし、確実に機能する方法)は、特定の関数名を除外することです。

_ALTER SERVER AUDIT [servAudit]
WHERE ([object_name]<>'function_name');
_

または、複数の名前の場合:

_ALTER SERVER AUDIT [servAudit]
WHERE ([object_name]<>'function_name1' AND [object_name]<>'function_name2');
_

あまり一般的ではありませんが、フィルタリングする関数の数はかなり少なくなければならず、新しい関数が導入されることはあまりないため、このアプローチは問題ありません。

最後に、この状況に直面していて、変更を加えることに制限されていない他の人たちに:関数を独自のスキーマに配置し、そのスキーマだけをフィルターで除外できます。これは、関数を個別にフィルタリングするよりも一般的です。 fnという名前のスキーマを作成し、その中に関数を配置するとします。

_ALTER SERVER AUDIT [servAudit]
WHERE ([schema_name]<>'fn');
_

また、質問の次の2つのコメントに関して:

残念ながら、SQL ServerはリレーショナルIN演算子を許可していません(おそらく監査ログに書き込む必要があるたびにクエリを実行したくないためです)。

そして:

WHERE句でobject_idをハードコードするストアドプロシージャの作成を避けたい

IN演算子は問題ではありません。確かに、これはサポートされていませんが、OR条件のリストの省略形です。実際の問題は、T-SQLの使用です。リテラル(文字列または数値)のみが許可されます。したがって、とにかくストアドプロシージャを実行できなかったでしょう。また、組み込み関数を使用することもできません。

6
Solomon Rutzky