Saya memiliki tabel dengan 42 kolom dan pemicu yang harus melakukan beberapa hal ketika 38 kolom ini diperbarui. Jadi, saya perlu melewati logika jika 4 kolom sisanya diubah.
Saya dapat menggunakan fungsi UPDATE () dan membuat satu IF
kondisi besar , tetapi lebih suka melakukan sesuatu yang lebih pendek. Menggunakan COLUMNS_UPDATED saya dapat memeriksa apakah semua kolom tertentu diperbarui?
Misalnya, memeriksa apakah kolom 3, 5 dan 9 diperbarui:
IF
(
(SUBSTRING(COLUMNS_UPDATED(),1,1) & 20 = 20)
AND
(SUBSTRING(COLUMNS_UPDATED(),2,1) & 1 = 1)
)
PRINT 'Columns 3, 5 and 9 updated';
Jadi, nilai 20
untuk kolom 3
dan 5
, dan nilai 1
untuk kolom 9
karena diatur dalam bit pertama dari byte kedua. Jika saya mengubah pernyataan untuk OR
itu akan memeriksa apakah kolom 3
dan 5
atau kolom 9
diperbarui?
Bagaimana bisa menerapkan OR
logika dalam konteks satu byte?
sql-server
t-sql
trigger
Gotqn
sumber
sumber
SET
daftar, atau apakah nilainya benar-benar berubah? KeduanyaUPDATE
danCOLUMNS_UPDATED()
hanya memberitahu Anda yang pertama. Jika Anda ingin tahu apakah nilainya benar-benar berubah, Anda harus melakukan perbandinganinserted
dandeleted
.SUBSTRING
untuk membagi formulir nilai yang dikembalikanCOLUMNS_UPDATED()
, Anda harus menggunakan perbandingan bitwise, seperti yang ditunjukkan dalam dokumentasi . Berhati-hatilah bahwa jika Anda mengubah tabel dengan cara apa pun, urutan nilai yang dikembalikan olehCOLUMNS_UPDATED()
akan berubah.SET
atauUPDATE
, Anda mungkin ingin melihat menggunakanCHECKSUM()
atauBINARY_CHECKSUM()
, atau bahkan diHASHBYTES()
atas kolom yang dimaksud.Jawaban:
Anda dapat menggunakan
CHECKSUM()
metodologi yang cukup sederhana untuk membandingkan nilai aktual untuk melihat apakah mereka diubah.CHECKSUM()
akan menghasilkan checksum di seluruh daftar nilai yang diteruskan, di mana jumlah dan jenisnya tidak ditentukan. Hati-hati, ada kemungkinan kecil membandingkan checksum seperti ini akan menghasilkan negatif palsu. Jika Anda tidak dapat menghadapi itu, Anda dapat menggunakanHASHBYTES
sebagai gantinya 1 .Contoh di bawah ini menggunakan
AFTER UPDATE
pemicu untuk mempertahankan riwayat modifikasi yang dibuat keTriggerTest
tabel hanya jika salah satu nilai dalam kolomData1
atauData2
berubah. JikaData3
berubah, tidak ada tindakan yang diambil.Jika Anda ngotot menggunakan fungsi COLUMNS_UPDATED () , Anda tidak boleh meng -hard-code nilai ordinal kolom yang bersangkutan, karena definisi tabel mungkin berubah, yang bisa membuat nilai-nilai hard-code tidak valid. Anda bisa menghitung berapa nilainya saat runtime menggunakan tabel sistem. Ketahuilah bahwa
COLUMNS_UPDATED()
fungsi mengembalikan true untuk bit kolom yang diberikan jika kolom diubah dalam baris APA PUN yang dipengaruhi olehUPDATE TABLE
pernyataan.Demo ini menyisipkan baris ke tabel sejarah yang mungkin tidak boleh dimasukkan. Baris telah
Data1
diperbarui kolomnya untuk beberapa baris, danData3
kolom diperbarui untuk beberapa baris. Karena ini adalah pernyataan tunggal, semua baris diproses oleh satu melewati pemicu. Karena beberapa baris telahData1
diperbarui, yang merupakan bagian dariCOLUMNS_UPDATED()
perbandingan, semua baris yang dilihat oleh pelatuk dimasukkan ke dalamTriggerHistory
tabel. Jika ini "salah" untuk skenario Anda, Anda mungkin perlu menangani setiap baris secara terpisah, menggunakan kursor.The
TriggerResult
meja sekarang memiliki beberapa baris berpotensi menyesatkan yang terlihat seperti mereka tidak milik karena mereka menunjukkan benar-benar tidak ada perubahan (ke dua kolom dalam tabel itu). Dalam rangkaian baris ke-2 pada gambar di bawah ini, TriggerTestID 7 adalah satu-satunya yang sepertinya dimodifikasi. Baris lain hanya memilikiData3
kolom diperbarui; namun karena satu baris dalam kumpulan telahData1
diperbarui, semua baris dimasukkan dalamTriggerResult
tabel.Sebagai alternatif, seperti yang ditunjukkan oleh @AaronBertrand dan @srutzky, Anda dapat melakukan perbandingan data aktual di
inserted
dandeleted
tabel virtual. Karena struktur kedua tabel identik, Anda bisa menggunakanEXCEPT
klausa di pemicu untuk menangkap baris di mana kolom yang tepat Anda tertarik telah berubah:1 - lihat /programming/297960/hash-collision-what-are-the-chances untuk diskusi tentang peluang kecil yang semakin menghilang sehingga perhitungan HASHBYTES juga dapat mengakibatkan tabrakan. Preshing juga memiliki analisis yang layak untuk masalah ini.
sumber
HASHBYTES
." menyesatkan. Memang benar bahwaHASHBYTES
adalah kurang mungkin untuk memiliki negatif palsu dariCHECKSUM
(kemungkinan yang bervariasi pada ukuran algoritma yang digunakan), tetapi tidak dapat dikesampingkan. Setiap fungsi hashing akan selalu memiliki potensi untuk mengalami tabrakan karena kemungkinan besar akan berkurang informasinya. Satu-satunya cara untuk menjadi tertentu tidak ada perubahan adalah untuk membandingkanINSERTED
danDELETED
tabel, dan menggunakan_BIN2
pemeriksaan jika data string. Membandingkan hash hanya memberikan kepastian untuk perbedaan.