代码之家  ›  专栏  ›  技术社区  ›  Nicolai Parlog

如果插入后重新启动Identifier列,脚本文件中出错

  •  1
  • Nicolai Parlog  · 技术社区  · 10 年前

    插入行后,是否可以重新启动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 s、 documentation 没有暗示为什么这是必要的。

    我最终将不得不在2.2.4版本上完成这项工作,但当前版本2.3.2也有同样的问题。

    出身背景

    我在这里要做的是重新创建一个明显发生在生产中的情况:与数据库的不幸交互(我不知道具体发生了什么)似乎导致了新插入的行与现有的行发生冲突,因为它们的ID相同。我想创建一个复制场景的测试,以便编写正确的修复程序。

    2 回复  |  直到 10 年前
        1
  •  1
  •   Nicolai Parlog    10 年前

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

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

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

    像这样的问题的实际解决方法是用主键列中的最大值加一重新启动。

        2
  •  0
  •   Vlad Mihalcea    7 年前

    我想 SEQUENCES are much more flexible 而不是身份。顺便说一下,IDENTITY生成器禁用了JDBC批处理。

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

    使用序列 the restart 是这样的:

    ALTER SEQUENCE my_seqeunce RESTART WITH 105;