Als u SSMS (of een ander soortgelijk hulpmiddel) gebruikt om de code uit te voeren die door dit is geproduceerd script, krijg je precies dezelfde fout. Het zou goed kunnen werken als u batchscheidingstekens invoegde (GO
), maar nu je dat niet doet, zul je hetzelfde probleem ook in SSMS tegenkomen.
Aan de andere kant, de reden waarom u GO
. niet kunt plaatsen in uw dynamische scripts is omdat GO
is geen SQL-instructie, het is slechts een scheidingsteken dat wordt herkend door SSMS en enkele andere tools. Waarschijnlijk weet je dat al.
Hoe dan ook, het punt van GO
is dat de tool weet dat de code moet worden gesplitst en dat de delen ervan afzonderlijk moeten worden uitgevoerd . En dat, afzonderlijk , is wat u ook in uw code zou moeten doen.
Je hebt dus deze opties:
-
voeg
EXEC sp_execute @sql
in net na het deel dat de trigger laat vallen, reset dan de waarde van@sql
om vervolgens het definitiegedeelte op zijn beurt op te slaan en uit te voeren; -
gebruik twee variabelen,
@sql1
en@sql2
, sla het IF EXISTS/DROP-gedeelte op in@sql1
, de CREATE TRIGGER een in@sql2
en voer vervolgens beide scripts uit (opnieuw, afzonderlijk).
Maar dan, zoals je al hebt ontdekt, krijg je te maken met een ander probleem:je kunt geen trigger maken in een andere database zonder de instructie in de context van die database uit te voeren .
Er zijn nu 2 manieren om de nodige context te bieden:
1) gebruik een USE
verklaring;
2) voer de instructie(s) uit als een dynamische query met behulp van EXEC targetdatabase..sp_executesql N'…'
.
Het is duidelijk dat de eerste optie hier niet werkt:we kunnen USE …
niet toevoegen voor CREATE TRIGGER
, omdat de laatste de enige verklaring in de batch moet zijn.
De tweede optie kan worden gebruikt, maar het vereist een extra laag dynamiek (weet niet of het een woord is). Het is omdat de databasenaam hier een parameter is en daarom moeten we EXEC targetdatabase..sp_executesql N'…'
als een dynamisch script, en aangezien het eigenlijke script dat moet worden uitgevoerd zelf een dynamisch script moet zijn, wordt het daarom twee keer genest.
Dus, vóór de (tweede) EXEC sp_executesql @sql;
regel voeg het volgende toe:
SET @sql = N'EXEC ' + @dbname + '..sp_executesql N'''
+ REPLACE(@sql, '''', '''''') + '''';
Zoals je kunt zien, om de inhoud van @sql
te integreren als een genest dynamisch script correct is, moeten ze tussen enkele aanhalingstekens worden geplaatst. Om dezelfde reden is elk aanhalingsteken in @sql
moet worden verdubbeld (bijvoorbeeld met behulp van de REPLACE()
functie
, zoals in de bovenstaande verklaring).