在 Oracle 中使用 ROWNUM 插入行

Insert Rows Using ROWNUM In Oracle

在我的代码中,我试图根据行号在 for 循环中插入数据。我想使用它的原因是因为否则我会得到一个 "single-row subquery returns more than one row" 错误,因为我的 select 子查询 return 不止一行,确实而且很明显我想一次插入一个.

declare
begin
for x in (select * from PilotKeyLookup) loop
if x.p2id != null then
insert into BridgeTable (groupid, pilotid) values (sqBridgeGroupID.nextval, (select p1id from PilotKeyLookup));
insert into BridgeTable (groupid, pilotid) values (sqBridgeGroupID.currval, (select p2id from PilotKeyLookup));
else
insert into BridgeTable (groupid, pilotid) values (sqBridgeGroupID.nextval, (select p1id from PilotKeyLookup));
end if;
end loop;
end;

这就是我尝试使用 rownum 的方式:

declare
begin
for x in (select * from PilotKeyLookup) loop
if x.p2id != null then
insert into BridgeTable (groupid, pilotid) values (sqBridgeGroupID.nextval, (select p1id from PilotKeyLookup where rownum = x));
insert into BridgeTable (groupid, pilotid) values (sqBridgeGroupID.currval, (select p2id from PilotKeyLookup where rownum = x));
else
insert into BridgeTable (groupid, pilotid) values (sqBridgeGroupID.nextval, (select p1id from PilotKeyLookup where rownum = x));
end if;
end loop;
end;

但是,我收到 "expression is of wrong type" 错误。 有什么建议吗?

您可能需要一个条件插入 INSERT ... WHEN ... THEN,像这样:

CREATE TABLE PilotKeyLookup(
  p1id int, p2id int
);

INSERT INTO PilotKeyLookup VALUES( 5, null );
INSERT INTO PilotKeyLookup VALUES( 6, 7 );

CREATE TABLE BridgeTable(
   groupid int, pilotid int
);

CREATE SEQUENCE sqBridgeGroupID;

INSERT
  WHEN 1 = 1 THEN INTO BridgeTable( groupid, pilotid ) 
                  VALUES ( sqBridgeGroupID.nextval, p1id )
  WHEN p2id is not null THEN INTO BridgeTable( groupid, pilotid ) 
                  VALUES ( sqBridgeGroupID.currval, p2id )
SELECT *
FROM PilotKeyLookup p;



select * from BridgeTable;

   GROUPID    PILOTID
---------- ----------
         1          5 
         2          6 
         2          7 

你的代码有两个问题

1) 使用x.p1id代替子查询和

2) 抱歉,这个 x.p2id != null 不起作用...... **IS NOT null* 必须使用!

这有效...

declare
begin
for x in (select * from PilotKeyLookup) loop
if x.p2id is  not null then
insert into BridgeTable (groupid, pilotid) values (sqBridgeGroupID.nextval, x.p1id);
insert into BridgeTable (groupid, pilotid) values (sqBridgeGroupID.currval, x.p2id);
else
insert into BridgeTable (groupid, pilotid) values (sqBridgeGroupID.nextval, x.p1id);
end if;
end loop;
end;

...但是您应该按照其他答案中的建议明确使用没有游标循环的解决方案。

作为练习者,您可以将两种方法的性能与一些非常重要的数据量进行比较,您会明白为什么避免循环(如果可能的话)是个好主意。