游标中嵌套游标

发布于 2024-12-21 00:08:35 字数 429 浏览 1 评论 0原文

我有一个游标,

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 行。现在这个查询可以返回多行。我怎样才能改变这个逻辑?

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

我主要关心的是效率。因为每次执行它都会处理数百万条记录。你们能建议这里最好的方法是什么吗?

I have a cursor which is

CURSOR B_CUR IS select DISTINCT big_id from TEMP_TABLE;

This would return multiple values. Earlier it was being used as

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;

Earlier it was certain that the inner select query would always return 1 row. Now this query can return multiple rows. How can I change this logic?

I was thinking to create a nested cursor which will fetch into an array of record type (which i will declare) but I have no idea how nested cursor would work here.

My main concern is efficiency. Since it would be working on millions of records per execution. Could you guys suggest what would be the best approach here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

心清如水 2024-12-28 00:08:35

通常,您只需连接两个表即可。

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,这样您就不需要执行一系列单行 INSERT 或 UPDATE 操作的循环,而是执行单个操作修改整组行的 INSERTUPDATE。如果您确实需要分块处理数据,那么 PL/SQL 集合和批量处理就可以发挥作用,但这不会像直接 SQL 那样高效。
  • 为什么在针对 TEMP_TABLE 的查询中包含 DISTINCT?您真的希望存在没有错误的重复 big_id 值吗?大多数时候,人们错误地使用 DISTINCT 来掩盖数据错误连接的问题,或者强制 Oracle 进行昂贵的排序,以防将来创建不正确的数据。约束将是保护自己的更合适的方式。

Normally, you would just join the two tables.

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

Since you are concerned about efficiency, however

  • Is TEMP_TABLE really a temporary table? If so, why? It is exceedingly rare that Oracle actually needs to use temporary tables so that leads me to suspect that you're probably doing something inefficient to populate the temporary table in the first place.
  • Why do you have a cursor FOR loop to process the data from TEMP_TABLE? Row-by-row processing is the slowest way to do anything in PL/SQL so it would generally be avoided if you're concerned about efficiency. From a performance standpoint, you want to maximize SQL so that rather than doing a loop that did a series of single-row INSERT or UPDATE operations, you'd do a single INSERT or UPDATE that modified an entire set of rows. If you really need to process data in chunks, that's where PL/SQL collections and bulk processing would come in to play but that will not be as efficient as straight SQL.
  • Why do you have the DISTINCT in your query against TEMP_TABLE? Do you really expect that there will be duplicate big_id values that are not erroneous? Most of the time, people use DISTINCT incorrectly either to cover up problems where data has been joined incorrectly or where you're forcing Oracle to do an expensive sort just in case incorrect data gets created in the future when a constraint would be the more appropriate way to protect yourself.
临风闻羌笛 2024-12-28 00:08:35
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; 
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; 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文