Ако използвате SSMS (или друг подобен инструмент), за да стартирате кода, произведен от това скрипт, ще получите точно същата грешка. Може да работи добре, когато сте вмъкнали пакетни разделители (GO
), но сега, когато не го правите, ще се сблъскате със същия проблем и в SSMS.
От друга страна, причината, поради която не можете да поставите GO
във вашите динамични скриптове е защото GO
не е SQL израз, това е просто разделител, разпознат от SSMS и някои други инструменти. Вероятно вече сте наясно с това.
Както и да е, смисълът на GO
е инструментът да знае, че кодът трябва да бъде разделен и неговите части да се изпълняват отделно . И това, отделно , е това, което трябва да направите и във вашия код.
И така, имате следните опции:
-
вмъкнете
EXEC sp_execute @sql
точно след частта, която изпуска тригера, след което нулирайте стойността на@sql
за да съхрани и изпълни дефиниционната част на свой ред; -
използвайте две променливи,
@sql1
и@sql2
, съхранете частта IF EXISTS/DROP в@sql1
, този CREATE TRIGGER в@sql2
, след което изпълнете и двата скрипта (отново поотделно).
Но след това, както вече разбрахте, ще се сблъскате с друг проблем:не можете да създадете тригер в друга база данни, без да изпълните оператора в контекста на тази база данни .
Сега има 2 начина за предоставяне на необходимия контекст:
1) използвайте USE
изявление;
2) изпълнете израза(ите) като динамична заявка с помощта на EXEC targetdatabase..sp_executesql N'…'
.
Очевидно първата опция няма да работи тук:не можем да добавим USE …
преди CREATE TRIGGER
, тъй като последният трябва да е единственият израз в пакета.
Втората опция може да се използва, но ще изисква допълнителен слой динамика (не съм сигурен дали е дума). Това е така, защото името на базата данни е параметър тук и затова трябва да изпълним EXEC targetdatabase..sp_executesql N'…'
като динамичен скрипт и тъй като самият скрипт, който трябва да се изпълнява, се предполага, че е динамичен скрипт, той следователно ще бъде вложен два пъти.
И така, преди (втория) EXEC sp_executesql @sql;
ред добавете следното:
SET @sql = N'EXEC ' + @dbname + '..sp_executesql N'''
+ REPLACE(@sql, '''', '''''') + '''';
Както можете да видите, за интегриране на съдържанието на @sql
като правилно вложен динамичен скрипт, те трябва да бъдат оградени в единични кавички. По същата причина всяка една кавичка in @sql
трябва да се удвои (напр. с помощта на REPLACE()
функция
, както в горното твърдение).