SQL Server Denetim Verilerinden Skaler Değerli Kullanıcı Tanımlı İşlev kullanımı nasıl filtrelenir?


12

Veritabanındaki tüm yürütme eylemlerini denetleyen bir veritabanı denetim belirtimine sahip bir SQL Server veritabanımız var.

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

Bazı sorguların denetim günlüğüne bir sonuç kümesindeki her satır için bir skaler işlev kullanımını yazdığını bulduk. Bu olduğunda, günlük, son dinlenme yerine ETL yapabilmemiz için dolar ve günlüklememizde bir boşluk var.

Maalesef uyumluluk nedeniyle, her EXECUTEifadeyi denetlemeyi durduramayız .

Bu soruna yaklaşım için ilk düşüncemiz , etkinliği denetlemek için Sunucu DenetimindeWHERE madde kullanmaktır . Kod şöyle görünüyordu:

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

Ne yazık ki, SQL Server ilişkisel IN operatörüne izin vermez (muhtemelen denetim günlüğüne her yazmak zorunda kaldığında sorgulamak istemediği için).

Biz sert kodları saklı yordam yazılmasını önlemek istiyoruz object_idiçinde WHEREfıkra, ama bu sorunu yaklaşım en iyi yolu mevcut düşünmedir. Dikkate almamız gereken alternatif bir yaklaşım var mı?

Skalar fonksiyon özyinelemeli bir CTE'de kullanıldığında, sorgunun sonuç kümesindeki her satır için denetim günlüğüne yazmasına neden olduğunu fark ettik.

Başka bir veritabanını silemediğimiz veya başka bir veritabanına taşıyamadığımız bir satıcı tarafından teslim edilen bazı Skaler Değerli İşlevler vardır.


6
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.- Bu duyduğum skaler UDF'lerin en görkemli yan etkilerinden biri ve çok duydum.
Erik Darling

3
Ayrı bir veritabanında denetlenmesini istemediğiniz UDF'leri oluşturma ve denetlenmeyen bir seçenek var mı?
Scott Hodgin

@ScottHodgin, geçici çözümü seviyorum, ancak koşullarımızda, başka bir veritabanına silemediğimiz veya başka bir veritabanına geçemediğimiz bir satıcı tarafından sunulan bazı Skaler Değerli İşlevler vardır.
Mark Iannucci

Bunu izleyenler, sorgunun sonuç kümesindeki her satır için denetim günlüğüne yazmasına neden olan durumu merak ediyor olabilir; skaler fonksiyon tekrarlanan bir CTE'de kullanıldığında ortaya çıktığını fark ettik.
Mark Iannucci

Yanıtlar:


6

Çalışabildiğim birkaç seçenek var. Tüm seçenekler filtre tahminlerinin varyasyonlarıyla ilgilidir. NOT: değişiklik yapmak için Sunucu Denetimini devre dışı bırakmanız ve ardından yeniden etkinleştirmeniz gerekir.

Birincisi, en genel yaklaşım tüm Skaler UDF'leri filtrelemektir. Bunu class_typedenetim alanını kullanarak yapabilirsiniz . Belgeler bu alanın olduğunu gösterir VARCHAR(2), ancak dize belirtilmesine izin vermez. Ancak, çalışmak için aşağıdakileri aldım:

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

(burada bu inceleme hakkında daha fazla bilgi: Sunucu Denetim Gizemi: Class_type filtrelemek Hata Msg 25713 alır )

Bir sonraki en genel yaklaşım bir seçenek değildir, çünkü bunun satıcı tarafından sağlanan bir veritabanı olduğu ve dolayısıyla hiçbir değişiklik yapılamayacağı belirtilmiştir. Bu yüzden bunu en son ele alacağım.

En az genel yaklaşım (ancak kesinlikle işe yarayan yaklaşım) belirli işlev adını filtrelemektir:

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

Veya birden fazla ad varsa:

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

Çok genel olmasa da, filtrelenecek işlevlerin sayısı oldukça az olduğundan ve yeni işlevlerin tanıtılması çok sık olmayacağından bu yaklaşım iyi olmalıdır.

Son olarak, bu durumla karşılaşan ve değişiklik yapmakla sınırlı olmayan diğerlerine: işlevleri kendi Şemalarına yerleştirebilir ve daha sonra sadece bu Şemayı filtreleyebilirsiniz. Bu, işlevleri tek tek filtrelemekten daha geneldir. Adında bir Şema oluşturduğunuz fnve işlev (ler) i buna yerleştirdiğinizi varsayarsak :

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

AYRICA, soruya aşağıdaki iki yorum ile ilgili olarak:

Ne yazık ki, SQL Server ilişkisel IN operatörüne izin vermez (muhtemelen denetim günlüğüne her yazmak zorunda kaldığında sorgulamak istemediği için).

ve:

WHERE deyiminde object_id kodunu sabit olarak kodlayan depolanmış bir proc yazmaktan kaçınmak istiyoruz

Sorun INoperatör değil. Doğru, desteklenmiyor, ancak ORkoşulların bir listesi için sadece kısayol . Asıl mesele T-SQL kullanımıdır. Yalnızca değişmez değerlere (dize veya sayı) izin verilir. Bu nedenle, bir Saklı Yordam'ı yine de yürütemezdiniz. Yerleşik işlevleri de kullanamazsınız.


bu yanıt için teşekkür ederim. Bu değişikliği uygulama sürecindeyiz ve çevremizde çalıştığını onayladığımızda bu cevabı kabul edeceğim.
Mark Iannucci

1
@MarkIannucci Teşekkürler! Ayrıca, sadece benim ideal öneri küçük bir hata düzeltildi. HERHANGİ BİR AMA işlevi yerine FOR işlevlerini filtrelediğim testten kopyalandım ve yapıştırdım. Cevabımda =olacak şekilde değiştirdim <>. Ben de sadece test ve reklamı gibi çalışır :-)
Solomon Rutzky
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.