自引用列可能会损坏H2数据库

| 在您不必删除的H2DB上尝试以下操作。警告。这将不可逆转地损坏数据库! 创建一个具有自引用默认列的表。例如,使用ѭ0修改普通表:
create table if not exists BRICK_H2( ID tinyint );
alter table BRICK_H2 alter column ID set default ifnull(
    (select max(ID) from BRICK_H2 for update)+1,0
);
关闭连接并关闭数据库。 再次启动数据库,然后尝试连接。观察错误时的连接失败: 找不到表“ BRICK_H2”; SQL语句: 创建缓存的表PUBLIC.BRICK_H2(     ID TINYINT默认IFNULL((((     最大(ID) 来自PUBLIC.BRICK_H2     / * PUBLIC.BRICK_H2.tableScan * / 更新)+ 1),0) )[42102-155] 42S02 / 42102(帮助) 顺便说一句。请不要回复“使用
auto_increment
”。是的,我知道
auto_increment
列。回滚后,自动增量列会留下空白,并且不会处理所有数据类型。例如,当应用程序使用的算法不是“加常数”的时候,如何自动增加一列?此外,也没有办法将
auto_increment
VARCHAR
,但是您的应用程序可能有一个非常合理的概念。     
已邀请:
        一种解决方案是使用Java函数,例如:
drop all objects;
create table if not exists do_not_brick(id int);
create alias query as $$
String query(Connection conn, String sql) throws SQLException { 
  ResultSet rs = conn.createStatement().executeQuery(sql); 
  rs.next(); 
  return rs.getString(1);
}$$;
alter table do_not_brick alter column id set default
ifnull(query(\'select max(id) from do_not_brick for update\')+1, 0);
insert into do_not_brick() values(), (), ();
select * from do_not_brick;
顺便说一下,\'brick \'是相对的...您仍然可以使用“恢复”工具来检索数据。但是当然不好,它将在下一个版本中修复。问题在于H2不会限制您可以在default子句中执行的操作。其他数据库根本不允许在默认子句中进行任何查询,但我认为这很胆小(这是正确的词吗?),我将尝试找到更好的解决方案(可能允许它)。你有什么建议?     

要回复问题请先登录注册