Liquibase部署T-SQL存储过程报错:OR关键字附近语法错误
问题排查与解决
核心问题
报错里的OR语法问题并非WHEN语句之间的逻辑错误,而是Liquibase的语句分隔配置与SQL脚本格式不匹配导致的解析错误——你的SQL脚本本身在本地数据库能正常运行,说明语法没问题,问题出在Liquibase对脚本的处理逻辑上。
具体问题点
- Changeset配置混乱:原changeset里
endDelimiter=";":/的写法错误,同时启用了splitStatements="false"却保留了GO语句,导致Liquibase无法正确识别整个存储过程的边界,错误解析CREATE OR ALTER语句。 - 多余的
GO语句:当splitStatements="false"时,Liquibase会把整个脚本块当作一个单语句执行,GO是SQL Server客户端的分隔符,Liquibase无法识别,反而会干扰解析。
修正后的脚本
-- changeset Conner:492 splitStatements="false" endDelimiter="/" CREATE OR ALTER PROCEDURE dbo.UpdateOrInsertWinningColorsAnswers(@json NVARCHAR(max)) AS BEGIN MERGE INTO WinningColorsAnswer W USING( SELECT * FROM OPENJSON(@json) WITH( Id int, Answer varchar(max), QuestionId int, SectionId int, StudentChallengeMappingId int, CreatedDate datetime2, CreatedUser varchar(20), UpdatedDate datetime2, UpdatedUser varchar(20), IsDeleted bit ) ) as InputJSON (Id, Answer, QuestionId, SectionId, StudentChallengeMappingId, CreatedDate, CreatedUser, UpdatedDate, UpdatedUser, IsDeleted) ON(W.StudentChallengeMappingId = InputJSON.StudentChallengeMappingId AND W.QuestionId = InputJSON.QuestionId) WHEN MATCHED THEN UPDATE SET W.Answer = InputJSON.Answer, W.UpdatedDate = CONVERT(datetime, InputJSON.UpdatedDate, 104), W.UpdatedUser = InputJSON.UpdatedUser WHEN NOT MATCHED THEN INSERT(Answer,QuestionId,SectionId,StudentChallengeMappingId,CreatedDate,CreatedUser,UpdatedDate,UpdatedUser,IsDeleted) VALUES(InputJSON.Answer, InputJSON.QuestionId, InputJSON.SectionId, InputJSON.StudentChallengeMappingId, CONVERT(datetime, InputJSON.CreatedDate, 104), InputJSON.CreatedUser, CONVERT(datetime, InputJSON.UpdatedDate, 104), InputJSON.UpdatedUser, CAST(InputJSON.IsDeleted AS bit)) ; END /
关键修正说明
- 把
endDelimiter统一设置为"/",并确保脚本最后以/结尾,配合splitStatements="false",让Liquibase正确识别整个存储过程作为一个执行单元。 - 删除了多余的
GO语句,避免干扰Liquibase的解析逻辑。 - 把
and改为大写AND(可选,但符合SQL Server的最佳实践)。
额外注意事项
- 确认你的SQL Server版本支持
CREATE OR ALTER(SQL Server 2016 SP1及以上版本支持),如果是旧版本需要改为DROP PROCEDURE IF EXISTS再CREATE PROCEDURE的写法。 - 检查
CONVERT(datetime, ..., 104)的格式,确保传入的CreatedDate和UpdatedDate是dd.mm.yyyy格式,否则会出现转换错误。
内容的提问来源于stack exchange,提问作者NorSer
相关产品推荐
相关产品推荐

