Placez le script entier dans une chaîne de modèle, avec des espaces réservés {SERVERNAME}. Modifiez ensuite la chaîne en utilisant:
SET @SQL_SCRIPT = REPLACE(@TEMPLATE, '{SERVERNAME}', @DBNAME)
puis exécutez-le avec
EXECUTE (@SQL_SCRIPT)
Difficile de croire qu'en l'espace de trois ans, personne n'a remarqué que mon code ne fonctionne pas !
Vous ne pouvez pas EXEC
plusieurs lots. GO
est un séparateur de lots, pas une instruction T-SQL. Il est nécessaire de créer trois chaînes distinctes, puis EXEC
chacune après la substitution.
Je suppose que l'on pourrait faire quelque chose d '"intelligent" en divisant la chaîne de modèle unique en plusieurs lignes en la divisant GO
; Je l'ai fait dans le code ADO.NET.
Et d'où vient le mot "SERVERNAME"?
Voici un code que je viens de tester (et qui fonctionne):
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
serait un type de données plus approprié que celuiVARCHAR(255)
qui devrait également utiliserQUOTENAME
pour traiter tous les noms de bases de données possibles (et éventuellement pour empêcher l'injection SQL en fonction de la source du nom)CREATE SCHEMA
dans une autre base de données, en utilisantUSE {DBNAME}
. Le schéma crée dans la mauvaise base de données; /Vous pouvez également utiliser le
sqlcmd
mode pour cela (activez-le dans le menu "Requête" de Management Studio).ÉDITER:
Consultez cet article MSDN pour définir les paramètres via l'outil SQLCMD.
la source
Malheureusement, vous ne pouvez pas déclarer les noms de base de données avec une variable dans ce format.
Pour ce que vous essayez d'accomplir, vous allez devoir encapsuler vos déclarations dans une instruction EXEC (). Vous auriez donc quelque chose comme:
Puis appelez
pour exécuter la chaîne sql.
la source
EXEC
recherche une procédure stockée. Dans ce casEXECUTE
est nécessaire.EXEC
etEXECUTE
sont les mêmes. J'ai fait cette déclaration après avoir échouéEXEC
et réussiEXECUTE
. Bien évidemment, mon vrai problème n'était pas lié à l'un ou l'autre.Vous ne pouvez pas utiliser une variable dans une instruction create table. La meilleure chose que je puisse suggérer est d'écrire la requête entière sous forme de chaîne et de l'exécuter.
Essayez quelque chose comme ceci:
la source