【问题标题】:Liquibase data loading into HSQLDB with a sequence使用序列将 Liquibase 数据加载到 HSQLDB
【发布时间】:2011-06-12 02:20:47
【问题描述】:

我正在尝试使用 Liquibase 1.9.5 将一些数据加载到 HSQLDB 数据库中。我有一个loadData 命令如下:

<loadData tableName="LIST_ITEM_TYPE" file="data/global/list_item_type.csv">
    <column name="ID" type="NUMERIC" />
    <column name="NAME" type="STRING" />
    <column name="DESCRIPTION" type="STRING" />
</loadData>

在我的 CSV 数据文件中,我尝试将 ID 值设置为现有序列中的下一个值:

id,name,description
next value for SEQ_ITEM_TYPE_ID,Test Name,A test description

但是,这不起作用,因为它会生成以下 SQL:

INSERT INTO LIST_ITEM_TYPE (id, description, name) VALUES ('next value for SEQ_ITEM_TYPE_ID', 'A test description', 'Test Name')

几乎是正确的,除了 Liquibase 在 next value for SEQ_ITEM_TYPE_ID 周围添加的单引号导致 HSQLDB 给出以下错误:

java.sql.SQLException: data exception: invalid character value for cast

如果我删除 sinqle 引号并手动运行该 SQL,它会按预期工作。

所以,我的问题是,如何使用 Liquibase loadData 命令从 CSV 文件中提取数据,同时从序列中填充其中一列?

【问题讨论】:

  • 哦,是的,我们正在使用 HSQLDB 2.0,如果这很重要的话。

标签: hsqldb liquibase


【解决方案1】:

您可以通过在目标表上定义触发器以在插入的值是您定义的常量时使用序列来实现此目标。查看相关问题 Link a sequence with to an identity in hsqldb

您的 CSV 可能应该包含一个负值的 ID 列,这应该在触发器 WHEN 子句中进行检查。

CREATE TRIGGER trigg BEFORE INSERT ON list_item_type REFERENCING NEW ROW AS newrow FOR EACH ROW WHEN (id < 0) SET newrow.id = NEXT VALUE FOR seq_item_type_id;

或者,使用 CSV 在列中插入一些序列号。导入数据后,使用 UPDATE 语句将值设置为 seequece。当桌子不是很大时,这很实用。如果 ID 是主键,请注意插入中的序号确保插入成功。

UPDATE list_item_type SET id = NEXT VALUE FOR seq_item_type_id

第三种选择(不使用 Liquibase)是将导入文件创建为 SQL 插入语句而不是 CSV。这可以使用 SQLTool(HSQLDB 实用程序)导入 HSQLDB

【讨论】:

  • 谢谢,我没有考虑过使用触发器,尽管这似乎是我们不应该做的额外工作。如果几天后没有其他建议,将接受您的答案。
【解决方案2】:

使用 liquibase 2.0,您可能有更多选择。如果它被定义为数字,它可能不再引用 id 值,和/或您可以扩展 loadData 更改类以包含 SQL。

【讨论】:

  • 这是正确的。我在 Liquibase 2.0 中测试了相同的场景,它不再添加单引号。谢谢!
【解决方案3】:

您可以指定该列是计算值:

<column name="id" type="computed"/>

这可以防止 liquibase 在值周围加上引号。

【讨论】:

  • 有了这个解决方案,我可以使用 SEQNAME.NEXTVAL。太棒了!
【解决方案4】:

你可以这样使用标签:

<modifySql>
   <replace 
        replace="'next value for SEQ_ITEM_TYPE_ID'" 
        with="next value for SEQ_ITEM_TYPE_ID">
</modifySql>

【讨论】:

    【解决方案5】:

    使用 liquibase 3.2 的解决方案非常适合我:

     <createTable tableName="mytable">
            <column autoIncrement="true" name="id" type="BIGINT">
                <constraints primaryKey="true" primaryKeyName="mytablePK" />
            </column>
            ...
    </createTable>
    

    该定义还将创建“mytable”表和“mytable_id_seq”序列。 然后,在 CSV 中定义数据时,只需省略那里的 ID 列。 Liquibase 将完成剩下的工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-18
      • 2020-09-18
      • 1970-01-01
      • 1970-01-01
      • 2011-08-22
      • 2015-06-23
      相关资源
      最近更新 更多