Jika Anda menggunakan SSMS (atau alat serupa lainnya) untuk menjalankan kode yang dihasilkan oleh ini skrip, Anda akan mendapatkan kesalahan yang persis sama. Itu bisa berjalan dengan baik ketika Anda memasukkan pembatas batch (GO
), tetapi sekarang Anda tidak melakukannya, Anda juga akan menghadapi masalah yang sama di SSMS.
Di sisi lain, alasan mengapa Anda tidak dapat memasukkan GO
dalam skrip dinamis Anda adalah karena GO
bukan pernyataan SQL, itu hanya pembatas yang dikenali oleh SSMS dan beberapa alat lainnya. Mungkin Anda sudah mengetahuinya.
Pokoknya, intinya GO
adalah alat untuk mengetahui bahwa kode harus dipecah dan bagian-bagiannya dijalankan secara terpisah . Dan itu, secara terpisah , adalah apa yang harus Anda lakukan dalam kode Anda juga.
Jadi, Anda memiliki opsi ini:
-
masukkan
EXEC sp_execute @sql
tepat setelah bagian yang melepaskan pemicu, lalu setel ulang nilai@sql
untuk kemudian menyimpan dan menjalankan bagian definisi pada gilirannya; -
gunakan dua variabel,
@sql1
dan@sql2
, simpan bagian IF EXISTS/DROP ke@sql1
, CREATE TRIGGER menjadi@sql2
, lalu jalankan kedua skrip (sekali lagi, secara terpisah).
Tetapi kemudian, seperti yang telah Anda ketahui, Anda akan menghadapi masalah lain:Anda tidak dapat membuat pemicu di database lain tanpa menjalankan pernyataan dalam konteks database itu .
Sekarang, ada 2 cara untuk menyediakan konteks yang diperlukan:
1) gunakan USE
pernyataan;
2) jalankan pernyataan sebagai kueri dinamis menggunakan EXEC targetdatabase..sp_executesql N'…'
.
Jelas, opsi pertama tidak akan berfungsi di sini:kita tidak dapat menambahkan USE …
sebelum CREATE TRIGGER
, karena yang terakhir harus menjadi satu-satunya pernyataan dalam kumpulan.
Opsi kedua bisa digunakan, tetapi akan membutuhkan lapisan tambahan dinamis (tidak yakin apakah itu sebuah kata). Itu karena nama database adalah parameter di sini dan jadi kita perlu menjalankan EXEC targetdatabase..sp_executesql N'…'
sebagai skrip dinamis, dan karena skrip yang sebenarnya untuk dijalankan adalah skrip dinamis, maka skrip tersebut akan disarangkan dua kali.
Jadi, sebelum (kedua) EXEC sp_executesql @sql;
baris tambahkan berikut ini:
SET @sql = N'EXEC ' + @dbname + '..sp_executesql N'''
+ REPLACE(@sql, '''', '''''') + '''';
Seperti yang Anda lihat, untuk mengintegrasikan konten @sql
sebagai skrip dinamis bersarang dengan benar, skrip tersebut harus diapit oleh tanda kutip tunggal. Untuk alasan yang sama, setiap tanda kutip di @sql
harus digandakan (misalnya menggunakan REPLACE()
fungsi
, seperti pada pernyataan di atas).