Our SSDT database project includes a table that has a computed column that can take one of several forms, depending on customer requirements. I’m trying to figure out how to manage this computed column so that we can still use the Publish function without reverting everyone’s columns back to the default.
What I’m trying to accomplish can be explained in the following invalid T-SQL code:
CREATE TABLE dbo.Customer
(
Id INTEGER,
Region INTEGER,
Name VARCHAR(50),
AccountNumber AS dbo.FormatAccountNumber(Id, Region)
)
CREATE FUNCTION [dbo].[FormatAccountNumber]
(
@Id INTEGER,
@Region INTEGER
)
RETURNS VARCHAR(20)
AS
BEGIN
IF '$(AccountType)' = 'Regional'
RETURN CONVERT(VARCHAR, @Region) + '-' + CONVERT(VARCHAR, @Id)
IF '$(AccountType)' = 'Merged'
RETURN CONVERT(VARCHAR, @Region * 100000 + @Id)
IF '$(AccountType)' = 'Flat'
RETURN CONVERT(VARCHAR, @Id)
END
This, of course, doesn’t work because the $(AccountType) SQLCMD variable can’t be used inside of the function, and wouldn’t be set properly at run-time anyway. I’ve also trying putting the SQLCMD conditional around the entire function:
IF '$(AccountType)' = 'Flat'
CREATE FUNCTION ...
but this produces the error that “CREATE FUNCTION must be the only statement in the batch.”
Is there any way to do any sort of conditional compilation of schema in the SSDT project? And if not, what options do I have for maintaining this sort of customizable field within the SSDT publishing process?
You could use a Post-Deploment script to imperatively deploy your object in dynamic SQL:
Note that by doing this, you won’t be able to make any references to the
dbo.FormatAccountNumberfunction in your SSDT Database Project (unless those objects also included in the Post-Deployment script).I also toyed with an alternate solution which involved addition conditionals within the
.sqlprojfile itself (within theItemGroupelements), but this did get a bit messy since MsBuild Properties aren’t exactly like-for-like with SQLCMD Variables, but I can post this if you like.If you find yourself needing to conditionally deploy objects in your database often, you may like to consider moving to an imperative-based deployment solution (as opposed to the declarative style of SSDT projects). Imperative deployment, often called migrations, gives you greater control of deploy-time behaviour.
Disclaimer: I am the founder of ReadyRoll, which makes a product for VS that uses imperative deployment.