Kami menggunakan CDC untuk menangkap perubahan yang dilakukan pada tabel produksi. Baris yang diubah diekspor ke gudang data (informatica). Saya tahu bahwa kolom __ $ update_mask menyimpan kolom apa saja yang diperbarui dalam bentuk varbinary. Saya juga tahu bahwa saya bisa menggunakan berbagai fungsi CDC untuk mencari tahu dari topeng itu apa kolom-kolom itu.
Pertanyaan saya adalah ini. Adakah yang bisa mendefinisikan logika di balik topeng itu untuk kami sehingga kami dapat mengidentifikasi kolom yang diubah di gudang? Karena kami sedang memproses di luar server, kami tidak memiliki akses mudah ke fungsi-fungsi MSSQL CDC. Saya lebih suka memecah topeng sendiri dalam kode. Kinerja fungsi cdc di SQL end bermasalah untuk solusi ini.
Singkatnya, saya ingin mengidentifikasi kolom yang diubah dengan tangan dari bidang __ $ update_mask.
Memperbarui:
Sebagai alternatif, mengirimkan daftar kolom perubahan yang dapat dibaca manusia ke gudang juga dapat diterima. Kami menemukan ini dapat dilakukan dengan kinerja yang jauh lebih besar daripada pendekatan awal kami.
Jawaban CLR untuk pertanyaan ini di bawah ini memenuhi alternatif ini dan termasuk rincian menafsirkan topeng untuk pengunjung masa depan. Namun jawaban yang diterima menggunakan XML PATH adalah yang tercepat namun untuk hasil akhir yang sama.
sumber
Jawaban:
Dan moral dari cerita ini adalah ... ujian, coba hal-hal lain, berpikir besar, lalu kecil, selalu menganggap ada cara yang lebih baik.
Secara ilmiah menarik seperti jawaban terakhir saya. Saya memutuskan untuk mencoba satu pendekatan lain. Saya ingat saya bisa melakukan concat dengan trik XML PATH (''). Karena saya tahu bagaimana cara mendapatkan ordinal dari setiap kolom yang diubah dari daftar capt_column dari jawaban sebelumnya, saya pikir akan layak untuk diuji jika fungsi bit MS akan bekerja lebih baik seperti itu untuk apa yang kami butuhkan.
Ini jauh lebih bersih daripada (meskipun tidak menyenangkan) semua CLR itu, mengembalikan pendekatan kembali ke kode SQL asli saja. Dan, drum roll .... mengembalikan hasil yang sama dalam waktu kurang dari satu detik . Karena data produksi adalah 100 kali lebih besar setiap detik diperhitungkan.
Saya meninggalkan jawaban yang lain untuk tujuan ilmiah - tetapi untuk sekarang, ini adalah jawaban yang benar.
sumber
Jadi, setelah beberapa penelitian kami memutuskan untuk tetap melakukan ini di sisi SQL sebelum menyerahkan ke gudang data. Tetapi kami mengambil pendekatan yang jauh lebih baik ini (berdasarkan kebutuhan dan pemahaman baru tentang cara kerja topeng).
Kami mendapatkan daftar nama kolom dan posisi ordinal mereka dengan pertanyaan ini. Pengembalian kembali dalam format XML sehingga kita bisa beralih ke SQL CLR.
Kami kemudian meneruskan blok XML itu sebagai variabel dan bidang mask ke fungsi CLR yang mengembalikan string kolom yang koma yang diubah per bidang biner _ $ update_mask. Fungsi clr ini menginterogasi bidang mask untuk bit perubahan untuk setiap kolom dalam daftar xml dan kemudian mengembalikan namanya dari ordinal terkait.
Kode c # clr terlihat seperti ini: (dikompilasi ke dalam rakitan yang disebut CDCUtilities)
Dan fungsi untuk CLR seperti ini:
Kami kemudian menambahkan daftar kolom ini ke rowset dan meneruskannya ke gudang data untuk dianalisis. Dengan menggunakan kueri dan CLR kami menghindari keharusan menggunakan dua panggilan fungsi per baris per perubahan. Kita dapat langsung beralih ke daging dengan hasil yang disesuaikan untuk instance tangkapan perubahan kita.
Berkat posting stackoverflow ini disarankan oleh Jon Seigel untuk cara yang menafsirkan topeng.
Dalam pengalaman kami dengan pendekatan ini, kami dapat memperoleh daftar semua kolom yang diubah dari baris 10k cdc dalam waktu kurang dari 3 detik.
sumber