Kami memiliki database SQL Server yang memiliki spesifikasi audit database yang mengaudit semua tindakan yang dilakukan pada database.
CREATE DATABASE AUDIT SPECIFICATION [dbAudit]
FOR SERVER AUDIT [servAudit]
ADD (EXECUTE ON DATABASE::[DatabaseName] BY [public])
Kami telah menemukan bahwa beberapa pertanyaan akan menulis ke audit log penggunaan fungsi skalar untuk setiap baris di set hasil. Ketika ini terjadi, log terisi sebelum kita bisa ETL ke tempat peristirahatan terakhir dan kita memiliki celah dalam pencatatan kita.
Sayangnya karena alasan kepatuhan, kami tidak bisa berhenti mengaudit setiap EXECUTE
pernyataan.
Pikiran pertama kami untuk pendekatan masalah ini adalah menggunakan WHERE
klausa pada Server Audit untuk menyaring aktivitas. Kode tersebut terlihat seperti ini:
WHERE [object_id] not in (Select object_id from sys.objects where type = 'FN' )
Sayangnya, SQL Server tidak mengizinkan operator IN relasional (mungkin karena ia tidak ingin meminta setiap kali harus menulis ke log audit).
Kami ingin menghindari penulisan proc yang tersimpan yang kode kerasnya ada object_id
dalam WHERE
klausa, tetapi itulah pemikiran kami saat ini tentang cara terbaik untuk mendekati masalah ini. Apakah ada pendekatan alternatif yang harus kita pertimbangkan?
Kami telah memperhatikan bahwa ketika fungsi skalar digunakan dalam CTE rekursif, maka itu menyebabkan permintaan untuk menulis ke log audit untuk setiap baris dalam hasil yang ditetapkan.
Ada beberapa Fungsi Berharga Skalar yang dikirimkan oleh vendor yang tidak dapat kami hapus atau pindahkan ke database alternatif.
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.
- Itulah salah satu efek samping paling menakjubkan dari skalar UDF yang pernah saya dengar, dan saya sering mendengar.Jawaban:
Ada beberapa opsi yang bisa saya peroleh. Semua opsi berurusan dengan variasi predikat filter. CATATAN: Anda harus menonaktifkan Audit Server untuk membuat perubahan, dan kemudian mengaktifkannya kembali .
Pertama, pendekatan yang paling umum adalah menyaring semua UDF Skalar. Anda dapat melakukannya dengan menggunakan
class_type
bidang audit. Dokumentasi menunjukkan bahwa bidang iniVARCHAR(2)
, tetapi tidak memungkinkan menentukan string. Namun, saya berhasil menjalankan yang berikut ini:(info lebih lanjut tentang penyelidikan itu di sini: Misteri Audit Server: Memfilter class_type mendapat Galat Msg 25713 )
Pendekatan paling umum berikutnya bukanlah pilihan karena dinyatakan bahwa ini adalah database yang disediakan vendor dan karenanya tidak ada perubahan yang dapat dilakukan. Jadi saya akan membahas yang terakhir.
Pendekatan yang paling tidak umum (tetapi yang pasti berhasil) adalah memfilter nama fungsi tertentu:
Atau, jika banyak nama:
Meskipun tidak terlalu umum, pendekatan ini harus baik-baik saja karena jumlah fungsi untuk disaring harus cukup kecil, dan tidak akan terlalu sering bahwa fungsi-fungsi baru diperkenalkan.
Akhirnya, untuk orang lain yang menghadapi situasi ini dan tidak dibatasi membuat perubahan: Anda dapat menempatkan fungsi ke dalam Skema mereka sendiri dan kemudian menyaring hanya Skema itu. Ini lebih umum daripada memfilter fungsi secara individual. Dengan asumsi bahwa Anda membuat Skema bernama
fn
dan menempatkan fungsi ke dalamnya:JUGA, mengenai dua komentar berikut dalam pertanyaan:
dan:
The
IN
Operator tidak masalah. Benar, itu tidak didukung, tetapi hanya singkatan untuk daftarOR
kondisi. Masalah sebenarnya adalah penggunaan T-SQL. Hanya literal - string atau angka - yang diizinkan. Jadi, Anda tidak akan bisa menjalankan Prosedur Tersimpan. Anda juga tidak dapat menggunakan fungsi bawaan.sumber
=
menjadi<>
dalam jawaban saya. Saya juga baru mengujinya dan berfungsi seperti yang diiklankan :-)