sql - Oracle pl/sql - 从 dbms_sql 检索 sql_id

标签 sql oracle plsql

是否可以使用 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/

相关文章:

MySQL 错误 1054 : Unknown Column 'hotels.postal_code' in 'on clause'

sql - ORA-32033 : unsupported column aliasing : Oracle 10g

oracle - 更改 Oracle 客户端注册表中 NLS_LANG 设置的影响

sql - PLSQL CASE WHEN 条件

oracle - 如何使用 Oracle DBMS_LDAP 执行大型(大于 Sizelimit)LDAP 查询

sql - 显示两个范围之间的所有数据点

mysql - 在 WHERE 子句中使用一个 Count() 运算符时出现 GROUP BY 错误

java - UI 组件问题 onPageLoad 方法 ADF oracle

oracle - 如何从plsql存储过程返回集合类型

SQL 查询 : Deleting rows from PostgreSQL with same values