如何在Liquibase中执行SET ESCAPE \;语句?
问题根源
Liquibase是跨数据库的迁移工具,默认不会识别Oracle SQLPlus专属的SET ESCAPE这类命令——SQL Developer能正常执行是因为它原生支持SQLPlus指令,而Liquibase的SQL解析逻辑会把这类命令当作无效SQL抛出错误。
可行解决方案
直接替换反斜杠为双反斜杠
放弃依赖SET ESCAPE,把INSERT语句里的单个\全部替换成\\,数据库本身能识别双反斜杠作为转义后的单个反斜杠,Liquibase也不会报错。
示例:
原语句:INSERT INTO demo_table (content) VALUES ('path\file.txt');
修改后:INSERT INTO demo_table (content) VALUES ('path\\file.txt');用Liquibase原生insert标签替代原生SQL
改用Liquibase提供的<insert>标签构造插入操作,工具会自动处理字符串转义,不需要手动处理反斜杠。
示例:<changeSet id="insert-demo-data" author="your-id"> <insert tableName="demo_table"> <column name="content" value="path\file.txt" /> </insert> </changeSet>让Liquibase原封不动传递SQL块给Oracle
如果必须保留原生SQL和SET ESCAPE命令,把相关语句放在同一个<sql>标签内,并指定dbms="oracle",强制Liquibase不解析直接转发给数据库执行。
示例:<changeSet id="insert-with-escape" author="your-id"> <sql dbms="oracle"> SET ESCAPE \; INSERT INTO demo_table (content) VALUES ('path\file.txt'); INSERT INTO demo_table (content) VALUES ('docs\readme.md'); </sql> </changeSet>使用sqlFile标签并关闭注释剥离
如果SQL语句保存在单独文件中,在changelog的<sqlFile>标签里添加stripComments="false",避免Liquibase误把SET ESCAPE当作注释处理(部分Liquibase版本有效)。
示例:<changeSet id="run-insert-script" author="your-id"> <sqlFile path="insert_data.sql" stripComments="false" dbms="oracle" /> </changeSet>
内容的提问来源于stack exchange,提问作者Harsh

