You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Liquibase中runAlways为true的changeset如何使用<preconditions>标签?

解决方案

1 基于<preconditions>标签的实现方式

核心思路是不修改已执行过的原有changeset,避免触发checksum校验规则,新增独立changeset通过前置条件实现DROP IF EXISTS的等效逻辑,完全不需要添加<validCheckSum>标签。
你之前的报错本质是修改了已经存入DATABASECHANGELOG表的changeset内容,导致新计算的checksum和历史记录不匹配,不改动原有changeset就能从根源避免这个问题。

实现代码如下:

<!-- 原有id为foo-1的changeset完整保留,不要做任何修改 -->
<changeSet dbms="voltdb" author="foo" id="foo-1" runAlways="true">
        <sql>DROP PROCEDURE BAR</sql>
        <rollback/>
</changeSet> 

<!-- 新增独立的changeset,通过preconditions控制执行逻辑 -->
<changeSet dbms="voltdb" author="foo" id="foo-2" runAlways="true">
    <!-- 前置条件:校验BAR存储过程是否存在,不存在则直接标记为已执行,不报错 -->
    <preConditions onFail="MARK_RAN">
        <sqlCheck expectedResult="1">
            SELECT COUNT(*) FROM SYS.PROCEDURES WHERE UPPER(PROCEDURE_NAME) = 'BAR'
        </sqlCheck>
    </preConditions>
    <sql>DROP PROCEDURE BAR</sql>
    <rollback/>
</changeSet>

参数说明:

  • onFail="MARK_RAN":如果前置条件不满足(存储过程不存在),Liquibase会直接将该changeset标记为已执行,跳过后续SQL执行,不会抛出错误,等效于IF EXISTS的效果
  • 适配VoltDB的系统表规则,使用SYS.PROCEDURES查询存储过程是否存在,加UPPER避免大小写敏感问题

该方案符合Liquibase的最佳实践,所有变更均有独立记录,相比<validCheckSum>ANY</validCheckSum>完全跳过校验的逻辑安全性更高,避免后续误改changeset无法被发现的问题。

2 其他替代方案

如果一定要修改原有changeset的内容,不需要新增changeset,可以直接执行liquibase clearCheckSums命令,该命令会清空DATABASECHANGELOG表中所有历史checksum记录,下次执行时会重新计算所有changeset的checksum并写入表中,不会再触发校验失败错误。
注意该命令全局生效,执行前需确认所有现有changeset内容均为正确版本,避免误更新。

内容的提问来源于stack exchange,提问作者Deep Dalsania

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 03:54:03