Hvis du bruger SSMS (eller andet lignende værktøj) til at køre koden produceret af dette script, vil du få nøjagtig den samme fejl. Det kunne køre godt, når du indsatte batch-afgrænsere (GO
), men nu hvor du ikke gør det, vil du også stå over for det samme problem i SSMS.
På den anden side grunden til, at du ikke kan sætte GO
i dine dynamiske scripts skyldes GO
er ikke en SQL-sætning, det er blot en afgrænsning, der genkendes af SSMS og nogle andre værktøjer. Det er du sikkert allerede klar over.
Uanset hvad, pointen med GO
er for værktøjet at vide, at koden skal opdeles og dens dele køre separat . Og det, separat , er hvad du også skal gøre i din kode.
Så du har disse muligheder:
-
indsæt
EXEC sp_execute @sql
lige efter den del, der slipper triggeren, skal du nulstille værdien af @sql
for derefter at gemme og køre definitionsdelen på sin side; -
brug to variable,
@sql1
og@sql2
, gem IF EXISTS/DROP-delen i@sql1
, CREATE TRIGGER en til@sql2
, kør derefter begge scripts (igen, separat).
Men så, som du allerede har fundet ud af, står du over for et andet problem:du kan ikke oprette en trigger i en anden database uden at køre sætningen i konteksten af den database .
Nu er der 2 måder at give den nødvendige kontekst på:
1) brug en USE
erklæring;
2) kør sætningen/sætningerne som en dynamisk forespørgsel ved hjælp af EXEC targetdatabase..sp_executesql N'…'
.
Den første mulighed vil naturligvis ikke fungere her:vi kan ikke tilføje USE …
før CREATE TRIGGER
, fordi sidstnævnte skal være den eneste sætning i batchen.
Den anden mulighed kan bruges, men det vil kræve et ekstra lag af dynamik (ikke sikker på om det er et ord). Det er fordi databasenavnet er en parameter her, og derfor skal vi køre EXEC targetdatabase..sp_executesql N'…'
som et dynamisk script, og da det faktiske script, der skal køres, i sig selv formodes at være et dynamisk script, vil det derfor blive indlejret to gange.
Så før (anden) EXEC sp_executesql @sql;
linje tilføje følgende:
SET @sql = N'EXEC ' + @dbname + '..sp_executesql N'''
+ REPLACE(@sql, '''', '''''') + '''';
Som du kan se, for at integrere indholdet af @sql
som et indlejret dynamisk script korrekt, skal de være omgivet af enkelte anførselstegn. Af samme grund, hvert enkelt anførselstegn i @sql
skal fordobles (f.eks. ved at bruge REPLACE()
funktion
, som i ovenstående erklæring).