Saya bekerja pada SQL Server 2008 R2.
Saya memiliki manfaat tabel yang memiliki SETELAH INSERT, pemicu UPDATE bernama tiu_benefit .
Saya ingin menulis pernyataan UPDATE untuk tabel ini untuk memperbarui 1 baris tetapi saya tidak ingin pemicu untuk menyala. Saya tahu saya dapat menonaktifkan pemicu sebelum UPDATE dan kemudian mengaktifkan pelatuk setelah UPDATE:
DISABLE TRIGGER tiu_benefit ON benefit;
GO
UPDATE benefit SET editor = 'srh' where benefit_id = 9876
GO
ENABLE TRIGGER tiu_benefit ON benefit;
GO
Tapi ini menonaktifkan dan mengaktifkan memicu akan mempengaruhi semua pengguna yang masuk saat ini. Jadi ada kemungkinan pengguna lain menjalankan UPDATE / INSERT ketika pemicu dinonaktifkan oleh skrip saya yang tidak bagus. Karena itulah saya hanya ingin menonaktifkan dan mengaktifkan pemicu untuk sesi saya saat ini. Apa itu mungkin? Jika ya tolong beri tahu caranya.
Terima kasih
Jawaban:
Saya melakukan beberapa pengujian pada ini dan saya pikir Anda akan baik-baik saja jika Anda menjalankan proses Anda dalam satu transaksi.
Dalam pengujian saya, saya hanya menyoroti dan mengeksekusi
BEGIN TRANSACTION
dan yangDISABLE TRIGGER
pertama. Saya kemudian membuka baru (kedua) jendela query dan mencoba untuk menjalankan berbagai pernyataan DML (SELECT
,INSERT
,UPDATE
DELETE
) terhadap tabel basis. Semua upaya untuk mengakses tabel dasar di jendela kueri kedua menunggu kunci yang dipegang oleh jendela dengan transaksi eksplisit. Setelah saya melakukan (atau memutar kembali) transaksi eksplisit saya, jendela kedua dapat mengakses tabel.sumber
benefit_id
:)Untuk mengatasi masalah Anda, kami harus mengambil pendekatan terprogram untuk masalah tersebut. Ada dua rute yang bisa Anda tuju di sini. Alasan untuk memerlukan pendekatan ini adalah karena Anda tidak dapat menonaktifkan pemicu untuk pernyataan tertentu, itu hanya dapat dinonaktifkan untuk keseluruhan tabel.
Opsi 1: Context_Info ()
Samuel Vanga di MS SQL Tips memiliki contoh yang bagus:
Sekarang ketika Samuel tidak ingin ingin pelatuk dieksekusi, mereka menggunakan ini:
Context_Info
menggunakan tampilan sistem berikut untuk mengambil informasi mengenai sesi saat ini:sys.dm_exec_requests
sys.dm_exec_sessions
sys.sysprocesses
Ideologinya di sini adalah bahwa string biner yang Anda setel hanya terpapar ke sesi saat ini, jadi ketika pelatuk dijalankan selama sesi Anda, ia akan melihat ruang lingkup dan pengaturan variabel
Context_info
fungsi dan itu akan melompat ke bagian melarikan diri dari pelatuk sebagai gantinya.Opsi 2: Tabel Temp
Itzik Ben-Gan memiliki solusi hebat dalam bukunya "Di dalam Microsoft SQL Server 2008 Pemrograman T-SQL: Pemrograman T-SQL" yang juga ada dalam bukunya T-SQL Querying . Masalah utama dengan
context_info
fungsi ini adalah overhead TempDB kecil.Untuk merusak kejutan tetapi tidak merusak plot buku-buku (saya merasa mereka layak dibeli dan dibaca), Anda akan mengubah pelatuk Anda.
Pemicu Anda harus melakukan pemeriksaan untuk tabel sementara. Jika tabel sementara ada, pelatuk harus tahu untuk mengakhiri dan tidak melakukan tindakan.
Dalam pernyataan pembaruan yang ingin Anda lakukan, buat tabel sementara terlebih dahulu. Itu akan terlihat dalam transaksi yang sama sebagai pemicu dan itu akan menyebabkan pemicu mengabaikan pernyataan Anda.
Contoh pemicu:
Contoh pernyataan awal saat Anda tidak ingin pemicu dijalankan:
Taruh semuanya sebagai contoh Anda:
sumber
context_info
menggunakanoriginal_login()
untuk memberi tahu pemicu untuk tidak pernah berjalan jika orang tertentu memukul pelatuk.Saya akan menggunakan salah satu
CONTEXT_INFO
atau yang lebih baruSESSION_CONTEXT
. Keduanya adalah nilai berbasis sesi.CONTEXT_INFO
adalahVARBINARY(128)
nilai tunggal . Ini telah tersedia sejak setidaknya SQL Server 2000.CONTEXT_INFO
dapat dilihat oleh siapa sajaVIEW SERVER STATE
karena merupakan bidang yang dikembalikan olehsys.dm_exec_sessions
DMV. Saya telah menggunakan yang ini sebelumnya dan bekerja dengan sangat baik.Set via SET CONTEXT_INFO
Dapatkan melalui CONTEXT_INFO () atau sys.dm_exec_sessions
Tergantung pada jenis nilai yang Anda simpan
CONTEXT_INFO
, ada beberapa nuansa yang harus diperhatikan. Saya membahasnya dalam posting blog berikut:Mengapa Tidak CONTEXT_INFO () Mengembalikan Nilai Tepat yang Ditetapkan oleh SET CONTEXT_INFO?
Session_context adalah pasangan kunci / nilai
SQL_VARIANT
nilai. Ini diperkenalkan di SQL Server 2016. Pemisahan nilai untuk tujuan yang berbeda cukup bagus. Session_context hanya dapat dilihat oleh sesi saat ini.Tetapkan nilai ini melalui sp_set_session_context
Dapatkan nilai ini melalui SESSION_CONTEXT
Satu hal yang perlu dipertimbangkan mengenai opsi tabel sementara lokal dan bahkan opsi nonaktifkan / aktifkan Pemicu: keduanya memerlukan sejumlah aktivitas penguncian dan tran log. Kedua opsi tersebut meningkatkan potensi pertikaian, meskipun minimal. Dua opsi "konteks" harus lebih ringan / hanya memori.
sumber