Bagaimana saya bisa memonitor database SQL Server untuk perubahan tabel tanpa menggunakan pemicu atau memodifikasi struktur database dengan cara apa pun? Lingkungan pemrograman pilihan saya adalah .NET dan C #.
Saya ingin dapat mendukung SQL Server 2000 SP4 atau yang lebih baru. Aplikasi saya adalah visualisasi data untuk produk perusahaan lain. Basis pelanggan kami ada ribuan, jadi saya tidak ingin harus memasukkan persyaratan bahwa kami memodifikasi tabel vendor pihak ketiga di setiap instalasi.
Dengan "perubahan ke tabel" Maksudku perubahan data tabel, bukan perubahan pada struktur tabel.
Pada akhirnya, saya ingin perubahan untuk memicu suatu peristiwa dalam aplikasi saya, daripada harus memeriksa perubahan pada suatu interval.
Tindakan terbaik yang diberikan persyaratan saya (tidak ada pemicu atau modifikasi skema, SQL Server 2000 dan 2005) tampaknya menggunakan BINARY_CHECKSUM
fungsi dalam T-SQL . Cara saya berencana untuk mengimplementasikannya adalah ini:
Setiap X detik jalankan kueri berikut:
SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*))
FROM sample_table
WITH (NOLOCK);
Dan membandingkannya dengan nilai yang disimpan. Jika nilai telah berubah, buka baris tabel demi baris menggunakan kueri:
SELECT row_id, BINARY_CHECKSUM(*)
FROM sample_table
WITH (NOLOCK);
Dan bandingkan checksum yang dikembalikan dengan nilai yang disimpan.
sumber
Jawaban:
Lihatlah perintah CHECKSUM:
Itu akan mengembalikan nomor yang sama setiap kali dijalankan asalkan isi tabel tidak berubah. Lihat posting saya tentang ini untuk informasi lebih lanjut:
CHECKSUM
Inilah cara saya menggunakannya untuk membangun kembali dependensi cache ketika tabel berubah:
ASP.NET 1.1 dependensi cache database (tanpa pemicu)
sumber
Sayangnya CHECKSUM tidak selalu berfungsi dengan baik untuk mendeteksi perubahan .
Ini hanya perhitungan primitif dan tidak ada perhitungan cyclic redundancy check (CRC).
Karenanya Anda tidak dapat menggunakannya untuk mendeteksi semua perubahan, mis. Perubahan simetris menghasilkan CHECKSUM yang sama!
E. g. solusi dengan
CHECKSUM_AGG(BINARY_CHECKSUM(*))
akan selalu memberikan 0 untuk semua 3 tabel dengan konten yang berbeda:sumber
Mengapa Anda tidak ingin menggunakan pemicu? Mereka adalah hal yang baik jika Anda menggunakannya dengan benar. Jika Anda menggunakannya sebagai cara untuk menegakkan integritas referensial saat itulah mereka beralih dari baik ke buruk. Tetapi jika Anda menggunakannya untuk pemantauan, mereka tidak benar-benar dianggap tabu.
sumber
Seberapa sering Anda perlu memeriksa perubahan dan seberapa besar (dalam hal ukuran baris) tabel dalam database? Jika Anda menggunakan
CHECKSUM_AGG(BINARY_CHECKSUM(*))
metode yang disarankan oleh John, itu akan memindai setiap baris dari tabel yang ditentukan. TheNOLOCK
petunjuk membantu, tetapi pada database besar, Anda masih memukul setiap baris. Anda juga perlu menyimpan checksum untuk setiap baris sehingga Anda tahu ada yang berubah.Sudahkah Anda mempertimbangkan untuk melakukan ini dari sudut yang berbeda? Jika Anda tidak ingin memodifikasi skema untuk menambahkan pemicu, (yang masuk akal, ini bukan database Anda), sudahkah Anda mempertimbangkan bekerja dengan vendor aplikasi yang membuat database?
Mereka dapat menerapkan API yang menyediakan mekanisme untuk memberi tahu aplikasi aksesori bahwa data telah berubah. Ini bisa sesederhana menulis ke tabel notifikasi yang mencantumkan tabel apa dan baris mana yang dimodifikasi. Itu bisa diimplementasikan melalui pemicu atau kode aplikasi. Dari pihak Anda, ti tidak masalah, satu-satunya masalah Anda akan memindai tabel notifikasi secara berkala. Kinerja yang dicapai pada database akan jauh lebih sedikit daripada memindai setiap baris untuk perubahan.
Bagian yang sulit adalah meyakinkan vendor aplikasi untuk mengimplementasikan fitur ini. Karena ini dapat ditangani sepenuhnya melalui SQL melalui pemicu, Anda bisa melakukan sebagian besar pekerjaan untuk mereka dengan menulis dan menguji pemicu dan kemudian membawa kode ke vendor aplikasi. Dengan meminta vendor mendukung pemicu, itu mencegah situasi di mana Anda menambahkan pemicu secara tidak sengaja menggantikan pemicu yang disediakan oleh vendor.
sumber
Sayangnya, saya tidak berpikir bahwa ada cara bersih untuk melakukan ini di SQL2000. Jika Anda mempersempit persyaratan Anda ke SQL Server 2005 (dan lebih baru), maka Anda berada dalam bisnis. Anda bisa menggunakan
SQLDependency
kelas diSystem.Data.SqlClient
. Lihat Pemberitahuan Permintaan di SQL Server (ADO.NET) .sumber
Memiliki pekerjaan DTS (atau pekerjaan yang dimulai oleh layanan windows) yang berjalan pada interval tertentu. Setiap kali dijalankan, ia mendapat informasi tentang tabel yang diberikan dengan menggunakan tabel sistem INFORMATION_SCHEMA , dan mencatat data ini dalam repositori data. Bandingkan data yang dikembalikan mengenai struktur tabel dengan data yang dikembalikan pada waktu sebelumnya. Jika berbeda, maka Anda tahu bahwa strukturnya telah berubah.
Contoh permintaan untuk mengembalikan informasi mengenai semua kolom dalam tabel ABC (idealnya mencantumkan hanya kolom dari tabel INFORMATION_SCHEMA yang Anda inginkan, daripada menggunakan * pilih ** seperti yang saya lakukan di sini):
Anda akan memantau kolom yang berbeda dan tampilan INFORMATION_SCHEMA tergantung pada bagaimana Anda mendefinisikan "perubahan ke tabel".
sumber
Tebakan liar di sini: Jika Anda tidak ingin mengubah tabel pihak ketiga, dapatkah Anda membuat tampilan lalu meletakkan pemicu pada tampilan itu?
sumber
Periksa tanggal komit terakhir. Setiap basis data memiliki riwayat kapan setiap komit dibuat. Saya percaya ini adalah standar kepatuhan ACID.
sumber