1
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;  

上面的代码导致外键约束违反。声称该ID字段Apple尚不存在。我的问题是如何使上面的代码起作用并让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
4

3 回答 3

2

您的解释中似乎遗漏了某些内容-正确创建表后,您的代码似乎可以正常工作

我假设这是定义apple,bananaapple_banana_lookup表的方式(请注意,由于您没有在插入时指定列列表apple_banana_lookup,我假设表中的列作为您的 PL/SQL 块排序似乎期望他们是)。

SQL> create table apple(
  2    id number primary key,
  3    weight number
  4  );

Table created.

SQL> create table banana(
  2    id number primary key,
  3    weight number
  4  );

Table created.

SQL> create table apple_banana_lookup (
  2    id number primary key,
  3    appleID number references apple(id),
  4    bananaID number references banana(id)
  5  );

Table created.

只是为了避免对您的代码进行任何更改,我创建了一个starting包含 1 行的表

SQL> create table starting( id number );

Table created.

SQL> insert into starting values( 1 );

1 row created.

现在我完全按照您发布的代码运行您的代码。不会产生错误,并且在每个表中插入一行。

SQL> DECLARE
  2   cursor curs is select * from starting;
  3   appleId number;
  4   bananaId number;
  5  BEGIN
  6      for foo in curs
  7      LOOP
  8          insert into apple (id, weight)
  9          values(1,1)
 10          returning id into appleId;
 11          insert into banana(id,weight)
 12          values(1,3)
 13          returning id into bananaId;
 14          insert into apple_banana_lookup
 15          values(1,appleId,bananaId);
 16      END LOOP;
 17      COMMIT;
 18  END;
 19  /

PL/SQL procedure successfully completed.

SQL> select * from apple_banana_lookup;

        ID    APPLEID   BANANAID
---------- ---------- ----------
         1          1          1
于 2012-08-09T15:48:29.247 回答
1
create table apple  
( 
    id number(20,0) not null, 
    weight number (20,0)   
);  --No primary keys here

create table banana  
(   
     id number(20,0) not null, 
     weight number(20,0)  
)  ;  -- No primary keys here


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),   --this wont work
     CONSTRAINT banana_fk foreign key (bananaId)  
      REFERENCES banana(id)  --this wont work
);  

看起来上面的创建语句apple_banana_lookup不起作用。表的引用完整性apple_banana_lookup需要引用引用表上的唯一键。这就是它应该是什么

create table apple  
( 
  id number(20,0) not null, 
  weight number (20,0) ,
  CONSTRAINT apple_pk PRIMARY KEY (id)
);

create table banana  
(   
  id number(20,0) not null, 
  weight number(20,0) , 
  CONSTRAINT banana_pk PRIMARY KEY (id)
)  ;

create table apple_banana_lookup  
( 
      id number(20,0) not null,
      appleId number(20,0) not null,
      bananaId number(20,0) not null,  
      CONSTRAINT app_ban_pk PRIMARY KEY (appleId, bananaId),
      CONSTRAINT apple_fk foreign key (appleId)  
      REFERENCES apple(id),  
     CONSTRAINT banana_fk foreign key (bananaId)  
      REFERENCES banana(id)
); 

所以有了这个,下面的工作就像一个魅力(除了循环之外,它和你的一样) -

SQL> DECLARE    
 appleId number;      
 bananaId number;    
BEGIN    
        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);      
    COMMIT;   
END; 
/

PL/SQL block completed successfully.


SQL> select * from apple;
                  ID               WEIGHT
-------------------- --------------------
                   1                    1

SQL> select * from banana;
                  ID               WEIGHT
-------------------- --------------------
                   1                    3 

SQL> select * from apple_banana_lookup;
                  ID              APPLEID             BANANAID
-------------------- -------------------- --------------------
                   1                    1                    1 
于 2012-08-09T15:51:39.500 回答
0

AFAIR 数据在事务中始终可见,因此您应该能够引用在之前的 INSERT 语句中插入的数据。
我怀疑该错误是指字段名称,而不是字段值。如果您向我们提供了有关错误的更多详细信息,那么我们将能够提供更好的帮助。
也检查您的约束源。

于 2012-08-09T15:41:21.127 回答