针对mssql的不同数据库版本的不同校验和

时间:2015-02-25 16:51:49

标签: liquibase

我的liquibase changeSets有点问题。

如果我针对MSSQL 2008数据库模式运行我的changeSet,liquibase将生成一个校验和(让我们称之为'x')。 当我针对MSSQL 2012数据库模式运行我的changeSet时,liquibase将为(我的一些变更集)生成一个不同的校验和('y')。

创建不同校验和的变更集示例:

<changeSet author="Camilla" id="25c">
       <preConditions onFail="MARK_RAN">
           <dbms type="db2" />
       </preConditions>

       <comment>extend column abc within table def (db2)</comment>
       <sql >
           ALTER TABLE def ALTER COLUMN abc SET DATA TYPE ${P_VARCHAR}(8)
       </sql>

       <update tableName="VERSION">
           <column name="V_NO" value="0.03"/>
       </update>
   </changeSet>

 <changeSet author="Camilla" id="22">
    <comment>add default value column for mapping</comment>
    <addColumn tableName="MAPPING">
        <column name="M_DEF" type="${P_VARCHAR}(256)"/>
    </addColumn>

    <update tableName="VERSION">
        <column name="V_NO" value="0.027"/>
    </update>
</changeSet>

现在,如果我从2008开始,然后将安装升级到2012,则校验和不再匹配。

我尝试使用'validCheckSum'来解决问题。 起初我想,我需要将校验和放在数据库中(可能是x),而liquibase只是将x更新为新计算的值y。 但后来我发现了讨论understanding validCheckSum,并认识到它是另一种方式。我必须将y放在validCheckSum中,然后将忽略数据库中的任何值。

然而我又找到了主题liquibase-checksum-differs-with-different-database-vendors,而Nathan建议

  

如果您使用像@Andremoniy建议的'validCheckSum',您可以只列出已知有效的校验和,但仍会在所有其他校验和上失败。 - Nathan Voxland 2014年9月24日16:02

但我无法确认这种行为。如果我将<validCheckSum>y</validCheckSum>添加到我的变更集并将数据库中的'x'更改为'z',liquibase将会发生并忽略该'z'。结果是,我永远不会意识到databasechangelog条目中的操作(例如,人们从那里复制来自不同模式的条目,因为“他们知道他们在做什么”)。

据我了解,'validCheckSum'仅适用于那些我希望保护自己免于意外更改可能已使用的更改集的情况。但是我不能在我想确保不操纵databasechangelog的情况下使用它。

一旦我知道数据库版本从2008年改为2012年,这让我成为数据库中校验和的唯一替代选择。在这种情况下,我将交叉检查从数据库校验和中松开,只生成一次。

或者还有另一种方法可以实现我的目标吗?

另一个问题是为什么它与2008年和2012年相比有所不同。 我使用changelog参数:

    liquibase.setChangeLogParameter("P_CHAR", getCharDataType());
    liquibase.setChangeLogParameter("P_VARCHAR", getVarcharDataType());
    liquibase.setChangeLogParameter("P_INT", getIntegerDataType());
    liquibase.setChangeLogParameter("P_LONG", getLongDataType());

    liquibase.setChangeLogParameter("P_DEFAULT_SCHEMA_NAME", defaultSchemaName);

用liquibase-core 2.0.5

有趣的更改集不会生成不同的校验和:

<changeSet author="Camilla" id="17">
    <comment>Added column 'in test mode' (TST) to table </comment>
    <addColumn tableName="EXAMPLE">
        <column name="TST" type="${P_INT}" defaultValueNumeric="0"/>
    </addColumn>

    <update tableName="VERSION">
        <column name="V_NO" value="0.022"/>
    </update>
</changeSet>

如果我在changeSet中使用$ {P_CHAR}或$ {P_VARCHAR},这似乎是一个问题。但是在这两种情况下提供的值都是相同的,因为它只会在NCHAR / CHAR之间变化,这是在我的系统配置中定义的,并且不会随数据库版本而改变。

哦,顺便说一下。我浏览了为DB2生成的校验和,似乎是这种情况,它们与2008年生成的校验和相同。

谢谢, 卡米拉

1 个答案:

答案 0 :(得分:0)

通常Liquibase在计算校验和时不考虑数据库,只考虑XML本身。您看到的差异是因为changelog参数将XML更改为校验和。不改变校验和的属性中的参数问题已在3.x中解决,因此如果升级,您将看到其中的差异。

在升级数据库时,您只有两个选项是使用validCheckSum或从DATABASECANGELOG中清空问题行。

ValidCheckSum是常规方法,您可以在其中列出X和Y校验和,因为您知道这些排列是正确的。它没有解决有人意外更改DATABASECHANGELOG表中的校验和的问题,但我不确定通常会发生这种情况的用例。