Liquibase唯一约束的前提条件(indexExists)对HSQLDB数据库不起作用吗?

时间:2016-09-08 08:56:50

标签: hsqldb liquibase

当我使用Liquibase升级现有的HSQLDB数据库(数据库不包含2个Liquibase控制表 - databasechangelog databasechangeloglock )时脚本(显示如下),报告java.sql.SQLSyntaxErrorException: object name already exists: SOME_TABLE_UK in statement [ALTER TABLE PUBLIC.SOME_TABLE ADD CONSTRAINT SOME_TABLE_UK UNIQUE (COLUMN_3, COLUMN_4)]时出错。

<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
    <property name="TYPE_AS_ID" value="VARCHAR2(36 BYTE)" dbms="oracle" />
    <property name="TYPE_AS_ID" value="VARCHAR(36)" dbms="postgresql" />
    <property name="TYPE_AS_ID" value="VARCHAR(36)" dbms="hsqldb" />

    <property name="TYPE_AS_NORMAL_TEXT" value="VARCHAR2(255 BYTE)" dbms="oracle" />
    <property name="TYPE_AS_NORMAL_TEXT" value="TEXT" dbms="postgresql" />
    <property name="TYPE_AS_NORMAL_TEXT" value="VARCHAR(255)" dbms="hsqldb" />

    <changeSet author="RayChen" id="1">
        <preConditions onFail="MARK_RAN">
            <not>
                <tableExists tableName="SOME_TABLE" />
            </not>
        </preConditions>
        <createTable tableName="SOME_TABLE">
            <column name="COLUMN_1" type="${TYPE_AS_ID}">
                <constraints nullable="false" />
            </column>
            <column name="COLUMN_2" type="${TYPE_AS_ID}" />
            <column name="COLUMN_3" type="${TYPE_AS_NORMAL_TEXT}" />
            <column name="COLUMN_4" type="${TYPE_AS_NORMAL_TEXT}" />
        </createTable>
    </changeSet>

    <changeSet author="RayChen" id="2">
        <preConditions onFail="MARK_RAN">
            <not>
                <tableExists tableName="SOME_OTHER_TABLE" />
            </not>
        </preConditions>
        <createTable tableName="SOME_OTHER_TABLE">
            <column name="COLUMN_1" type="${TYPE_AS_ID}">
                <constraints nullable="false" />
            </column>
            <column name="COLUMN_2" type="${TYPE_AS_NORMAL_TEXT}" />
        </createTable>
    </changeSet>

    <changeSet author="RayChen" id="3">
        <preConditions onFail="MARK_RAN">
            <not>
                <primaryKeyExists tableName="SOME_TABLE" />
            </not>
        </preConditions>
        <addPrimaryKey constraintName="SOME_TABLE_PK" tableName="SOME_TABLE" columnNames="COLUMN_1" />
    </changeSet>

    <changeSet author="RayChen" id="4">
        <preConditions onFail="MARK_RAN">
            <not>
                <primaryKeyExists tableName="SOME_OTHER_TABLE" />
            </not>
        </preConditions>
        <addPrimaryKey constraintName="SOME_OTHER_TABLE_PK" tableName="SOME_OTHER_TABLE" columnNames="COLUMN_1" />
    </changeSet>

    <changeSet author="RayChen" id="5">
        <preConditions onFail="MARK_RAN">
            <not>
                <foreignKeyConstraintExists foreignKeyName="SOME_TABLE_FK" />
            </not>
        </preConditions>
        <addForeignKeyConstraint constraintName="SOME_TABLE_FK" baseTableName="SOME_TABLE" baseColumnNames="COLUMN_2" referencedTableName="SOME_OTHER_TABLE" referencedColumnNames="COLUMN_1" deferrable="false" initiallyDeferred="false" onDelete="RESTRICT" onUpdate="RESTRICT" />
    </changeSet>

    <changeSet author="RayChen" id="6">
        <preConditions onFail="MARK_RAN">
            <not>
                <indexExists indexName="SOME_TABLE_UK" />
            </not>
        </preConditions>
        <addUniqueConstraint constraintName="SOME_TABLE_UK" tableName="SOME_TABLE" columnNames="COLUMN_3, COLUMN_4" />
    </changeSet>
</databaseChangeLog>

但我已在更改集中添加了 not indexExists 前提条件,以创建 SOME_TABLE_UK 唯一键,如下所示,为什么会出现上述错误?

<changeSet author="RayChen" id="6">
    <preConditions onFail="MARK_RAN">
        <not>
            <indexExists indexName="SOME_TABLE_UK" />
        </not>
    </preConditions>
    <addUniqueConstraint constraintName="SOME_TABLE_UK" tableName="SOME_TABLE" columnNames="COLUMN_3, COLUMN_4" />
</changeSet>

让我更加困惑的是,当数据库是Oracle或PostgreSQL时,Liquibase脚本运行良好且没有错误(由于 not indexExists 前提条件,将跳过上述更改集#6 ),类似的代码运行良好,主键和外键没有错误。

1 个答案:

答案 0 :(得分:0)

有另一种方法可以解决此问题。您可以使用sql系统对象来管理自己的前提条件。 (我不确定这是否是正确的HSQLDB语法)

<changeSet author="RayChen" id="6">
        <preConditions onFail="MARK_RAN">
             <sqlCheck expectedResult="0">SELECT COUNT(*) FROM sys.objects WHERE name LIKE 'SOME_TABLE_UK%'</sqlCheck>
        </preConditions>
        <addUniqueConstraint constraintName="SOME_TABLE_UK" tableName="SOME_TABLE" columnNames="COLUMN_3, COLUMN_4" />
<changeSet/>