Issues with endDelimeter with SQL Server migrations [LiquiBase 4.31]

I’m setting up LiquiBase for a few existing legacy SQL Server databases that my team maintains. I’ve created a dump of all the DDL scripts from SQL Server Management Studio, here’s an example script:

USE [DatabaseName]
GO
/****** Object:  StoredProcedure [dbo].[xp_DataUpdate_MoveChartsToNewORGByPTORG]    Script Date: 3/28/2025 4:17:28 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE OR ALTER PROCEDURE [dbo].[xp_DataUpdate_MoveChartsToNewORGByPTORG]
	@ticketNum varchar(20),
	@requesterName varchar(50),
	@note varchar(2000) = null,
	@unscheduleCharts tinyint = 1,
	@orgStatus varchar(30) = 'Unscheduled',
	@code smallint = null,
	@retrievalMethod smallint = null
as	
begin
	
	set noCount on;

	declare	@theErrorMsg	nvarchar(4000), 
			@theErrorState	int,
			@dt				datetime, 
			@userId			int,
			@statusName		varchar(50),
			@msg			varchar(2000),
			@sql			varchar(max)

	-- omitting full code, not relevant
        ...
 
	set noCount off;
end    
GO

As you can see, the script assumes that it will be run using sqlcmd (it has GO statements). Additionally, the procedure itself uses semi-colon (;) to end statements (I can’t just remove them, for example MERGE requires a semi-colon).

At the end of the day, I need all the statements separated by GO, and that’s enough to run them successfully, I thought of changing the endDelimeter to GO, thinking that it won’t split by ; anymore. My changeset looks like this:

- changeSet:
    author: echofoxxx
    changes:
    - sqlFile:
        endDelimeter: GO
        path: ./dbo.xp_DataUpdate_MoveChartsToNewORGByPTORG.sql
        relativeToChangelogFile: true
    id: dbo.xp_DataUpdate_MoveChartsToNewORGByPTORG
    runOnChange: true

However, running the migration fails:

ERROR: Exception Details
ERROR: Exception Primary Class:  SQLServerException
ERROR: Exception Primary Reason:  Incorrect syntax near ';'.
ERROR: Exception Primary Source:  Microsoft SQL Server 15.00.4430
ERROR: Exception Details
ERROR: Exception Primary Class:  SQLServerException
ERROR: Exception Primary Reason:  Incorrect syntax near ';'.
ERROR: Exception Primary Source:  Microsoft SQL Server 15.00.4430

Unexpected error running Liquibase: Migration failed for changeset sprocs/sprocs-changelog.yaml::dbo.xp_DataUpdate_MoveChartsToNewORGByPTORG::abhishekgoyal@datavant.com:
     Reason: liquibase.exception.DatabaseException: Incorrect syntax near ';'. [Failed SQL: (102) CREATE OR ALTER PROCEDURE [dbo].[xp_DataUpdate_MoveChartsToNewORGByPTORG]
        @ticketNum varchar(20),
        @requesterName varchar(50),
        @note varchar(2000) = null,
        @unscheduleCharts tinyint = 1,
        @orgStatus varchar(30) = 'Unscheduled',
        @code smallint = null,
        @retrievalMethod smallint = null
as
begin

SET NOCOUNT ON;

        declare @theErrorMsg    nvarchar(4000),
                        @theErrorState  int,
                        @dt                             datetime,
                        @userId                 int,
                        @statusName             varchar(50),
                        @msg                    varchar(2000),
                        @sql                    varchar(max)

-- omitting the full code, not relevant
...

SET NOCOUNT OFF;]

It looks like for some reason, the statement is still being terminated at ; instead of GO as I would expect. It’s also interesting that in this script only the last semi-colon causes this problem (there are more semicolons immediately after the CREATE OR ALTER PROCEDURE calls). In other scripts, sometimes it splits in the middle. I can’t find a pattern.

I’ve confirmed removing the last ; (just before END\nGO) in this particular script fixes the issue and the migration runs just fine, but there are are scripts where the statement gets terminated in the middle (for example, a long procedure).

I’ve looked into the native sqlmd executor, but that requires a pro license which I do not have.

Does anyone know what configuration I can use to fix this? Is this a bug, or do I just have to modify the original scripts? Do I need to get pro, because without this LiquiBase is basically useless in my scenario.

I’ve also been looking at this source code to try to figure out what’s going on: liquibase/liquibase-standard/src/main/java/liquibase/util/StringUtil.java at 01021693adb26878bb3eae54b4d693f4f8f76d77 · liquibase/liquibase · GitHub

One of the suspicions I have is that if endDelimeter is null here for some reason, then it’s probably defaulting to ; and GO again

I misspelled endDelimiter as endDelimeter :sweat_smile:

1 Like