Reputation: 137
We have multiple clients who have different database versions running on their servers. Some clients are using SQL Server 2008, some SQL Server 2012 and some clients are using SQL Server 2014.
I have a SSDT project in my Visual Studio 2015 solution.
For production deployment, first we ask client for the SQL Server version & according to that version, we give the suitable .dacpac
file to the client.
Every time on build of SSDT project it only creates a single .dacpac
file in the output folder for the selected "Target platform" version (SSDT project > Properties > Project Settings > Target platform)
If SQL Server 2008 is selected as Target Platform - a single .dacpac
file is created for SQL Server 2008
If SQL Server 2012 is selected as Target Platform - a single .dacpac
file is created for SQL Server 2012
Is there any way to create multiple .dacpac
files for all the version in a single build without changing the "Target Platform" setting manually?
By using pre/post build event OR using some Exe file?
Thanks.
Upvotes: 2
Views: 1873
Reputation: 579
So, I was trying to figure this out myself, and at first I went down the path of editing the project msbuild xml. Unfortunately I could not get the DSP (SQL Server Version) to change no matter how I approached the build xml. Finally I decided to give up and write a PowerShell that would and create all of the builds. Here is what I came up with in case it helps anyone else. Add this PowerShell to your solution folder, and modify the project path inside of it, and it should create a separate folder per SQL server version for you with each dacpac targeted to that version. Of course all of the build parameters are changeable to fit your desired outputs. I wanted the builds to control not only the SQL version, but the .net framework version as well. You could add other things as well, like conditional compile symbols. Up to you.
Clear-Host
# TIM C: I extrapolated how to do this from the shortcut that installs with VS 2019 called: "Developer PowerShell for VS 2019".
# I added the take on VSWHERE so it will work for any version 2017+
#. "C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" -?
$instance = (. "$(${env:ProgramFiles(x86)})\Microsoft Visual Studio\Installer\vswhere.exe" -latest -format json | ConvertFrom-Json)
$common7Path = ([System.IO.FileInfo]$instance.productPath).Directory.Parent.FullName
$instanceId = $instance.instanceId
$vsVersion = ([System.Version]$instance.installationVersion).Major
Import-Module "$common7Path\Tools\Microsoft.VisualStudio.DevShell.dll";
Enter-VsDevShell $instanceId
$scriptRoot = [System.IO.Directory]::GetParent($MyInvocation.MyCommand.Definition).FullName
Set-Location $scriptRoot
<# *********************************************************************
EDIT HERE: The sub path to the SSDT project to build
********************************************************************* #>
$projectPath = [System.IO.Path]::Combine($scriptRoot, "project\project.sqlproj")
<# *********************************************************************
********************************************************************* #>
$projectFileName = [System.IO.Path]::GetFileNameWithoutExtension($projectPath)
$builds = @(
[pscustomobject]@{sql=2008;version=100;framework="v3.5";constants=""},
[pscustomobject]@{sql=2012;version=110;framework="v4.5";constants="DOTNET45"},
[pscustomobject]@{sql=2014;version=120;framework="v4.5";constants="DOTNET45"},
[pscustomobject]@{sql=2016;version=130;framework="v4.5";constants="DOTNET45"}
)
$configs = @( "Debug", "Release" )
foreach ($build in $builds) {
foreach ($config in $configs) {
Write-Host "Building for $($build.sql)-$config" -ForegroundColor Yellow
& msbuild $projectPath `
/target:ReBuild /interactive:false /nologo /nodeReuse:false /p:platform="any cpu" /consoleLoggerParameters:ErrorsOnly `
/p:configuration="$config" /p:VisualStudioVersion="$vsVersion.0" /p:OutputPath="bin\$config\$($build.sql)\" `
/p:DSP="Microsoft.Data.Tools.Schema.Sql.Sql$($build.version)DatabaseSchemaProvider" `
/p:TargetFrameworkVersion=$($build.framework) /p:SqlTargetName="$($projectFileName)_$($build.sql)" `
/p:DefineConstants="$($build.constants)" | Out-Host
if (!$?) { Write-Host "Build -failed for $($build.sql)-$config" -ForegroundColor Red }
}
}
Upvotes: 1
Reputation: 6856
I have had a similar thing where I needed one project to work on multiple versions, the way I managed it was to set it for the lowest version you support (I only needed 2007r2 and 2012 so it wasn't too hard). Then when I deployed I set "AllowIncompatiblePlatform" to true.
Another way would be to open th dacpac as a zip file or using System.Packaging .net api and change the version in the model.xml.
I also blogged about some difficulties you probably already know about when you don't control the database you are deploying to:
If you decide to change the version inside the dacpac let me know and I'll show you how but it does mean you skip the build phase which isn't ideal.
Ed
Upvotes: 1