J'utilise un projet de base de données SQL 2008 (dans Visual Studio) pour gérer le schéma et les données de test initiales de mon projet. Le projet atabase utilise un post-déploiement qui comprend un certain nombre d'autres scripts utilisant la syntaxe ": r" de SQLCMD.
Je voudrais pouvoir inclure conditionnellement certains fichiers basés sur une variable SQLCMD. Cela me permettra d'exécuter le projet plusieurs fois avec notre build nocturne pour configurer différentes versions de la base de données avec différentes configurations des données (pour un système multi-locataire).
J'ai essayé ce qui suit:
IF ('$(ConfigSetting)' = 'Configuration1')
BEGIN
print 'inserting specific configuration'
:r .\Configuration1\Data.sql
END
ELSE
BEGIN
print 'inserting generic data'
:r .\GenericConfiguration\Data.sql
END
Mais j'obtiens une erreur de compilation: SQL01260: Une erreur fatale de l'analyseur s'est produite: Script.PostDeployment.sql
Quelqu'un a-t-il vu cette erreur ou réussi à configurer son script de post-déploiement pour être flexible de cette manière? Ou est-ce que je me trompe complètement?
Merci, Rob
P.S. J'ai également essayé de changer cela pour que le chemin d'accès au fichier soit une variable, similaire à cet article . Mais cela me donne une erreur en disant que le chemin est incorrect.
[~ # ~] mise à jour [~ # ~]
J'ai maintenant découvert que la syntaxe if/else ci-dessus ne fonctionne pas pour moi car certains de mes scripts liés nécessitent une instruction GO. Essentiellement, le: r importe simplement les scripts en ligne, donc cela devient une syntaxe invalide.
Si vous avez besoin d'une instruction GO dans les scripts liés (comme je le fais), il n'y a pas de moyen facile de contourner cela, j'ai fini par créer plusieurs scripts de post-déploiement puis en modifiant mon projet pour écraser le script de post-déploiement principal au moment de la construction en fonction de sur la configuration de construction. Cela fait maintenant ce dont j'ai besoin, mais il semble qu'il devrait y avoir un moyen plus simple!
Pour tous ceux qui ont besoin de la même chose - j'ai trouvé cet article utile
Donc dans mon projet, j'ai les fichiers de post-déploiement suivants:
J'ai ensuite ajouté ce qui suit à la fin du fichier de projet (clic droit pour décharger puis clic droit modifier):
<Target Name="BeforeBuild">
<Message Text="Copy files task running for configuration: $(Configuration)" Importance="high" />
<Copy Condition=" '$(Configuration)' == 'Release' " SourceFiles="Scripts\Post-Deployment\Default.Script.PostDeployment.sql" DestinationFiles="Scripts\Post-Deployment\Script.PostDeployment.sql" OverwriteReadOnlyFiles="true" />
<Copy Condition=" '$(Configuration)' == 'Debug' " SourceFiles="Scripts\Post-Deployment\Default.Script.PostDeployment.sql" DestinationFiles="Scripts\Post-Deployment\Script.PostDeployment.sql" OverwriteReadOnlyFiles="true" />
<Copy Condition=" '$(Configuration)' == 'Configuration1' " SourceFiles="Scripts\Post-Deployment\Configuration1.Script.PostDeployment.sql" DestinationFiles="Scripts\Post-Deployment\Script.PostDeployment.sql" OverwriteReadOnlyFiles="true" />
</Target>
Enfin, vous devrez installer des configurations de build correspondantes dans la solution.
De plus, pour tous ceux qui essaient d'autres solutions, j'ai également essayé ce qui suit sans aucune chance:
Création d'un événement post-génération pour copier les fichiers au lieu de devoir pirater le fichier de projet XML. je n'ai pas pu faire fonctionner cela parce que je n'ai pas pu former le chemin correct vers le fichier de script de post-déploiement. Ce problème de connexion décrit le problème
Utilisation de variables pour le chemin du script à passer à la commande: r. Mais j'ai rencontré plusieurs erreurs avec cette approche.
J'ai réussi à contourner le problème en utilisant la méthode noexec .
Donc, au lieu de cela:
IF ('$(ConfigSetting)' = 'Configuration1')
BEGIN
print 'inserting specific configuration'
:r .\Configuration1\Data.sql
END
J'ai inversé le conditionnel et défini NOEXEC ON pour ignorer les instructions importées ainsi:
IF ('$(ConfigSetting)' <> 'Configuration1')
SET NOEXEC ON
:r .\Configuration1\Data.sql
SET NOEXEC OFF
Assurez-vous de le désactiver si vous souhaitez exécuter des instructions ultérieures.
Voici comment je gère le déploiement conditionnel dans le processus de post-déploiement pour déployer les données de test pour la configuration de débogage mais pas de version.
Tout d'abord, dans l'Explorateur de solutions, ouvrez le dossier des propriétés du projet et cliquez avec le bouton droit pour ajouter un nouveau fichier SqlCmd.variables.
Nommez le fichier Debug.sqlcmdvars
.
Dans le fichier, ajoutez vos variables personnalisées, puis ajoutez une variable finale appelée $(BuildConfiguration)
et définissez la valeur sur Debug.
Répétez le processus pour créer un Release.sqlcmdvars, en définissant $(BuildConfiguration)
sur Release.
Maintenant, configurez vos configurations: Ouvrez la page des propriétés du projet dans l'onglet Déployer. Dans la liste déroulante supérieure, définissez la configuration sur Debug. Dans la liste déroulante inférieure, (variables de commande SQL), définissez le fichier sur Properties\Debug.sqlcmdvars.
Répétez l'opération pour Release as: dans la liste déroulante supérieure, définissez la configuration sur Release. Dans la liste déroulante inférieure, (variables de commande SQL), définissez le fichier sur Properties\Release.sqlcmdvars.
Maintenant, dans votre fichier Script.PostDeployment.sql, vous pouvez spécifier une logique conditionnelle telle que:
IF 'Debug' = '$(BuildConfiguration)'
BEGIN
PRINT '***** Creating Test Data for Debug configuration *****';
:r .\TestData\TestData.sql
END
Dans l'Explorateur de solutions, cliquez avec le bouton droit sur la solution de niveau supérieur et ouvrez Configuration Manager. Vous pouvez spécifier quelle configuration est active pour votre build. Vous pouvez également spécifier la configuration sur la ligne de commande MSBUILD.EXE.
Voilà, vos versions de développeur contiennent des données de test, mais pas la version finale!
Au fur et à mesure que Rob a travaillé, les instructions GO ne sont pas autorisées dans les scripts SQL liés car cela les imbriquerait dans les instructions BEGIN/END.
Cependant, j'ai une solution différente de la sienne - si possible, supprimez toutes les instructions GO des scripts référencés et mettez-en une seule après l'instruction END:
IF '$(DeployTestData)' = 'True'
BEGIN
:r .\TestData\Data.sql
END
GO -- moved from Data.sql
Notez que j'ai également créé une nouvelle variable dans mon fichier sqlcmdvars appelée $ (DeployTestData) qui me permet d'activer/désactiver le déploiement du script de test.
J'ai trouvé un piratage sur un blog MSDN qui fonctionnait assez bien. L'astuce consiste à écrire les commandes dans un fichier de script temporaire, puis à exécuter ce script à la place. Fondamentalement, l'équivalent de SQL dynamique pour SQLCMD.
-- Helper newline variable
:setvar CRLF "CHAR(13) + CHAR(10)"
GO
-- Redirect output to the TempScript.sql file
:OUT $(TEMP)\TempScript.sql
IF ('$(ConfigSetting)' = 'Configuration1')
BEGIN
PRINT 'print ''inserting specific configuration'';' + $(CRLF)
PRINT ':r .\Configuration1\Data.sql' + $(CRLF)
END
ELSE
BEGIN
PRINT 'print ''inserting generic data'';' + $(CRLF)
PRINT ':r .\GenericConfiguration\Data.sql' + $(CRLF)
END
GO
-- Change output to stdout
:OUT stdout
-- Now execute the generated script
:r $(TEMP)\TempScript.sql
GO
Le fichier TempScript.sql
Contiendra alors soit:
print 'inserting specific configuration';
:r .\Configuration1\Data.sql
ou
print 'inserting generic data';
:r .\GenericConfiguration\Data.sql
en fonction de la valeur de $(ConfigSetting)
et il n'y aura aucun problème avec les instructions GO
etc. lors de son exécution.
J'ai été inspiré par la solution de Rob Bird. Cependant, j'utilise simplement les événements de génération pour remplacer les scripts de post-déploiement basés sur la configuration de génération sélectionnée.