是否可以使用 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 中来查看计划[并且很可能最终会遇到硬解析和可能不同的计划]。
增加复杂性的一件事是我们使用绑定(bind)变量。对于相同的 sql_id,可能有许多不同的“子计划”,具体取决于绑定(bind)变量查看/直方图。出于这个原因,我对直接查询 v$sql 来获取此信息犹豫不决。我宁愿尝试使用 v$session、dbms_sql 或其他 Tom Kyte 风格的魔法找到某种硬链接(hard link)。
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
清理完后,我将发布一个简洁的示例。感谢您的回复。
最佳答案
这对我有用。
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;
/
关于sql - Oracle pl/sql - 从 dbms_sql 检索 sql_id,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21564691/