如何在Liquibase的changelog.xml中配置多个endDelimiter
解决Liquibase中SQL脚本多结束符(;和/)的配置问题
错误原因
你在代码里重复设置了endDelimiter属性,XML规范中同名属性会被后面的赋值覆盖,最终Liquibase只会把;当作唯一的语句结束符。但你的脚本里还有用/结束的语句(比如Oracle的存储过程、触发器这类对象),Liquibase无法正确识别这类语句的结束位置,就会抛出ORA-00933错误。
正确解决方案
方案1:使用multipleEndDelimiters属性(推荐,Liquibase 4.9.0+支持)
Liquibase 4.9.0及以上版本支持multipleEndDelimiters属性,直接用逗号分隔多个结束符即可。修改你的代码如下:
ET.SubElement(change_set, "sqlFile", { "path": rel_sql_file_path, "relativeToChangelogFile": "true", "splitStatements": "true", "stripComments": "false", "multipleEndDelimiters": ";/", "encoding": "UTF-8" })
对应的XML元素会生成:
<sqlFile path="你的脚本路径.sql" relativeToChangelogFile="true" splitStatements="true" stripComments="false" multipleEndDelimiters=";/" encoding="UTF-8"/>
这样Liquibase会同时识别;和/作为语句结束符,正确拆分脚本里的所有语句。
方案2:拆分SQL脚本(兼容低版本Liquibase)
如果你的Liquibase版本低于4.9.0,不支持多结束符属性,就把脚本拆成两个文件:
- 一个文件只放用
;结束的普通SQL语句,在changelog里设置endDelimiter=";" - 另一个文件放用
/结束的对象定义语句(比如存储过程),设置endDelimiter="/"
然后在changelog里分别引用这两个文件即可。
方案3:在SQL脚本内动态切换结束符
不需要修改changelog配置,直接在SQL脚本里用Liquibase的注释指令临时切换结束符:
-- liquibase:setEndDelimiter:/ CREATE OR REPLACE PROCEDURE test_procedure AS BEGIN DBMS_OUTPUT.PUT_LINE('测试存储过程'); END; / -- liquibase:setEndDelimiter; SELECT * FROM test_table;
执行时Liquibase会根据注释指令自动切换结束符,适配不同类型的语句。
内容的提问来源于stack exchange,提问作者Abinash Mishra
相关产品推荐
相关产品推荐

