在Oracle中使用ROWNUM插入行

时间:2016-03-15 20:37:20

标签: oracle rownum

在我的代码中,我试图根据行号在for循环中插入数据。我想使用它的原因是因为否则我得到“单行子查询返回多行”错误,因为我的选择子查询返回多行,实际上显然我想一次插入一个。

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;

但是,我得到一个“表达式错误类型”错误。 有什么建议吗?

2 个答案:

答案 0 :(得分:1)

您可能需要条件插入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 :(得分:0)

您的代码中存在两个问题

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

2)抱歉这x.p2id != 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;

...但你应该明确地使用没有游标循环的解决方案,如其他答案所建议的那样。

作为一个exersize你可以比较两种方法的表现与一些非平凡的数据量,你会明白为什么避免循环是一个好主意(如果可能的话)。