Liquibase执行含SQL Server变量声明的SQL代码时报错:Incorrect syntax near 'INT'
遇到这个问题我太熟悉啦!这其实是Liquibase默认的语句拆分机制在“捣乱”,咱们一步步来解决:
问题回顾
你在Liquibase的XML变更集中写了一段包含变量声明的SQL Server批处理代码,本地直接在SQL Server 2019上运行完全没问题,但通过Liquibase执行时却抛出了如下错误:
liquibase.exception.DatabaseException: Incorrect syntax near 'INT'.
[Failed SQL: (102) begin
DECLARE @MyVariable INT]
你的原始代码是这样的:
<changeSet author="me" id="poc" runAlways="true" runOnChange="true" > <sql> BEGIN DECLARE @MyVariable INT; SET @MyVariable = 10; END; </sql> </changeSet>
你还尝试过去掉分号,但依然没有解决问题。
问题原因
Liquibase的<sql>标签默认开启了splitStatements="true",它会自动按照分号把你的SQL拆分成多条独立语句执行。但在SQL Server中,DECLARE变量是属于整个批处理上下文的,单独执行DECLARE @MyVariable INT这条语句时,SQL Server会认为语法不完整,从而抛出错误——因为它需要和后续的SET操作、逻辑代码在同一个批处理里运行。
解决方案
只需要修改<sql>标签,添加splitStatements="false"属性,让Liquibase把整个BEGIN...END块当成一个完整的批处理发送给SQL Server执行,不要拆分语句:
<changeSet author="me" id="poc" runAlways="true" runOnChange="true" > <sql splitStatements="false"> BEGIN DECLARE @MyVariable INT; SET @MyVariable = 10; END; </sql> </changeSet>
这样执行的时候,Liquibase就不会拆分你的代码,SQL Server能正确识别整个批处理中的变量声明和后续操作,问题也就解决啦!
备注:内容来源于stack exchange,提问作者Rick

