Pokud používáte SSMS (nebo jiný podobný nástroj) ke spuštění kódu vytvořeného tím skript, dostanete přesně stejnou chybu. Mohlo by to běžet v pořádku, když vložíte oddělovače dávek (GO ), ale teď, když to neuděláte, budete čelit stejnému problému i v SSMS.
Na druhou stranu, důvod, proč nemůžete vložit GO ve vašich dynamických skriptech je to proto, že GO není SQL příkaz, je to pouze oddělovač rozpoznávaný SSMS a některými dalšími nástroji. Pravděpodobně jste si toho již vědomi.
Každopádně smyslem GO je pro nástroj, aby věděl, že kód by měl být rozdělen a jeho části běžet odděleně . A to samostatně , je to, co byste měli udělat i ve svém kódu.
Máte tedy tyto možnosti:
-
vložte
EXEC sp_execute @sqlhned za částí, která spouští spoušť, potom resetujte hodnotu@sqlpoté uložit a spustit definiční část ve svém tahu; -
použijte dvě proměnné,
@sql1a@sql2, uložte část IF EXISTS/DROP do@sql1, CREATE TRIGGER jeden do@sql2a poté spusťte oba skripty (opět samostatně).
Ale pak, jak jste již zjistili, budete čelit dalšímu problému:nemůžete vytvořit spouštěč v jiné databázi bez spuštění příkazu v kontextu této databáze .
Nyní existují 2 způsoby, jak poskytnout potřebný kontext:
1) použijte USE prohlášení;
2) spusťte příkaz(y) jako dynamický dotaz pomocí EXEC targetdatabase..sp_executesql N'…' .
Je zřejmé, že první možnost zde nebude fungovat:nemůžeme přidat USE … před CREATE TRIGGER , protože druhý příkaz musí být jediným příkazem v dávce.
Druhá možnost může použít, ale bude to vyžadovat další vrstvu dynamiky (nejsem si jistý, jestli je to slovo). Je to proto, že název databáze je zde parametrem, a proto musíme spustit EXEC targetdatabase..sp_executesql N'…' jako dynamický skript, a protože skutečný skript, který se má spustit, má být sám o sobě dynamickým skriptem, bude proto vnořen dvakrát.
Tedy před (druhým) EXEC sp_executesql @sql; řádek přidejte následující:
SET @sql = N'EXEC ' + @dbname + '..sp_executesql N'''
+ REPLACE(@sql, '''', '''''') + '''';
Jak můžete vidět, integrovat obsah @sql jako správně vnořený dynamický skript musí být uzavřeny v jednoduchých uvozovkách. Ze stejného důvodu jsou všechny uvozovky v @sql musí být zdvojnásobeno (např. pomocí REPLACE() funkce
, jako ve výše uvedeném prohlášení).