让我们假设一个用户正在运行一个巨大的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;
但是这会返回整个脚本,而不是它当前的声明。有没有办法解决这个问题?
答案 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
的代码:
v$session
有几个有用的专栏
v$session.sql_id
将为您提供当前正在运行的sql语句 -
即使在plsql块中执行。
v$session.event
- 为您提供等待事件。我觉得
dbms_lock
被视为空闲(检查自己)。
v$session.ROW_WAIT_OBJ#
是object_id
等待事件中当前对象的(dba_objects.object_id
)。
v$active_session_info
- v$session
的快照。你可以追溯
自给定时间以来的会话并查询上述列。