如何将变换应用于SSDT发布配置文件

时间:2015-01-13 13:44:44

标签: sql-server-data-tools publish-profiles

使用Visual Studio 2013

我有一组8个SSDT项目,可以全部部署到几个不同的环境中。但是,每个项目的高级发布设置都是相同的。目前我已经为每个环境创建了一个独特的发布配置文件,这意味着我有大约20个发布配置文件,它们都使用完全相同的设置但不同的连接字符

为我的数据库调整发布设置(这对我的SSDT来说仍然是一些新的常规性)是最烦人的,但我还没有找到解决方法,因为我无法应用转换来发布配置文件就像我可以在ASP.NET项目中的web.config文件。我甚至尝试安装Visual Studio SlowCheetah插件,但它似乎不适用于SSDT项目,因为右键单击发布配置文件时不会显示应用转换的选项。

我不希望我的团队在将数据库部署到开发或QA环境时必须考虑手动输入连接详细信息。有没有办法设置主发布配置文件或以其他方式指定一组共享设置,以便我不必管理20个几乎相同的发布配置文件?

编辑: 使用SAS的答案,我能够为我的.sqlproj文件拼凑以下XML:

  <PropertyGroup>
    <PublishProfileDir>$(ProjectDir)Publish Profiles\</PublishProfileDir>
    <TemplatePublishProfile>$(PublishProfileDir)Baseline\publish.xml</TemplatePublishProfile>
  </PropertyGroup>
  <Target Name="CopyXml" AfterTargets="Build">
    <Copy SourceFiles="$(TemplatePublishProfile)" DestinationFolder="$(PublishProfileDir)Dev"/>
    <Copy SourceFiles="$(TemplatePublishProfile)" DestinationFolder="$(PublishProfileDir)Qa"/>
  </Target>
  <ItemGroup>
    <DevPublishUpdates Include="ConfigUpdates">
      <XPath>/msb:Project/msb:PropertyGroup/msb:TargetDatabaseName</XPath>
      <NewValue>CountyRecordsDev</NewValue>
    </DevPublishUpdates>
    <DevPublishUpdates Include="ConfigUpdates">
      <XPath>/msb:Project/msb:PropertyGroup/msb:DeployScriptFileName</XPath>
      <NewValue>CountyRecords.Dev.Sql</NewValue>
    </DevPublishUpdates>
  </ItemGroup>
  <Target Name="UpdateXml" AfterTargets="CopyXml">
    <Message Text="Editing Derived Xml Publish Profiles" Importance="high" />
    <XmlPoke Namespaces="&lt;NamespacePrefix='msb'Uri='http://schemas.microsoft.com/developer/msbuild/2003'/&gt;"
        XmlInputath="$(PublishProfileDir)Dev\publish.xml" 
        Query="%(DevPublishUpdates.XPath)" 
        Value="%(DevPublishUpdates.NewValue)" />
  </Target>

唯一的缺点是我似乎需要一个单独的文件夹来存放我的所有发布配置文件,以防止一个转换覆盖另一个,我似乎无法找到简单地覆盖现有文件的方法。对于XmlPoke,namespaces属性对于操作至关重要。我从Sayed Ibrahim Hashimi的this blog post那里学到了更多关于这个过程的知识。

1 个答案:

答案 0 :(得分:2)

我们正在使用模板xml文件作为发布的前置步骤自动复制,用于我们的所有目标,因此任何更改只需要在模板中使用mande。在创建发布xml文件时,将动态替换目标服务器名称。我们还必须为此修改xaml。我们使用复制和XMLPoke标签共同的proj文件thar包含在我们的proj文件中。这需要一些工作,但工作正常。

编辑:我已粘贴下面的一些代码试图解释,它只是原版的一部分,但我希望它足以让每个人都开始:

这部分内容在我们的公共文件中(SQLCommonInclude.proj):

<Target Name="CreatePublishXMLFile">
 <PropertyGroup>
  <VersionNumber Condition="'$(VersionNumber)'==''">Local Build</VersionNumber>
  <CurrentDate>$([System.DateTime]::Now.ToString(yyyy-MM-dd HH:mm:ss))</CurrentDate>
  <SqlPublishProfilePath Condition="'$(SqlPublishProfilePath)'==''">Publish\$(TargetServerParam).publish.xml</SqlPublishProfilePath>
  <TargetXMLFile>$(ProjectDir)Publish\$(TargetServerParam).publish.xml</TargetXMLFile>
  <ChangeSets Condition="'$(ChangeSets)'==''">Unknown</ChangeSets>
 </PropertyGroup>
 <XmlPoke XmlInputPath="$(TargetXMLFile)" Query="/*[local-name()='Project']/*[local-name()='PropertyGroup']/*[local-name()='TargetConnectionString']" Value="Data Source=$(TargetServerParam)%3BIntegrated Security=True%3BPooling=False" />
 <XmlPoke XmlInputPath="$(TargetXMLFile)" Query="/*[local-name()='Project']/*[local-name()='PropertyGroup']/*[local-name()='TargetDatabaseName']" Value="$(ProjectName)" />
 <XmlPoke XmlInputPath="$(TargetXMLFile)" Query="/*[local-name()='Project']/*[local-name()='ItemGroup']/*[local-name()='SqlCmdVariable'][@Include='ChangeSets']/*[local-name()='Value']" Value="$(ChangeSets)" />
</Target>

然后对每个目标服务器重复调用:

<Target Name="CreateAllPublishXMLFiles">
 <MSBuild Projects="$(MSBuildProjectFile)" Targets="CreatePublishXMLFile" Properties="TargetServerParam=OURSERVER1" />
 <MSBuild Projects="$(MSBuildProjectFile)" Targets="CreatePublishXMLFile" Properties="TargetServerParam=OURSERVER2" />
</Target>

在每个项目文件中,我们都包含并调用公共代码:

<Import Project="$(SolutionDir)SQLCommonInclude.proj" />
<Target Name="BeforeBuild" DependsOnTargets="CreateAllPublishXMLFiles">

然后,在部署后脚本中,我们设置扩展属性,如下所示:

IF NOT EXISTS (SELECT NULL FROM SYS.EXTENDED_PROPERTIES WHERE class_desc = 'DATABASE' AND name = 'SSDT ChangeSets')
EXEC sp_addextendedproperty @name = N'SSDT ChangeSets', @value = '';
EXEC sp_updateextendedproperty @name = N'SSDT ChangeSets', @value =  '$(ChangeSets)';