Saya perlu menulis Sisipan, Perbarui Pemicu pada tabel A yang akan menghapus semua baris dari tabel B yang satu kolomnya (katakanlah Desc) memiliki nilai seperti nilai yang dimasukkan / diperbarui di kolom tabel A (misalkan Col1). Bagaimana saya berkeliling menulis sehingga saya bisa menangani Pembaruan dan Masukkan kasus. Bagaimana saya menentukan apakah pelatuk dijalankan untuk pembaruan atau masukkan.
sumber
sumber
Banyak dari saran ini tidak memperhitungkan jika Anda menjalankan pernyataan hapus yang tidak menghapus apa pun.
Katakanlah Anda mencoba menghapus di mana ID sama dengan beberapa nilai yang tidak ada dalam tabel.
Pemicu Anda masih dipanggil tetapi tidak ada dalam tabel Dihapus atau Dimasukkan.
Gunakan ini agar aman:
Terima kasih khusus kepada @KenDog dan @Net_Prog atas jawaban mereka.
Saya membangun ini dari skrip mereka.
sumber
Saya menggunakan yang berikut ini, juga mendeteksi dengan benar pernyataan yang tidak menghapus apa pun:
sumber
Setelah banyak pencarian saya tidak dapat menemukan contoh yang tepat dari pemicu SQL Server tunggal yang menangani semua (3) tiga kondisi tindakan pemicu INSERT, UPDATE, dan DELETE. Saya akhirnya menemukan satu baris teks yang berbicara tentang fakta bahwa ketika DELETE atau UPDATE terjadi, tabel DELETED umum akan berisi catatan untuk dua tindakan ini. Berdasarkan informasi itu, saya kemudian membuat tindakan rutin kecil yang menentukan mengapa pemicu telah diaktifkan. Jenis antarmuka ini kadang-kadang diperlukan ketika ada konfigurasi umum dan tindakan khusus untuk terjadi pada pemicu INSERT vs UPDATE. Dalam kasus ini, membuat pemicu terpisah untuk UPDATE dan INSERT akan menjadi masalah pemeliharaan. (Yaitu kedua pemicu diperbarui dengan benar untuk memperbaiki algoritma data umum yang diperlukan?)
Untuk itu, saya ingin memberikan potongan kode peristiwa multi-pemicu berikut untuk menangani INSERT, UPDATE, DELETE dalam satu pemicu untuk Microsoft SQL Server.
sumber
Saya percaya bersarang sedikit membingungkan dan:
;)
sumber
sumber
Coba ini..
sumber
sementara saya juga menyukai jawaban yang diposting oleh @Alex, saya menawarkan variasi ini untuk solusi @ Graham di atas
ini secara eksklusif menggunakan catatan keberadaan dalam tabel INSERTED dan UPDATED, yang bertentangan dengan menggunakan COLUMNS_UPDATED untuk pengujian pertama. Ini juga memberikan bantuan programmer paranoid mengetahui bahwa kasus terakhir telah dipertimbangkan ...
Anda akan mendapatkan NOOP dengan pernyataan seperti berikut:
sumber
END
indentasi yang pertama salah! (menyebabkan mempertanyakan di mana yang pertamaBEGIN
ditutup)Ini mungkin cara yang lebih cepat:
sumber
Masalah potensial dengan dua solusi yang ditawarkan adalah, tergantung pada bagaimana mereka ditulis, permintaan pembaruan dapat memperbarui nol catatan dan permintaan memasukkan dapat memasukkan nol catatan. Dalam kasus ini, rekaman yang Dimasukkan dan Dihapus akan kosong. Dalam banyak kasus, jika kedua recordset yang Dimasukkan dan Dihapus kosong Anda mungkin hanya ingin keluar dari pelatuk tanpa melakukan apa pun.
sumber
Saya menemukan kesalahan kecil dalam Grahams jika tidak solusi keren:
Seharusnya JIKA COLUMNS_UPDATED () < > 0 - masukkan atau perbarui
daripada> 0 mungkin karena bit teratas ditafsirkan sebagai bit tanda integer SIGNED ... (?). Jadi totalnya:
sumber
Ini berguna bagi saya:
Karena tidak semua kolom dapat diperbarui pada satu waktu, Anda dapat memeriksa apakah kolom tertentu sedang diperbarui oleh sesuatu seperti ini:
sumber
sumber
Saya suka solusi yang "ilmu komputer elegan." Solusi saya di sini mengenai pseudotables [yang dimasukkan] dan [dihapus] masing-masing sekali untuk mendapatkan statusnya dan menempatkan hasilnya dalam variabel yang sedikit dipetakan. Kemudian setiap kemungkinan kombinasi INSERT, UPDATE dan DELETE dapat dengan mudah diuji di seluruh pemicu dengan evaluasi biner yang efisien (kecuali untuk kombinasi INSERT atau DELETE yang tidak mungkin).
Itu membuat asumsi bahwa tidak masalah apa pernyataan DML jika tidak ada baris yang dimodifikasi (yang harus memenuhi sebagian besar kasus). Jadi sementara itu tidak selengkap solusi Roman Pekar, itu lebih efisien.
Dengan pendekatan ini, kami memiliki kemungkinan satu pemicu "UNTUK INSERT, UPDATE, DELETE" per tabel, memberi kami A) kontrol penuh atas urutan tindakan dan b) satu implementasi kode per tindakan yang dapat diterapkan multi tindakan. (Jelas, setiap model implementasi memiliki pro dan kontra; Anda perlu mengevaluasi sistem Anda secara individual untuk apa yang benar-benar bekerja paling baik.)
Perhatikan bahwa pernyataan "ada (pilih * dari« disisipkan / dihapus »)" sangat efisien karena tidak ada akses disk ( https://social.msdn.microsoft.com/Forums/en-US/01744422-23fe-42f6 -9ab0-a255cdf2904a ).
sumber
Solusi cepat MySQL
Omong-omong: Saya menggunakan MySQL PDO.
(1) Dalam tabel kenaikan otomatis, dapatkan nilai tertinggi (nama kolom saya = id) dari kolom yang bertambah setelah setiap skrip dijalankan terlebih dahulu:
(2) Jalankan permintaan MySQL seperti biasa, dan masukkan hasilnya ke integer, misalnya:
(3) Setelah kueri "INSERT INTO ... ON DUPLICATE KEY UPDATE", dapatkan id yang disisipkan terakhir dengan cara yang Anda sukai, misalnya:
(4) Bandingkan dan bereaksi: Jika InsertId terakhir lebih tinggi dari yang tertinggi dalam tabel, itu mungkin INSERT, kan? Dan sebaliknya.
Saya tahu ini cepat dan mungkin kotor. Dan itu adalah pos lama. Tapi, hei, saya sudah mencari solusi untuk waktu yang lama, dan mungkin seseorang menemukan cara saya agak berguna. Semua yang terbaik!
sumber
hanya cara sederhana
sumber
Dalam skenario pertama saya menduga bahwa tabel Anda memiliki kolom IDENTITAS
Dalam skenario kedua tidak perlu menggunakan kolom IDENTITTY
sumber
JIKA pembaruannya
jika penyisipannya
sumber
Saya telah menggunakan
exists (select * from inserted/deleted)
pertanyaan itu untuk waktu yang lama, tapi itu masih tidak cukup untuk operasi CRUD kosong (ketika tidak ada catatan di dalaminserted
dandeleted
tabel). Jadi setelah meneliti topik ini sedikit saya menemukan solusi yang lebih tepat:Mungkin juga digunakan
columns_updated() & power(2, column_id - 1) > 0
untuk melihat apakah kolom diperbarui, tetapi tidak aman untuk tabel dengan jumlah kolom yang besar. Saya telah menggunakan cara penghitungan yang agak rumit (lihat artikel bermanfaat di bawah).Juga, pendekatan ini masih akan salah mengklasifikasikan beberapa pembaruan sebagai sisipan (jika setiap kolom dalam tabel dipengaruhi oleh pembaruan), dan mungkin itu akan mengklasifikasikan sisipan di mana hanya nilai-nilai default yang dimasukkan sebagai dihapus, tetapi mereka adalah raja operasi yang jarang (pada sewa di sistem saya mereka). Selain itu, saya tidak tahu bagaimana meningkatkan solusi ini saat ini.
sumber
sumber
saya melakukan ini:
1 -> masukkan
2 -> hapus
3 -> pembaruan
sumber
sumber