Liquibase中含SQL保留关键字列名的删除脚本执行失败
解决Liquibase操作H2数据库保留字列的DELETE报错问题
问题背景
使用Liquibase 4.23.1操作H2 2.2.222数据库时,删除grants表指定数据时,因表中group和grant是SQL保留字,用反引号包裹列名后执行脚本仍报错,提示Column "GROUP" not found。
核心原因
H2 2.x版本默认遵循SQL标准,仅支持双引号作为标识符(含保留字)的包裹符;反引号是MySQL专属语法,若未开启H2的MySQL兼容模式,H2会将反引号视为普通字符串的一部分,无法识别为列名,因此触发报错。
解决方案
方案1:改用双引号包裹保留字列名(推荐,无需修改数据库配置)
在Liquibase的<where>标签中使用双引号,并通过CDATA块避免XML解析冲突:
<changeSet id="delete-target-grants" author="your-author"> <preConditions onFail="MARK_RAN" onFailMessage="Removal failed"> <columnExists tableName="grants" columnName="group"/> <columnExists tableName="grants" columnName="grant"/> </preConditions> <delete tableName="grants"> <where><![CDATA["group"='Operator' AND "grant"='READ']]></where> </delete> </changeSet>
方案2:直接使用<sql>标签执行原生SQL
如果觉得XML标签写法受限,也可以用<sql>标签直接编写兼容H2的SQL语句:
<changeSet id="delete-target-grants" author="your-author"> <preConditions onFail="MARK_RAN" onFailMessage="Removal failed"> <columnExists tableName="grants" columnName="group"/> <columnExists tableName="grants" columnName="grant"/> </preConditions> <sql> DELETE FROM grants WHERE "group"='Operator' AND "grant"='READ' </sql> </changeSet>
方案3:开启H2的MySQL兼容模式(需修改数据库连接配置)
如果项目必须使用反引号语法,可以在H2的JDBC连接URL中添加;MODE=MySQL参数,让H2识别反引号为标识符包裹符:
jdbc:h2:~/your-db-name;MODE=MySQL
修改连接配置后,原脚本中的反引号写法即可正常执行。
内容的提问来源于stack exchange,提问作者code_buddy
相关产品推荐
相关产品推荐

