Question: In our SSDT project we have a script that is huge and contains a lot of INSERT statements for importing data from an old system. Using sqlcmd variables, I'd like to be able to conditionally include the file into the post deployment script.

We're currently using the `:r` syntax which includes the script inline:

```
IF '$(ImportData)' = 'true'
BEGIN
  :r .\Import\OldSystem.sql
END

```

This is a problem because the script is being included **inline** regardless of whether `$(ImportData)` is true or false and the file is so big that it's slowing the build down by about 15 minutes.

Is there another way to conditionally include this script file so it doesn't slow down the build?

Answer: 
The scripts referenced using :r are always included. You have a couple of options but I would first verify that if you take the script out it improves the performance to where you want it to get to.

The simplest approach is to just keep it outside of the whole build process and change your deploy process so it becomes a two step thing (deploy DAC then deploy script). The positives of this are you can do things outside of the ssdt process but the negatives are you don't get things like auto disabling of constraints on tables changing in the deployment.

The second way is to not include the script in the deploy when you build but create an AfterBuild msbuild task that adds the script as a post deploy script in the dacpac. The dacpac is a zip file so you can use the .net packaging Api to add a part called postdeploy.sql which will then be included in the deployment process.

Both of these ways mean you lose verification so you might want to keep it in a separate ssdt project which has a "same database" reference to your main project, it will slow down the build when it changes but should be quick the rest of the time.
Here is the way I had to do it.

1) Create a dummy post-deploy script.

2) Create build configurations in your project for each deploy scenario.

3) Use a pre-build event to determine which post deploy configuration to use.
You can either create separate scripts for each configuration or dynamically build the post-deploy script in your pre-build event. Either way you base what you do on the value of $(configuration) which always exists in a build event.

If you use separate static scripts, your build event only needs to copy the appropriate static file, overwriting the dummy post-deploy with whichever script is useful in that deploy scenario.

In my case I had to use dynamic generation because the decision about which scripts to include required knowing the current state of the database being deployed to. So I used the configuration variable to tell me which environment was being deployed to and then used an SQLCMD script with :OUT set to my Post-Deploy script location. Thus my pre-build script would then write the post-deploy script dynamically.

Either way, once build completed and the normal deploy process started the Post-Deploy script contained exactly the :r commands that I wanted.

Here's an example of the SQLCMD script I invoke in pre-build.

```
:OUT .\Script.DynamicPostDeployment.sql

PRINT ' /*';
PRINT '     DO NOT MANUALLY MODIFY THIS SCRIPT.                                               ';
PRINT '                                                                                       ';
PRINT '     It is overwritten during build.                                                   ';
PRINT '     Content IS based on the Configuration variable (Debug, Dev, Sit, UAT, Release...) ';
PRINT '                                                                                       ';
PRINT '     Modify Script.PostDeployment.sql to effect changes in executable content.         ';
PRINT ' */';
PRINT 'PRINT ''PostDeployment script starting at''+CAST(GETDATE() AS nvarchar)+'' with Configuration = $(Configuration)'';';
PRINT 'GO';
IF '$(Configuration)' IN ('Debug','Dev','Sit')
BEGIN
    IF (SELECT IsNeeded FROM rESxStage.StageRebuildNeeded)=1
    BEGIN
        -- These get a GO statement after every file because most are really HUGE
        PRINT 'PRINT ''ETL data was needed and started at''+CAST(GETDATE() AS nvarchar);';
        PRINT '                                                  ';
        PRINT 'EXEC iESxETL.DeleteAllSchemaData ''pExternalETL'';';
        PRINT 'GO';
        PRINT ':r .\PopulateExternalData.sql         ';
....

```