【问题标题】:dynamic table name without using cursors不使用游标的动态表名
【发布时间】:2017-08-11 04:03:36
【问题描述】:

我想在 for 循环中使用动态表名。我知道使用游标可以解决这个问题。但我想知道是否有没有游标的解决方案,因为我当前的代码具有通用 for 循环(隐式游标),我想知道是否可以在不使用显式游标的情况下以相同的方式保留它。

现在对我有用的是:

BEGIN 
for itr in (select var1,var2,var3,var4 from schedule_table)
loop
--work using itr.var1, itr.var2, itr.var3, itr.var4 
end loop
END

我想知道是否可以使用相同类型的 for 循环但动态地将表名传递给它。我查看了执行立即动态 sql 选项,但我认为我无法在 for 循环中使用它。在我开始重新设计整个过程以使用显式游标之前,我只是想在这里检查一下(不是我的忠实粉丝,因为我担心与隐式游标相比的性能)。

谢谢。

【问题讨论】:

  • “恐惧”不能替代基准。鉴于您正在逐行执行模式,管理显式游标的开销似乎很小。

标签: oracle performance plsql


【解决方案1】:

您可以使用EXECUTE IMMEDIATEBULK COLLECT INTO 一个集合并通过它循环:

Oracle 12c

DECLARE
  TYPE t_rec IS RECORD( fname VARCHAR2(100), lname VARCHAR2(100) );
  TYPE t_tab IS TABLE OF t_rec;
  t t_tab;
  v_table_name VARCHAR2(128) := 'HR.EMPLOYEES';
BEGIN
  EXECUTE IMMEDIATE 'SELECT first_name, last_name FROM ' || v_table_name
    BULK COLLECT INTO t;

  FOR i IN 1 .. t.COUNT LOOP
    DBMS_OUTPUT.PUT_LINE( t(i).fname || ' ' || t(i).lname );
  END LOOP;
END;
/

注意:在 Oracle 10/11 中,您需要在 SQL 范围内创建集合类型。在 Oracle 12 中,您可以在 PL/SQL 范围内声明它。

【讨论】:

  • 感谢您的回答。你认为这个动态 sql 解决方案会比使用显式游标更快吗?为了让您了解我们正在处理的数据类型,它是一个包含 3000 行和 100 列的表(全部在 varchar2(10 到 400 字节)上),需要逐行读取并根据它们的数据值计算。
  • 这样大小的表会占用大量会话内存。其影响可能很严重,具体取决于您的资源分配。使用带有 LIMIT 子句的显式游标可以让您更好地控制内存使用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-28
  • 1970-01-01
  • 1970-01-01
  • 2011-06-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多