如果我在插入后重新启动标识符列,则脚本文件出错

时间:2015-01-29 13:42:02

标签: java hsqldb

插入行后是否可以重新启动HSQLDB的ID列?我是否可以将其设置为以低于表中现有ID的值重新启动?

情况

我有一个简单的Java程序连接到HSQLDB,如下所示:

DriverManager.getConnection("jdbc:hsqldb:file:" + hsqldbPath, "", "");

这在执行以下脚本时给了我HsqlException(这是摘录,可以找到HSQLDB 2.2.4的完整脚本here):

SET SCHEMA PUBLIC
CREATE MEMORY TABLE PUBLIC.MAP(
    ID BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 0) NOT NULL PRIMARY KEY,
    FOO VARCHAR(16) NOT NULL)
ALTER TABLE PUBLIC.MAP ALTER COLUMN ID RESTART WITH 1
// [...]
SET SCHEMA PUBLIC
INSERT INTO MAP VALUES(1,'Foo')
INSERT INTO MAP VALUES(2,'Bar')
ALTER TABLE PUBLIC.MAP ALTER COLUMN ID RESTART WITH 42

消息是:

HsqlException: error in script file: ALTER TABLE PUBLIC.MAP ALTER COLUMN ID RESTART WITH 42

当我在RESTART之前移动INSERT - 命令时,异常消失了。 documentation没有提示为什么这是必要的。

我最终必须在版本2.2.4上完成这项工作,但在当前版本2.3.2中遇到同样的问题。

背景

我在这里要做的是重新创建一个显然发生在生产中的情况:与数据库的不幸交互(我不知道究竟发生了什么)似乎导致新插入的行与现有的行冲突,因为他们被发给了相同的身份证。我想创建一个复制场景的测试,以便编写适当的修复程序。

2 个答案:

答案 0 :(得分:1)

数据库的.script文件遵循预定义的语句顺序。如果编辑它并且仅允许某些手动更改,则不应更改此项(有关详细信息,请参阅the guide)。

您可以在测试开始时通过JDBC执行ALTER TABLE语句,而不是将其插入脚本中。

如果PRIMARY KEY的IDENTITY值发生冲突,则插入值时会出现异常。

此类问题的实际修复方法是使用主键列中的最大值加一个RESTART。

答案 1 :(得分:0)

我认为SEQUENCES are much more flexible比IDENTITY好。顺便说一句,IDENTITY生成器禁用了JDBC批处理。

但是如果你使用SEQUENCE标识符,你也必须注意hilo optimizers,因为标识符是由Hibernate使用序列值作为基本计算起点生成的。

SEQUENCE the restart是这样的:

ALTER SEQUENCE my_seqeunce RESTART WITH 105;