0

Setup:
I have a Visual Studio 2019 .Net solution and there's an SSDT project in it.

Goal:
I need to generate an sql change script automatically on each CI build (TFS) for further including it to build artifacts for distribution.

I know there's sqlpackage.exe tool that can generate a change script, but it requires either an existing database connection or a *.dacpac file to compare against.

Is there a standard way to generate an sql change script automatically on each CI build?

UPDATE:

Example:

Version #1 of my sql project:

MyProject\Schema Objects\Schemas\dbo\Tables\MyTable.sql:

CREATE TABLE [dbo].[MyTable] (
    [Id] INT IDENTITY (1, 1) NOT NULL,
    [Name] VARCHAR (50) NOT NULL,
);

Version #2 of my sql project:

MyProject\Schema Objects\Schemas\dbo\Tables\MyTable.sql:

CREATE TABLE [dbo].[MyTable] (
    [Id] INT IDENTITY (1, 1) NOT NULL,
    [Name] VARCHAR (50) NOT NULL,
    [Description] VARCHAR (255) NOT NULL,
);

MyProject\Schema Objects\Schemas\dbo\Programmability\Stored Procedures\MyProcedure.sql

CREATE PROCEDURE [dbo].[MyProcedure]
BEGIN
...
...
END

Script that I can generate now:

CREATE DATABASE
...
...
CREATE TABLE MyTable
...
...
CREATE PROCEDURE MyProcedure
...
...

Script that I need (change script, containing only changes made relative to a previous version):

ALTER TABLE [dbo].[MyTable] 
ADD [Description] VARCHAR (255) NOT NULL

GO

ALTER PROCEDURE MyProcedure
...
...

GO
2
  • It seems there is no standard way to generate a sql change script automatically by using MSBuild. Commented Sep 23, 2021 at 8:22
  • @Tianyu you can do that natively Commented Sep 23, 2021 at 12:09

1 Answer 1

1

msbuild.exe $SqlProjPath /p:SqlPublishProfilePath=$SqlPublishProfilePath /p:UpdateDatabase=false /t:Build,Publish where the most important argument is UpdateDatabase and when it is false, it will just generate the script without publishing

UPDATE (based on the comments): as far as I understand that connection to database is wanted to avoided. This is actually not recommended approach as normally you can't be 100% sure what exact version of database is currently on production (or whatever environment you are going to deploy to) as there could be million reasons why it drifted, most often because of some manual changes directly to database. That's why it is advised to compare to it. In any case, when working with SSDT you always need to have some database or dacpac to compare against. So, these are the options I can see:

  • Compare with real database
  • Extract dacpac from real database and compare against it
  • Checkout previous project version from source control, build project and compare current state with built dacpac
  • Save last deployed dacpac in version control and use it to compare. After deployment commit new version of dacpac

The first option is most advisable and going down each approach getting worse.

Sign up to request clarification or add additional context in comments.

5 Comments

Dmitrij, Thanks for the detailed answer! I'm afraid I didn't ask my question correctly enough, so I updated it with an example.
Where is "previous" version located?
It is located in git repository, all scripts are under git version control
but what's the previous? previous commit or what?
Dmitrij, all your options really make sense, thanks a lot! I remembered one more: To put change scripts along with create scripts manually. Yes, it will surely mean a duplication, but those change scripts can be easily included into build artifacts and then deployed by db administrator. Let's say each sql project modification you create a file: update-1.sql, update-2.sql,..., update-N.sql. A database version can be maintained in a separate database table and therefore a db operator can easily figure out which update scripts to apply for which version.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.