-->

how to use msbuild properties in sqlproj (SQL Serv

2020-06-16 06:06发布

问题:

I just upgraded my existing SQL Server 2008 r2 .dbproj to a SQL Server 2012 .sqlproj (using SQL Server Data Tools).

Previously, I was able to define a SQLCMD variable in my project, and then define the value by editing the project file to use msbuild values by adding the following element:

<ItemGroup>
    <SqlCommandVariableOverride Include="ProjectDirectory=$(MSBuildProjectDirectory)" />
</ItemGroup>

Which I could then use in my PostDeployment script like this:

SELECT * INTO dbo.MyTable FROM dbo.MyTable WHERE 1=2
BULK INSERT dbo.MyTable
FROM  '$(ProjectDirectory)\data\dbo.MyTable.dat'
WITH (DATAFILETYPE = 'widenative')

However, after the upgrade, this no longer seems to work.

I have tried adding that same entry to the new sqlproj, but the Publish functionality doesn't seem to pick it up and wants me to supply a value. If I supply $(MSBuildProjectDirectory), that is interpreted literally and fails.

Under the new regime, what is the mechanism for specifying a local filepath and/or using msbuild values?

回答1:

In a sql server 2012 sqlproj (SSDT database project) you use publishing profiles. You can start off by right-clicking your database project and choosing 'Publish'.

You can then set desired options and save these in a so-called publishing profile in your project. Double-clicking this profile launches the publishing wizard with the correct options set.

In your publish profile you can include hard-coded values for sqlcmd variables:

<ItemGroup>
    <SqlCmdVariable Include="ProjectDirectory">
        <Value>UNKNOWN</Value>
    </SqlCmdVariable>
</ItemGroup>

If desired, you can update these with dynamic values during build. In your msbuild project:

<Target Name="SetProjectDirectoryInPublishXml">
    <ItemGroup>
        <Namespaces Include="nsMsbuild">
            <Prefix>nsMsbuild</Prefix>
            <Uri>http://schemas.microsoft.com/developer/msbuild/2003</Uri>
        </Namespaces>
    </ItemGroup>
    <ItemGroup>
        <SSDTPublishFiles Include="$(SolutionBinFolder)\**\*.publish.xml" />
    </ItemGroup>
    <MSBuild.ExtensionPack.Xml.XmlFile Condition="%(SSDTPublishFiles.Identity) != ''"
                                   TaskAction="UpdateElement"
                                   File="%(SSDTPublishFiles.Identity)"
                                   Namespaces="@(Namespaces)" 
                                   XPath="//nsMsbuild:SqlCmdVariable[@Include='ProjectDirectory']/nsMsbuild:Value" 
                                   InnerText="$(MSBuildProjectDirectory)"/>
</Target>

This requires an extension to update the XML. I use the msbuild extension pack.

Credits for this mechanism go to Jamie Thomson