我正在使用Oracle 11.2g实例。 我想通过自己生成主键值将行插入表中来了解我所暴露的内容。 我会从某些表中选择SELECT max(pk); 然后使用接下来的100个值作为接下来的100个插入。 是在玩火吗?
上下文是:我有大量的插件要做,它们被分割在由外键链接的几个表上。我试图获得良好的性能,而不是使用PL / SQL。
[编辑]这里有一个看起来像我正在处理的代码示例:
QString query1 = "INSERT INTO table 1 (pk1_id, val) VALUES (pk1_seq.nextval, ?)"
sqlQuery->prepare(query);
sqlQuery->addBindValue(vec_of_values);
sqlQuery->execBatch();
QString query2 = "INSERT INTO table 2 (pk2_id, another_val, pk1_pk1_id) VALUES (pk2_seq.nextval, ?, ?)"
sqlQuery->prepare(query);
sqlQuery->addBindValue(vec_of_values);
// How do I get the primary keys (hundreds of them)
// from the first insert??
sqlQuery->addBindValue(vec_of_pk1);
sqlQuery->execBatch();
答案 0 :(得分:0)
您正在暴露自己的性能降低,逻辑错误以及需要维护的额外代码。 Oracle序列针对您的特定目的进行了优化。对于高DML操作,您还可以缓存序列:
ALTER SEQUENCE customers_seq CACHE 100;
答案 1 :(得分:0)
为主表创建序列
使用your_sequence.nextval
插入主表
使用your_sequence.currval
create table parent (id integer primary key not null);
create table child (id integer primary key not null, pid integer not null references parent(id));
create sequence parent_seq;
create sequence child_seq;
insert into parent (id) values (parent_seq.nextval);
insert into child (id, pid) values (child_seq.nextval, parent_seq.currval);
commit;
要解释为什么max(id)无法可靠地工作,请考虑以下情形:
现在想想当你有很多的交易时会发生什么。你会得到很多的错误。此外,您的插入将变得越来越慢,因为计算max(id)的成本将随着表的大小而增加。
序列 是解决此问题的唯一理智(即正确,快速和可扩展)方式。
修改
如果您对另一个无法应对这种策略的ORM感到震惊(现在几乎所有DBMS都支持它 - 甚至SQL Server现在都有序列),那么您应该可以在客户代码:
使用select parent_seq.nextval from dual
将下一个PK值检索到编程语言中的变量中(这是一种快速,可扩展且正确的检索PK值的方法)。
如果您可以运行select max(id)
,还可以运行select parent_seq.nextval from dual
。在这两种情况下,只需使用从该select语句中获得的值。