Spouštět sql skripty uložené například v adresáři na disku je poměrně častý úkol a my si ukážeme dva jednoduché způsoby jak na to: pomocí OPENROWSET() funkce a pomocí SQLCMD Mode nastavení Sql Server Management Studia.
Nejprve si ale musíme vytvořit testovací soubor C:\Test\Test.sql, do kterého umístíme tento jednoduchý skript:
SELECT 'HELLO WORLD' AS QueryResult
Při dalším testování musíme mít na paměti, že naše testovací instance musí mít k adresáři a souboru přístup, tzn. účtu, pod kterým instance běží, musíme přidat alespoň Read přístup.
1. OPENROWSET()
Funkce OPENROWSET() představuje ad hoc OLE DB připojení k datovému zdroji, který může být i soubor v souborovém systému:
DECLARE @Script VARCHAR(MAX) SELECT @Script = f.BulkColumn FROM OPENROWSET(BULK 'C:\Test\Test.sql', single_clob) f EXEC (@Script) GO
Obsah souboru jsme načetli do proměnné @Script a vykonali jej pomocí EXEC() příkazu.
2. SQLCMD Mode
SQLCMD mode je nastavení Management Studia, které přepne aktuálně otevřené okno do režimu, ve kterém je možné pří používat příkazy, kterým rozumí konzolová aplikace sqlcmd.exe.
Přepnutí provedeme z nabídky Query -> SQLCMD Mode:
Spuštění našeho souboru provedeme použitím příkazu :r :
Pozor ovšem musíme dát na jednu podstatnou věc: Pokud budeme tímto způsobem pouštět více souborů v jedné dávce (batch), chová se SSMS na pozadí tak, že nejprve všechny souboru spojí do jedné dávky a teprve poté je odešle na server jako jeden batch. Abychom mohli uvedené chování demonstrovat, vytvoříme si dva soubory Test1.sql a Test2.sql, do kterých umístíme tyto skripty:
-- Soubor Test1.sql SELECT 'HELLO WORLD Test1.sql' AS QueryResult -- Soubor Test2.sql SELECT 'HELLO WORLD Test2.sql' AS QueryResult
Oba soubory spustíme ze SSMS:
To podstatné se ovšem odehrálo na pozadí, kdy jsme zachytili v Profileru následující batch:
Vidíme, že SSMS nejprve spojilo oba soubory do jednoho a následně odeslalo na server jako jeden batch.
Čemu to vadí? Stačí si například vzpomenout na pravidlo, že proměnné musí být unikátní v rámci jedno batche.
Soubory upravíme takto:
--Soubor Test1.sql DECLARE @String NVARCHAR(200) SET @String = 'HELLO WORLD Test1.sql' PRINT @String --Soubor Test2.sql DECLARE @String NVARCHAR(200) SET @String = 'HELLO WORLD Test2.sql' PRINT @String
A po spuštění ze SSMS dostáváme následující chybovou hlášku:
Odpověď je opět v Profileru:
Obsah obou souborů dorazil jako jeden batch a proměnná @String je tak v jeho kontextu definována dvakrát. Řešení je nasnadě: důsledné použití GO, a to buď ve skriptech samotných:
--Soubor Test1.sql DECLARE @String NVARCHAR(200) SET @String = 'HELLO WORLD Test1.sql' PRINT @String GO --Soubor Test2.sql DECLARE @String NVARCHAR(200) SET @String = 'HELLO WORLD Test2.sql' PRINT @String GO
nebo v SSMS okně: