获取存储过程中执行的每个语句的 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 设置 module
和 action
,然后使用它们从 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_monitor
:
Performing 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)
我有以下存储过程:
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 设置 module
和 action
,然后使用它们从 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_monitor
:
Performing 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) |