Coloque el script completo en una cadena de plantilla, con marcadores de posición {SERVERNAME}. Luego edite la cadena usando:
SET @SQL_SCRIPT = REPLACE(@TEMPLATE, '{SERVERNAME}', @DBNAME)
y luego ejecutarlo con
EXECUTE (@SQL_SCRIPT)
¡Es difícil creer que, en el transcurso de tres años, nadie se dio cuenta de que mi código no funciona !
No puedes EXEC
varios lotes. GO
es un separador de lotes, no una declaración T-SQL. Es necesario construir tres cadenas separadas y luego EXEC
cada una después de la sustitución.
Supongo que uno podría hacer algo "inteligente" al dividir la cadena de plantilla única en varias filas dividiéndola GO
; Lo hice en el código ADO.NET.
¿Y de dónde saqué la palabra "SERVERNAME"?
Aquí hay un código que acabo de probar (y que funciona):
DECLARE @DBNAME VARCHAR(255)
SET @DBNAME = 'TestDB'
DECLARE @CREATE_TEMPLATE VARCHAR(MAX)
DECLARE @COMPAT_TEMPLATE VARCHAR(MAX)
DECLARE @RECOVERY_TEMPLATE VARCHAR(MAX)
SET @CREATE_TEMPLATE = 'CREATE DATABASE {DBNAME}'
SET @COMPAT_TEMPLATE='ALTER DATABASE {DBNAME} SET COMPATIBILITY_LEVEL = 90'
SET @RECOVERY_TEMPLATE='ALTER DATABASE {DBNAME} SET RECOVERY SIMPLE'
DECLARE @SQL_SCRIPT VARCHAR(MAX)
SET @SQL_SCRIPT = REPLACE(@CREATE_TEMPLATE, '{DBNAME}', @DBNAME)
EXECUTE (@SQL_SCRIPT)
SET @SQL_SCRIPT = REPLACE(@COMPAT_TEMPLATE, '{DBNAME}', @DBNAME)
EXECUTE (@SQL_SCRIPT)
SET @SQL_SCRIPT = REPLACE(@RECOVERY_TEMPLATE, '{DBNAME}', @DBNAME)
EXECUTE (@SQL_SCRIPT)
SYSNAME
sería un tipo de datos más apropiado que el queVARCHAR(255)
debería usarseQUOTENAME
para tratar con todos los nombres de bases de datos posibles (y posiblemente para evitar la inyección de SQL dependiendo de la fuente del nombre)CREATE SCHEMA
en otra base de datos, usandoUSE {DBNAME}
. El esquema se crea en una base de datos incorrecta; /También puede usar el
sqlcmd
modo para esto (habilítelo en el menú "Consulta" en Management Studio).EDITAR:
Consulte este artículo de MSDN para establecer parámetros a través de la herramienta SQLCMD.
fuente
Lamentablemente, no puede declarar nombres de bases de datos con una variable en ese formato.
Para lo que está tratando de lograr, necesitará ajustar sus declaraciones dentro de una declaración EXEC (). Entonces tendrías algo como:
Luego llame
para ejecutar la cadena sql.
fuente
EXEC
busca un procedimiento almacenado. En este casoEXECUTE
es necesario.EXEC
yEXECUTE
son los mismos. Hice la declaración después de fallarEXEC
y tener éxitoEXECUTE
. Aunque obviamente mi verdadero problema no estaba relacionado con ninguno de los dos.No puede usar una variable en una instrucción de creación de tabla. Lo mejor que puedo sugerir es escribir toda la consulta como una cadena y ejecutar eso.
Intenta algo como esto:
fuente