嵌套游标在游标中

时间:2011-12-12 22:05:45

标签: oracle plsql oracle10g cursor nested-loops

我有一个

的光标
CURSOR B_CUR IS select DISTINCT big_id from TEMP_TABLE;

这会返回多个值。之前它被用作

FOR b_id IN B_CUR LOOP
    select s.col1, s.col2 INTO var1, var2 from sometable s where s.col3 = b_id.col1;
END LOOP;

之前确定内部选择查询总是返回1行。现在,此查询可以返回多行。我怎样才能改变这种逻辑?

我正在考虑创建一个嵌套游标,它将获取一个记录类型的数组(我将声明),但我不知道嵌套游标如何在这里工作。

我主要担心的是效率。因为它将在每次执行时处理数百万条记录。你们能提出一下这里最好的方法吗?

2 个答案:

答案 0 :(得分:3)

通常,您只需加入两个表格。

FOR some_cursor IN (SELECT s.col1,
                           s.col2
                      FROM sometable s
                           JOIN temp_table t ON (s.col3 = t.col1))
LOOP
  <<do something>>
END LOOP

因为你关注效率,但是

  • TEMP_TABLE真的是临时表吗?如果是这样,为什么? Oracle实际上需要使用临时表非常罕见,因此我怀疑您可能正在做一些低效的事情来填充临时表。
  • 为什么有一个游标FOR循环来处理来自TEMP_TABLE的数据?逐行处理是在PL / SQL中执行任何操作的最慢方式,因此如果您关注效率,通常可以避免这种情况。从性能的角度来看,您希望最大化SQL,以便不是执行一系列单行INSERTUPDATE操作的循环,而是执行单个INSERTUPDATE修改了整个行集。如果你真的需要以块的形式处理数据,那就是PL / SQL集合和批量处理可以使用的地方,但是效率不如直接SQL。
  • 为什么在DISTINCT的查询中有TEMP_TABLE?你真的希望有重复的big_id值不是错误的吗?大多数情况下,人们错误地使用DISTINCT来掩盖数据未正确连接的问题,或者强迫Oracle进行昂贵的排序,以防万一在将来出现不正确的数据时是保护自己的更合适的方式。

答案 1 :(得分:0)

FOR b_id IN B_CUR LOOP 
  for c_id in  (select s.col1, s.col2 INTO var1, var2 from sometable s where s.col3 = b_id.col1)loop
    ......
  end loop;
END LOOP;