Переменные MSBuild и sqlcmd в приложениях уровня данных после развертывания.sql

#deployment #msbuild #data-tier-applications

#развертывание #msbuild #приложения уровня данных

Вопрос:

Предисловие

Я использую проект приложения уровня данных и проект базы данных SQL CLR для управления частью базы данных моего приложения.
У меня есть 3 разных компьютера (для локальных, dev / ci / qa и сред развертывания preprod / prod соответственно), где должна быть установлена часть базы данных.
В сценарии после развертывания я создаю хранимые процедуры CLR (со сборкой) и логины и пользователи.
Логины и пользователи должны отличаться в зависимости от конфигурации.

Проблема

У меня проблема с использованием переменных. Вот сценарии после развертывания, которые я пробовал

 GO
IF '$(DeploymentConfiguration)' = 'Debug'
BEGIN
    :r .AddLoginsUsersRolesDev.sql
END
ELSE
BEGIN
    :r .AddLoginsUsersRolesProd.sql
END
GO
....
ALTER DATABASE QProduction SET TRUSTWORTHY ON
GO
CREATE ASSEMBLY QProcedures from '[$(MSBuildProjectDir)]Q.Core.Database.dll' WITH PERMISSION_SET = SAFE
GO
....
 

И

 GO
:setvar databasename "$(TargetDatabase)"
:setvar deploymentconfig "$(DeploymentConfiguration)"
:setvar msbuildprojectdir "$(MSBuildProjectDirectory)"

IF '$(deploymentconfig)' = 'Debug'
BEGIN
    :r .AddLoginsUsersRolesDev.sql
END
ELSE
BEGIN
    :r .AddLoginsUsersRolesProd.sql
END
GO
....
ALTER DATABASE QProduction SET TRUSTWORTHY ON
GO
CREATE ASSEMBLY QProcedures from '[$(msbuildprojectdir)]Q.Core.Database.dll' WITH PERMISSION_SET = SAFE
GO
....
 

Вот как я добавляю логины, пользователей (AddLoginsUsersRolesDev.sql):

 GO
IF NOT EXISTS 
    (SELECT name  
     FROM master.sys.server_principals
     WHERE name = 'QIUSR_Q')
BEGIN
    CREATE LOGIN [QIUSR_Q] FROM WINDOWS WITH DEFAULT_DATABASE=[master], DEFAULT_LANGUAGE=[us_english]
END

USE [$(databasename)]
GO
IF NOT EXISTS
    (SELECT name
     FROM sys.database_principals
     WHERE name = 'QIUSR_Q')
BEGIN
    CREATE USER [QIUSR_Q] FOR LOGIN [QIUSR_Q]
END
GO

USE [$(databasename)]
GO
EXEC sp_addrolemember N'db_datareader', N'QIUSR_Q'
GO

USE [$(databasename)]
GO
EXEC sp_addrolemember N'db_datawriter', N'QIUSR_Q'
....
 

Для PostDeployment.sql выполняется действие PostDeploy и включен режим SQLCMD, для включения скриптов действие не находится в сборке.
Сбой развертывания с ошибкой выполнения SQL: произошла неустранимая ошибка. Не удалось найти переменную MSBuildProjectDirectory «.
Насколько я знаю, в проекте базы данных я мог бы использовать Database.sqlcmdvars для этих целей.
Как мне решить эту проблему?

Update

I’ve added

 <SqlCommandVariablesFile>Database.sqlcmdvars</SqlCommandVariablesFile>
 

to .dbproj file and created Database.sqlcmdvars:

 <SqlCommandVariables xmlns="urn:Microsoft.VisualStudio.Data.Schema.Package.SqlCmdVars">
  <Version>1.0</Version>
  <Properties>
    <Property>
      <PropertyName>databasename</PropertyName>
      <PropertyValue>Q</PropertyValue>
    </Property>
  </Properties>
</SqlCommandVariables>
 

Это не работает.

Я добавил

 <ItemGroup>
  <SqlCommandVariableOverride Include="databasename=$(TargetDatabase)" />
</ItemGroup>  
 

Это тоже не работает.

Я добавил

 <PropertyGroup>
 <databasename>Q</databasename>
 <SetVariables>
  <Variable Name="databasename" Value="Q" />
 </SetVariables>
</PropertyGroup>  
 

Это тоже не работает (где-то я читал, что возможная переменная MSBuild должна существовать с тем же именем, что и sqlcmd).

Я переместил импорт проекта SqlTasks.targets перед разделом PostBuildEvent.
Перед:

 <PropertyGroup>
 <PostBuildEvent/>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)MicrosoftVisualStudiov10.0TeamDataMicrosoft.Data.Schema.SqlTasks.targets" /> 
 

После:

 <Import Project="$(MSBuildExtensionsPath)MicrosoftVisualStudiov10.0TeamDataMicrosoft.Data.Schema.SqlTasks.targets" />
<PropertyGroup>
 <PostBuildEvent/>
</PropertyGroup>  
 

Это тоже не работает.

Спасибо.

Ответ №1:

Похоже, что sqlcmdvars не поддерживаются. По крайней мере, они помечены как «Неприменимые» для dacpac.