Problema: Mi empresa tiene varios scripts de instalación de SQL que crean una copia nueva de nuestra base de datos. Cada script se relaciona con una tarea específica de SQL. Llamo a SQLCMD repetidamente para ejecutar cada script. ¿Es posible concatenar estos scripts y ejecutarlos con una sola llamada a SQLCMD?
Solución: Sí, es posible. SQLCMD ofrece el comando :r. Cuando se encuentra :r en un script de SQL, básicamente le indica a la utilidad SQLCMD que incluya el archivo referenciado en el script de llamada. Esto te permite dividir un solo script en varios scripts que representan áreas funcionales de la base de datos o reemplazar múltiples llamadas de SQLCMD con una sola llamada a un archivo SQL principal. Además, el uso del comando :r para ejecutar múltiples scripts en un solo lote te permite definir un solo conjunto de variables que pueden ser vistas por todos los scripts incluidos (siempre que no haya un terminador GO intermedio).
SQLCMD se introdujo en SQL Server 2005 y es el reemplazo de osql, que Microsoft eliminará en una versión futura. Si no estás familiarizado con SQLCMD, es una utilidad de línea de comandos que se puede utilizar para ejecutar comandos y scripts de T-SQL desde el sistema operativo.
En el ejemplo siguiente, demostraré cómo crear una copia nueva de una base de datos de muestra llamada MSSQLTIPS utilizando múltiples scripts de SQL y una sola llamada a SQLCMD.
Primero, crea una subcarpeta en tu unidad C: llamada C:\Scripts. Almacena los siguientes scripts de SQL en esta carpeta:
Código de script para crear tablas (CREATE_TABLES.sql):
PRINT 'CREATING TABLES'
GO
IF OBJECT_ID('EMPLOYEE') IS NOT NULL
DROP TABLE DBO.EMPLOYEE
GO
CREATE TABLE DBO.EMPLOYEE (
EMPLOYEEID INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
FIRSTNAME VARCHAR(50),
LASTNAME VARCHAR(50)
)
GO
IF OBJECT_ID('TIMECARD') IS NOT NULL
DROP TABLE DBO.TIMECARD
GO
CREATE TABLE DBO.TIMECARD (
TIMECARDID INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
EMPLOYEEID INT NOT NULL,
HOURSWORKED TINYINT NOT NULL,
HOURLYRATE MONEY NOT NULL,
DATEWORKED DATETIME NOT NULL
)
GO
DECLARE @TOTAL_TABLES INT
SET @TOTAL_TABLES = 2
Código de script para insertar datos (TABLE_INSERTS.sql):
PRINT 'TOTAL TABLES CREATED = ' + CAST(@TOTAL_TABLES AS VARCHAR) GO PRINT 'INSERTING DATA INTO EMPLOYEE' GO INSERT INTO DBO.EMPLOYEE (FIRSTNAME, LASTNAME) SELECT 'JOHN', 'DOE' GO INSERT INTO DBO.EMPLOYEE (FIRSTNAME, LASTNAME) SELECT 'JANE', 'DOE' GO INSERT INTO DBO.EMPLOYEE (FIRSTNAME, LASTNAME) SELECT 'JEFF', 'DOE' GO
Código de script para crear índices (CREATE_INDEXES.sql):
PRINT 'CREATING INDEXES'
GO
IF NOT EXISTS (SELECT 1 FROM SYS.INDEXES WHERE NAME = 'IX_EMPLOYEE_LASTNAME')
CREATE INDEX IX_EMPLOYEE_LASTNAME ON DBO.EMPLOYEE(LASTNAME, FIRSTNAME)
GO
IF NOT EXISTS (SELECT 1 FROM SYS.INDEXES WHERE NAME = 'IX_TIMECARD_EMPLOYEEID')
CREATE INDEX IX_TIMECARD_EMPLOYEEID ON DBO.TIMECARD(EMPLOYEEID)
GO
Código de script para crear procedimientos (CREATE_PROCEDURES.sql):
PRINT 'CREATING PROCEDURES'
GO
IF OBJECT_ID('GET_EMPLOYEE_TIMECARDS') IS NOT NULL
DROP PROCEDURE DBO.GET_EMPLOYEE_TIMECARDS
GO
CREATE PROCEDURE DBO.GET_EMPLOYEE_TIMECARDS
@EMPLOYEEID INT
AS
SET NOCOUNT ON
SELECT * FROM DBO.EMPLOYEE E
JOIN DBO.TIMECARD T ON E.EMPLOYEEID = T.EMPLOYEEID
WHERE E.EMPLOYEEID = @EMPLOYEEID
ORDER BY DATEWORKED
GO
Código de script para crear la nueva base de datos y objetos (CREATE_DB.sql):
/* CONSTRUIR UNA BASE DE DATOS */
-- Este es el llamador principal para cada script
SET NOCOUNT ON
GO
PRINT 'CREATING DATABASE'
IF EXISTS (SELECT 1 FROM SYS.DATABASES WHERE NAME = 'MSSQLTIPS')
DROP DATABASE MSSQLTIPS
GO
CREATE DATABASE MSSQLTIPS
GO
:r c:\Scripts\CREATE_TABLES.sql
:r c:\Scripts\TABLE_INSERTS.sql
:r c:\Scripts\CREATE_INDEXES.sql
:r c:\Scripts\CREATE_PROCEDURES.sql
PRINT 'DATABASE CREATE IS COMPLETE'
GO
En la carpeta raíz C:\, crea un archivo llamado create_db.bat que se utilizará para crear la base de datos con todos los objetos:
SQLCMD -E -dmaster -ic:\Scripts\create_db.sql PAUSE
Haz doble clic en el archivo .bat para ejecutarlo. Verás que cada script se procesa y se crea la base de datos correctamente.
La utilidad SQLCMD ofrece una gran cantidad de comandos que se pueden utilizar para modificar el archivo .bat y controlar y refinar aún más la salida y el comportamiento de errores.