使用dbms_sql.execute,是否可以以编程方式检索正在执行的查询的sql_id?
这是我失败的尝试:
declare
v_sql_text varchar2(128) := 'select 123 from dual';
v_cursor INTEGER;
v_ret number;
v_sql_id varchar2(13) := null;
BEGIN
v_cursor := dbms_sql.open_cursor;
dbms_sql.parse(v_cursor, v_sql_text, dbms_sql.native);
-- ==================================================
-- attempt 1 - after parse
select prev_sql_id
into v_sql_id
from v$session
where audsid = sys_context('userenv', 'sessionid');
dbms_output.put_line('after parse: ' || v_sql_id);
-- ==================================================
v_ret := dbms_sql.execute(v_cursor);
-- ==================================================
-- attempt 2 - after execute - this doesn't seem to work either
--select prev_sql_id
-- into v_sql_id
-- from v$session
-- where audsid = sys_context('userenv', 'sessionid');
--dbms_output.put_line('after execute: ' || v_sql_id);
-- ==================================================
dbms_sql.close_cursor(v_cursor);
END;
/
1)这甚至可能吗?
2)有更好的方法吗?
其他资讯 - 2014年2月17日
我真的在sql_id 和 child_number之后。
我们使用dbms_scheduler和dbms_sql的组合来“在后台”运行报告。我的目的是捕获并存储两条信息 - sql_id和child_number - 每次运行报告。我想捕获此信息以用于诊断目的(例如 - 可以使用dbms_xplan.display_cursor(sql_id,sql_child)显示运行的特定查询的缓存执行计划)。这样我们就不会依赖企业管理器,也不会将查询文本复制/粘贴到sqlplus中以查看计划[并且很可能最终会得到一个硬解析和可能不同的计划]。
增加复杂性的一件事是我们使用绑定变量。对于相同的sql_id,根据绑定变量偷看/直方图,可能存在许多不同的“子计划”。出于这个原因,我对直接查询v $ sql以获取此信息犹豫不决。我宁愿尝试使用v $ session,dbms_sql或其他一些Tom Kyte风格的巫术找到某种硬链接。
2014年2月21日更新
根据以下来源的信息处理解决方案:
https://dba.stackexchange.com/questions/55609/how-to-use-the-dbms-sql-to-get-the-analyze-for-insert-into-statement http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:40832696008013
我会在清理后发布一个简洁的例子。谢谢你的回复。
答案 0 :(得分:2)
这适合我。
declare
v_sql_text varchar2(128) := 'select 112233 from dual';
v_cursor INTEGER;
v_ret number;
v_sql_id varchar2(13) := null;
BEGIN
v_cursor := dbms_sql.open_cursor;
dbms_sql.parse(v_cursor, v_sql_text, dbms_sql.native);
v_ret := dbms_sql.execute(v_cursor);
dbms_sql.close_cursor(v_cursor);
--To save time lets only look 5 minutes back
--last_load_time is a varchar that's why we have to use to_date
select sql_id into v_sql_id from v$sql
where dbms_lob.compare(sql_fulltext, v_sql_text) = 0
and to_date(last_load_time,'YYYY-MM-DD/HH24:MI:SS') > sysdate - (5/1440);
dbms_output.put_line('v_sql_id: ' || v_sql_id);
END;
/