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

时间:2017-01-30 16:06:19

标签: 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_ $ sql_bind_capture,value_string列时,我可以看到绑定column_A的当前值,幸运的是,该值每隔几分钟就会不断变化。

由于光标没有被任何东西排序,有没有办法看到要记录多少记录(直到完成)? 换句话说,我需要从该游标中查看当前获取的查询值。在哪里寻找它?

这是Oracle 12数据库。

1 个答案:

答案 0 :(得分:3)

您可以使用youtube执行此操作。结果在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;

请注意,为了获得总工作值,我使用了分析COUNT()函数来获取结果集中的总行数。如果速度更快,您可以在循环原始光标之前运行单独的查询以获取计数。您必须测试两种方法才能找到最适合您数据的方法等。

当然,根据procedure_a的作用,如果您可以重构事物,那么您可以避免监视进度的需要,以便所有工作都在单个SQL语句中完成。我上面的回答假设不可能这样做。如果是,我强烈建议您重构代码!