我们有一个Oracle数据库,我们有一个表,我们在其中存储了很多数据。这个表有一个主键,通常这些主键是在插入新行时创建的。
但是现在我们需要用某些固定的主键手动地将数据插入到这个表中。没有办法改变这些主键。
例如::
我们的表已经有20个主键1到20的条目,现在我们需要用主键21到23手动添加数据。
当有人想使用我们的标准方法输入一行时,插入过程将失败,原因是:
Caused by: java.sql.BatchUpdateException: ORA-00001: Unique Constraint (VDMA.SYS_C0013552) verletzt
at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:10500)
at oracle.jdbc.driver.OracleStatementWrapper.executeBatch(OracleStatementWrapper.java:230)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)我完全理解这一点:创建下一个主键的数据库例程(序列)失败了,因为下一个主键已经被接受了。
但是:我如何告诉我的序列再次查看表,并意识到下一个主键是24而不是21 ?
更新
ID需要保持不变的原因是使用包含ID的链接使用Web接口访问记录,所以要么更改将旧ID映射为新ID的实现,要么将ID保留在数据库中。
UPDATE2
找到了一个解决方案:因为我们使用hibernate,所以只有一个序列正在填充所有的表。因此,在我寻找答案的那4天中,主键太高了,所以我可以保存所有数据。
发布于 2016-05-21 14:52:57
我如何告诉我的序列再次查看表,并意识到下一个主键是24而不是21?
在Oracle中,序列不知道您打算将其用于任何特定的表。所有序列都知道它的当前值,它的增量,它的最大值等等。因此,您不能告诉序列来查看表,但是可以告诉存储过程检查表,然后将序列增加到主键的最大值val之后。换句话说,如果您真的坚持用非序列值手动更新主键,那么您的代码需要检查PK中的非序列值,并在使用该序列生成新的PK之前使序列达到速度。
下面是一些简单的东西,您可以使用它来使序列达到所需的位置:
select testseq.nextval from dual; 每次运行它时,序列都会增加1。将其放入一个for循环中,然后运行它,直到testseq.currval达到您需要的位置为止。
话虽如此,我同意@a_horse_with_no_name和@EdStevens的观点。如果必须手动插入行,请至少在插入中使用sequence_name.nextval,而不是像'21‘这样的文字。如下所示:
create table testtab (testpk number primary key, testval number);
create sequence testseq start with 1 increment by 1;
insert into testtab values (testseq.nextval, '12');
insert into testtab values (testseq.nextval, '123');
insert into testtab values (testseq.nextval, '1234');
insert into testtab values (testseq.nextval, '12345');
insert into testtab values (testseq.nextval, '123456');
select * from testtab;
testpk testval
2 12
3 123
4 1234
5 12345
6 123456https://stackoverflow.com/questions/37361713
复制相似问题