sql >> Databáze >  >> RDS >> Sqlserver

dynamická chyba SQL:'CREATE TRIGGER' musí být prvním příkazem v dávce dotazu

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 @sql hned za částí, která spouští spoušť, potom resetujte hodnotu @sql poté uložit a spustit definiční část ve svém tahu;

  • použijte dvě proměnné, @sql1 a @sql2 , uložte část IF EXISTS/DROP do @sql1 , CREATE TRIGGER jeden do @sql2 a 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í).



  1. SQL Not Empty namísto Not NULL

  2. Získání přesného času provedení příkazu MySQL

  3. Návrh databáze MySql pro kvízový program

  4. Spojení SQL versus poddotazy SQL (výkon)?