T-SQL

Spouštění skriptů ze souboru

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

Run-Query-From-File-1

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:

Management-Studio-SQLCMD-Mode

Spuštění našeho souboru provedeme použitím příkazu :r :

Management-Studio-SQLCMD-Mode-Run-Script

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:

Management-Studio-SQLCMD-Mode-Run-Script-Multiple

Management-Studio-SQLCMD-Mode-Run-Script-Multiple-Result

To podstatné se ovšem odehrálo na pozadí, kdy jsme zachytili v Profileru následující batch:

Management-Studio-SQLCMD-Mode-Run-Script-Multiple-Profiler

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:

Management-Studio-SQLCMD-Mode-Run-Script-Multiple-Error

Odpověď je opět v Profileru:

Management-Studio-SQLCMD-Mode-Run-Script-Multiple-Error-Profiler

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ě:

Management-Studio-SQLCMD-Mode-Run-Script-Multiple-Error-Fixed

Leave a Reply

Your email address will not be published. Required fields are marked *