获取存储过程中执行的每个语句的 SQL ID

Getting the SQL ID's of each statement executed in a stored procedure

我有以下存储过程:

create or replace procedure insert_employee_to_dept (f_name IN varchar2, l_name IN varchar2, dept IN varchar2, tier IN char)
is
    dept_count number;
    t1_count number;
begin
    INSERT INTO employees (id, first_name, last_name, department, tier)
        VALUES (employee_sequence.NEXTVAL, 
                f_name,
                l_name, 
                dept,
                tier);
    select count(*) into dept_count from employees where department = dept;
    update dept_info set emp_count = dept_count where id = dept;
    select count(*) into t1_count from employees where tier = 1;
    update company set tier_one_count = t1_count where name = 'MyCompany';
end;

我使用下面的语句启用 SQL ID 反馈

set feedback on sql_id;

最后我 运行 我的存储过程是这样的:

call insert_employee_to_dept('John', 'Doe', 'Finance', '5')

上述命令的输出包含 PL/SQL 块的 SQL id 但此块没有可以使用 DBMS_XPLAN.DISPLAY_CURSOR[=16= 查询的执行块]

有没有办法获取调用存储过程时执行的所有 SQL ID?

this answer 之后,我启用了跟踪并 运行 在服务器上生成跟踪文件的过程。不幸的是,在我的用例中,我无法访问数据库服务器的文件系统

如果你这样做是为了测试目的,你可以使用 dbms_application_info 设置 moduleaction,然后使用它们从 v$[= 到 select 25=]$sqlarea/v$active_session_history/etc:

SQL> declare
  2     n number;
  3  begin
  4     dbms_application_info.set_module('test_module','test_action');
  5     select/*+test1*/ count(*) into n from dual;
  6     select/*+test2*/ count(*) into n from dual;
  7     dbms_application_info.set_module('','');
  8  end;
  9  /

PL/SQL procedure successfully completed.

SQL> select sql_id,substr(sql_text,1,50) sqltext50
  2  from v$sqlarea
  3  where module='test_module'
  4    and action='test_action';

SQL_ID        SQLTEXT50
------------- ------------------------------------
bavxnddfrxju6 SELECT/*+test2*/ COUNT(*) FROM DUAL
7d8853usybzdg SELECT/*+test1*/ COUNT(*) FROM DUAL

顺便说一句,您也可以将 module/action/client_id 用于 dbms_monitorPerforming Application Tracing DBMS_MONITOR

或者有时您甚至可以使用 v$open_cursor(取决于许多因素,例如 open_cursor 参数等):

SQL> declare
  2     n number;
  3  begin
  4     dbms_application_info.set_module('test_module','test_action');
  5     select/*+test10*/ count(*) into n from dual;
  6     select/*+test11*/ count(*) into n from dual;
  7     dbms_application_info.set_module('','');
  8  end;
  9  /

PL/SQL procedure successfully completed.

SQL> select sql_id,substr(sql_text,1,50) sqltext50
  2  from v$open_cursor
  3  where sid=userenv('sid')
  4  and user_name=user
  5  and last_sql_active_time is not null
  6  order by last_sql_active_time desc
  7  fetch first 5 rows only;

SQL_ID        SQLTEXT50
------------- ---------------------------------------------------
3669hp0tndbgu declare    n number; begin    dbms_application_inf
9szagfb62bhgs SELECT/*+test10*/ COUNT(*) FROM DUAL
9h8pabdtrb1wm select sql_id,substr(sql_text,1,50) sqltext50 from
1901dfp1ktg5d SELECT/*+test11*/ COUNT(*) FROM DUAL
bavxnddfrxju6 SELECT/*+test2*/ COUNT(*) FROM DUAL

您可以使用all_statements系统视图获取在PL/SQL单元中执行的所有语句及其SQL_ID

create table t (
  id int,
  val int
)
/

create or replace procedure test_proc(
  p_id in int
)
as
begin
  insert into t(id, val) values(p_id, 100);
  update t set val = 10;
  delete from t where id = p_id;
end;
/

begin
  test_proc(1);
end;
/

select
  owner
  , object_type
  , object_name
  , type
  , line
  , sql_id
  , text
from all_statements
/
OWNER OBJECT_TYPE OBJECT_NAME TYPE LINE SQL_ID TEXT
DEMO PROCEDURE TEST_PROC DELETE 8 85cd3d95cya5x DELETE FROM T WHERE ID = :B1
DEMO PROCEDURE TEST_PROC UPDATE 7 d6au94gzv1ydh UPDATE T SET VAL = 10
DEMO PROCEDURE TEST_PROC INSERT 6 bm74chwppp8w4 INSERT INTO T(ID, VAL) VALUES(:B1 , 100)