Mamy bazę danych SQL Server, która ma specyfikację kontroli bazy danych, która kontroluje wszystkie działania wykonywane w bazie danych.
CREATE DATABASE AUDIT SPECIFICATION [dbAudit]
FOR SERVER AUDIT [servAudit]
ADD (EXECUTE ON DATABASE::[DatabaseName] BY [public])
Odkryliśmy, że niektóre zapytania zapisują w dzienniku kontroli użycie funkcji skalarnej dla każdego wiersza w zestawie wyników. Kiedy tak się dzieje, dziennik zapełnia się, zanim będziemy mogli go ETL umieścić w ostatecznym miejscu spoczynku i mamy luki w logowaniu.
Niestety z powodów zgodności nie możemy po prostu przestać sprawdzać każdego EXECUTE
oświadczenia.
Naszym pierwszym podejściem do rozwiązania tego problemu jest użycie WHERE
klauzuli dotyczącej Audytu serwera w celu odfiltrowania działania. Kod wyglądał następująco:
WHERE [object_id] not in (Select object_id from sys.objects where type = 'FN' )
Niestety, SQL Server nie zezwala na relacyjny operator IN (prawdopodobnie dlatego, że nie chce zapytać za każdym razem, gdy musi zapisywać w dzienniku kontroli).
Chcielibyśmy uniknąć zapisywania przechowywanego proc, który koduje na stałe object_id
w WHERE
klauzuli, ale takie jest nasze obecne podejście do najlepszego rozwiązania tego problemu. Czy istnieje alternatywne podejście, które powinniśmy rozważyć?
Zauważyliśmy, że gdy funkcja skalarna jest używana w rekurencyjnym CTE, powoduje to, że zapytanie zapisuje się w dzienniku kontroli dla każdego wiersza w zestawie wyników.
Niektóre funkcje o wartościach skalarnych są dostarczane przez dostawcę, których nie możemy usunąć ani przenieść do alternatywnej bazy danych.
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.
- To jeden z najwspanialszych efektów ubocznych skalarnych UDF, jakie kiedykolwiek słyszałem i dużo słyszałem.