【发布时间】:2012-08-09 15:25:37
【问题描述】:
DECLARE
cursor curs is select * from starting;
appleId number;
bananaId number;
BEGIN
for foo in curs
LOOP
insert into apple (id, weight)
values(1,1)
returning id into appleId;
insert into banana(id,weight)
values(1,3)
returning id into bananaId;
insert into apple_banana_lookup
values(1,appleId,bananaId);
END LOOP;
COMMIT;
END;
以上代码导致外键约束违反。声称Apple 中的ID 字段尚不存在。我的问题是如何使上面的代码功能并使 apple_banana_lookup 表成功保留 appleId 和 bananaId 中引用的键。作为补充,我希望避免在每次插入 apple 和 banana 后都必须提交,因为给定游标中将有大约 2 亿条记录。
更新
架构声明:
create table apple
(
id number(20,0) not null,
weight number (20,0)
);
create table banana
(
id number(20,0) not null,
weight number(20,0)
) ;
create table apple_banana_lookup
(
id number(20,0) not null,
appleId number(20,0) not null,
bananaId number(20,0) not null
CONSTRAINT "apple_fk" foreign key ("appleId")
REFERENCES "apple" ("id"),
CONSTRAINT "banana_fk" foreign key ("bananaId")
REFERENCES "banana" ("id"),
);
错误信息:
ORA-02291: integrity constraint
parent key not found
【问题讨论】:
-
你能在第二次插入后试试
commit。 -
@Annjawn 我已经尝试过了,它会导致同样的错误
-
idinapple_banana_lookup不应该是必要的,因为人们会假设元组 [appleId,bananaId] 是独一无二的......而且 2 亿行似乎很多在一个事务中处理 - 根据许多其他因素,您的系统可能只是锁定表。另外,为什么是游标?当 SQL 真正意味着处理集合时,它们往往表示命令式思维。您可以只使用一组标准的INSERTs 吗? -
@X-Zero 如果我这样做,我最终会从
starting表中读取三个表。因为我必须取apple和starting和banana和starting之间的析取,然后从我的查找表中取析取 -
好的,我明白你的意思了。性能节省有那么大吗?我原以为使用游标会将其变成 RBAR(逐行痛苦)情况。