预览oracle中未排序游标查询的顺序

预览oracle中未排序游标查询的顺序,oracle,dictionary,plsql,Oracle,Dictionary,Plsql,我有一个简单的oracle plsql过程: declare cursor A is select column_A from A_TAB; -- no order by begin for rec_ in A loop procedure_A(rec_.column_A); end loop; end; 这已经运行了很长时间了 当我查看sys.v_u$sql_bind_capture,

我有一个简单的oracle plsql过程:

    declare
      cursor A is
        select column_A
        from A_TAB; -- no order by
    begin
      for rec_ in A loop
        procedure_A(rec_.column_A);
      end loop;
    end;
这已经运行了很长时间了

当我查看sys.v_u$sql_bind_capture,value_string column时,我可以看到绑定列A的当前值,谢天谢地,该值每隔几分钟就不断变化

由于光标没有按任何内容排序,是否有办法查看还有多少记录要处理(直到完成)? 换句话说,我需要查看当前从该游标获取的查询值。去哪里找

这是Oracle 12数据库。

您可以使用它来执行此操作。结果在V$SESSION_LONGOPS中可见

在您的示例中,这可以执行以下操作:

DECLARE
  rindex    BINARY_INTEGER;
  slno      BINARY_INTEGER;
  totalwork number;
  sofar     number;
  obj       BINARY_INTEGER;

  cursor A is
    select column_A,
           COUNT(*) OVER () cnt
    from A_TAB; -- no order by
begin
  rindex := dbms_application_info.set_session_longops_nohint;
  sofar := 0;
  for rec_ in A loop
    totalwork := rec_.cnt;
    sofar := sofar + 1;
    dbms_application_info.set_session_longops(rindex,
                                              slno,
                                              'Process a_tab',
                                              'A_TAB',
                                              0,
                                              sofar,
                                              totalwork,
                                              'table',
                                              'rows');

    procedure_A(rec_.column_A);
  end loop;
end;
请注意,为了获取totalwork值,我使用了解析COUNT()函数来获取resultset中的总行数。如果速度更快,您可以在循环使用原始游标之前运行单独的查询以获取计数。您必须测试这两种方法,以确定哪种方法最适合您的数据等


当然,根据过程a所做的工作,如果您可以重构一些东西,使所有的工作都在一条SQL语句中完成,那么您可能就不需要监视进度了。我上面的回答假设不可能做到这一点。如果是的话,我强烈建议您重构代码

一个选项卡中有多少行?过程A是做什么的?我可能在寻找一种不用修改任何代码就能监控进度的方法。而不是数据字典视图(如果有)?我正在运行大量的升级脚本,并且没有模式,这些脚本中的哪一部分会有性能问题(或者只是长时间运行)。因此,TAB_A可以有数百万条记录,尽管从我的真实示例来看,它只有10k条记录。并且过程A不断更新其他表,尽管为了简单起见,我们可以假设它只有一个“等待1小时语句”。所以我想知道,如果不是确切的顺序,那么还要处理多少条记录。您可能很幸运,在v$session_longops中已经报告了一些内容,因为您正在进行全表扫描。如果做不到这一点,那么除了修改代码之外,你能做的事情就不多了。@user1863063哦,那么你不想让这个过程进行得更快吗?等等,你有10k行,每次迭代调用一个过程需要1小时?让我做一些数学题。。。。好的,大约18个月后,当你的过程结束时再来。这正是问题所在。如果我能看到这将在18个月内完成,我会立即打破它。但是如何查看,如果当前记录ReCi.CulnnA(在V$$SqLyBundS俘获中看到)是来自未排序光标的最后一个,并且整个例程将在下一个小时结束,或者,我们在百万行的中间,还有9个月的时间?如果游标是按排序的,那么我会从一个单独的会话中查询一个_选项卡,从v_$sql_bind_capture中获取当前值,并且我确切地知道我在一个_选项卡中的位置(即,还有多少记录要去)。