找出PL / SQL脚本正在等待的内容

时间:2014-01-06 10:03:10

标签: sql oracle plsql

让我们假设一个用户正在运行一个巨大的PL / SQL脚本,由2000行组成,在那里的某个地方,有一个声明“等待”某些条件变为真。为此,使用了像这个例子的结构:

BEGIN

  --Wail until 2 o clock
  WHILE (to_date('06-01-2014 02:00','dd-mm-yyyy hh24:mi') > sysdate)
  LOOP
    DBMS_LOCK.SLEEP(60);
  END LOOP;

  --code to execute after 2 o clock

END;

现在脚本中有几种这样的结构,脚本似乎永远在运行,所以用户问我它在哪里。 困难在于我可以在动态性能视图中看到它正在运行,例如使用此查询:

SELECT S.USERNAME,
  s.sid,
  s.osuser,
  t.sql_id,
  sql_text
FROM v$sqltext_with_newlines t,
  V$SESSION s
WHERE t.address  =s.sql_address
AND t.hash_value = s.sql_hash_value
AND s.status     = 'ACTIVE'
AND s.username  <> 'SYSTEM'
ORDER BY s.sid,
  t.piece;

但是这会返回整个脚本,而不是它当前的声明。有没有办法解决这个问题?

2 个答案:

答案 0 :(得分:6)

我不知道如何获得当前正在执行的PL / SQL程序行。

但您可以在sleep语句之前使用dbms_application_info.set_module/set_action,它将在v$session.module/action列中显示。

SQL> select sys_context('USERENV', 'SID') from dual;

SYS_CONTEXT('USERENV','SID')
--------------------------------------------------------------------------------
273


SQL> exec dbms_application_info.set_module('My program', 'Waiting for the hell to freeze');

PL/SQL procedure successfully completed.


SQL> exec dbms_lock.sleep(60);

....

在另一场会议中:

SQL> select sid, module, action from v$session where sid = 273;

       SID MODULE                 ACTION
---------- ---------------------- ----------------------------------
       273 My program             Waiting for the hell to freeze

答案 1 :(得分:1)

@Kombajnzbożowy建议的是在运行时跟踪plsql执行的最佳方法 - 如果您已准备好并在脚本中设置调用。

如果您遇到未使用dbms_application_info的代码:

  1. v$session有几个有用的专栏

    v$session.sql_id将为您提供当前正在运行的sql语句 - 即使在plsql块中执行。

    v$session.event - 为您提供等待事件。我觉得 dbms_lock被视为空闲(检查自己)。

    v$session.ROW_WAIT_OBJ#是object_id 等待事件中当前对象的(dba_objects.object_id)。

  2. v$active_session_info - v$session的快照。你可以追溯 自给定时间以来的会话并查询上述列。
  3. 另外一件事,不是每60秒循环一次并检查日期是否已经过去 - 计算到达所需时间的秒数并且只是等待是不是更简单?