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

Time:03-03

I have the following 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;

I enable SQL ID feedback using below statement

set feedback on sql_id;

Finally I run my Stored Procedure as such:

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

The output of the above command contains the SQL id of the PL/SQL block but this block does not have an execution block which can be queried using DBMS_XPLAN.DISPLAY_CURSOR

Is there a way to get all the SQL ID's that were executed when the stored procedure was called?

Following this answer, I enabled tracing and ran the procedure which generated the trace file on the server. Unfortunately in my use case I do not have access the file system of the database server

CodePudding user response:

If you doing that for testing purpose, you can use dbms_application_info to set module and action, and then use them to select from v$sql/v$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

Btw, you can use module/action/client_id also for dbms_monitor: Performing Application Tracing DBMS_MONITOR

Or sometimes you can even use v$open_cursor (depends on many factors like open_cursor parameter, etc):

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

CodePudding user response:

You may use all_statements system view to get all the statements executed in PL/SQL unit and their SQL_ID's.

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)
  • Related