2011-01-19 44 views
0

我试图使用Liquibase 1.9.5将一些数据加载到HSQLDB数据库中。我有一个loadData命令如下:Liquibase数据加载到HSQLDB的序列

<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 DED给以下错误:

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

如果我删除sinqle报价和手动运行该SQL,它按预期工作。

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

+0

哦,是的,我们正在使用HSQLDB 2.0,如果它很重要的话。 – Andre 2011-01-19 22:06:56

回答

2

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

3

您可以通过在目标表上定义一个触发器来使用序列,以便在插入的值是您定义的常量时实现此目标。查看相关问题 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

+0

谢谢,使用触发器不是我考虑的选项,虽然它看起来像我们不应该做的额外工作。如果在几天后没有其他建议进来,将接受你的答案。 – Andre 2011-01-20 13:55:24

+0

增加了一些替代品。 – fredt 2011-01-20 18:34:20

0

您可以使用这样的标签:

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

解决方案完美地工作对我来说与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将完成剩下的工作。

0

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

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

这样可以防止liquibase从周围放置值引号。