foreignKeyConstraintExists如果存在具有相同参考详细信息但名称不同的外键,则前提条件似乎不充足

时间:2016-09-22 04:20:42

标签: liquibase

当我使用Liquibase脚本升级现有数据库时(数据库从未被Liquibase升级),发生以下错误。

liquibase.exception.MigrationFailedException: Migration failed for change set ../master.xml::5::ray.chen:
     Reason: liquibase.exception.DatabaseException: ORA-02275: such a referential constraint already exists in the table
 [Failed SQL: ALTER TABLE CRDM_RCHEN.SOME_TABLE ADD CONSTRAINT SOME_TABLE_FK FOREIGN KEY (COLUMN_2) REFERENCES CRDM_RCHEN.SOME_OTHER_TABLE (COLUMN_1)]

        at liquibase.changelog.ChangeSet.execute(ChangeSet.java:605)
        at liquibase.changelog.visitor.UpdateVisitor.visit(UpdateVisitor.java:51)
        at liquibase.changelog.ChangeLogIterator.run(ChangeLogIterator.java:79)
        at liquibase.Liquibase.update(Liquibase.java:214)
        at liquibase.Liquibase.update(Liquibase.java:192)
        at liquibase.integration.commandline.Main.doMigration(Main.java:1126)
        at liquibase.integration.commandline.Main.run(Main.java:184)
        at liquibase.integration.commandline.Main.main(Main.java:103)

我仔细检查了Liquibase脚本和数据库,数据库中已存在名为 SOME_TABLE_1_FK 的外键。根本原因应该是Liquibase脚本将添加名为 SOME_TABLE_FK 的外键,但已存在名为 SOME_TABLE_1_FK 的外键,其具有相同的引用详细信息和不同的名称。似乎数据库不允许2个外键,这些外键的名称不同,但引用细节相同。

您对此问题有任何解决方案或想法吗?感谢。

这是相关的Liquibase脚本。我使用 foreignKeyConstraintExists 前提条件检查是否存在外键 SOME_TABLE_FK ,如果不存在,则添加;但如果存在具有相同引用详细信息但名称不同的外键(上述情况),则将执行更改集并发生上述错误。

<changeSet author="ray.chen" 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>

2 个答案:

答案 0 :(得分:2)

liquibase提供的foreignKeyConstraintExists需要传递foreignKeyName。为了检查是否有没有名称的外键,您需要编写自定义前置条件。下面是一个相同的例子:

<preConditions onFail="MARK_RAN">
    <not>
        <customPrecondition className="com.ctp.liquibase.ForeignKeyExistsPrecondition">
            <param name="schemaName" value="MYSCHEMA"/>
            <param name="tableName" value="TABLE"/>
            <param name="columnName" value="COLUMN"/>
            <param name="foreignTableName" value="FTABLE"/>
        </customPrecondition>
    </not>
</preConditions>

上面将检查表上的列是否具有外表的外键约束。

您可以找到更多here

答案 1 :(得分:0)

为什么不只检查两个/所有名称?

initState