[20120414]儲存過程遞迴呼叫與V$SQL.txt
[20120414]儲存過程遞迴呼叫與V$SQL.txt
如果儲存過程存在遞迴呼叫看看能否在v$SQL中有記錄呢?前一陣子跟蹤程式,最佳化sql語句的過程中,
發現在儲存過程中再呼叫儲存過程,v$sql中體現不出來。
寫一個例子如下:
CREATE or replace PROCEDURE testfindme( flag VARCHAR2) as
BEGIN
IF flag = '1' THEN
dbms_output.put_line ('flag='||flag);
END IF;
IF flag = '2' THEN
dbms_output.put_line ('flag='||flag);
testfindme('1');
END IF;
END;
/
SQL> select * from v$version ;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
PL/SQL Release 11.2.0.1.0 - Production
CORE 11.2.0.1.0 Production
TNS for Linux: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production
1.檢查是否存在:
SELECT sql_text, sql_id, executions, plsql_exec_time, is_obsolete, is_bind_sensitive, is_bind_aware, is_shareable
FROM v$sql
WHERE lower(sql_text) LIKE '%testfindme%' AND lower(sql_text) NOT LIKE '%v$sql%';
no rows selected
2.測試,如果我執行exec testfindme('2'),可以確定儲存過程會呼叫testfineme('1').
SQL> set SERVEROUT on
SQL> column sql_text format a30
SQL> column is_obsolete format a10
SQL> column is_bind_sensitive format a10
SQL> column is_bind_aware format a10
SQL> column is_shareable format a10
SQL> exec testfindme('2');
flag=2
flag=1
SQL> SELECT sql_text, sql_id, executions, plsql_exec_time, is_obsolete, is_bind_sensitive, is_bind_aware, is_shareable
FROM v$sql
WHERE lower(sql_text) LIKE '%testfindme%' AND lower(sql_text) NOT LIKE '%v$sql%';
SQL_TEXT SQL_ID EXECUTIONS PLSQL_EXEC_TIME IS_OBSOLET IS_BIND_SE IS_BIND_AW IS_SHAREAB
------------------------------ ------------- ---------- --------------- ---------- ---------- ---------- ----------
BEGIN testfindme('2'); END; ahw3y5yzbjkg6 1 177 N N N Y
--可以發現並沒有呼叫testfindme('1')的情況。再執行一次:
SQL> exec testfindme('2');
flag=2
flag=1
PL/SQL procedure successfully completed.
SQL> SELECT sql_text, sql_id, executions, plsql_exec_time, is_obsolete, is_bind_sensitive, is_bind_aware, is_shareable
FROM v$sql
WHERE lower(sql_text) LIKE '%testfindme%' AND lower(sql_text) NOT LIKE '%v$sql%';
SQL_TEXT SQL_ID EXECUTIONS PLSQL_EXEC_TIME IS_OBSOLET IS_BIND_SE IS_BIND_AW IS_SHAREAB
------------------------------ ------------- ---------- --------------- ---------- ---------- ---------- ----------
BEGIN testfindme('2'); END; ahw3y5yzbjkg6 2 301 N N N Y
--奇怪並沒有記錄testfindme('1') 的語句。可以發現儲存過程存在遞迴呼叫在V$SQL中並沒有體現出來!
查詢基表:(sys使用者執行)
SQL> column KGLNAOBJ format a30
SQL> SELECT addr, indx, inst_id, kglhdpar, kglnaobj FROM SYS.x$kglob WHERE lower(KGLNAOBJ) like 'begin%testfindme%';
SQL> SELECT addr, indx, inst_id, kglhdpar, kglnaobj FROM SYS.x$kglob WHERE lower(KGLNAOBJ) like 'begin%testfindme%';
ADDR INDX INST_ID KGLHDPAR KGLNAOBJ
---------------- ---------- ---------- ---------------- ------------------------------
0000002A97467208 1402 1 00000000994F0D10 BEGIN testfindme('2'); END;
0000002A971CB900 1403 1 00000000994F0D10 BEGIN testfindme('2'); END;
3.我執行testfindme('1') 看看結果如何?
SQL> exec testfindme('1');
flag=1
PL/SQL procedure successfully completed.
SQL> SELECT sql_text, sql_id, executions, plsql_exec_time, is_obsolete, is_bind_sensitive, is_bind_aware, is_shareable
FROM v$sql
WHERE lower(sql_text) LIKE '%testfindme%' AND lower(sql_text) NOT LIKE '%v$sql%';
SQL_TEXT SQL_ID EXECUTIONS PLSQL_EXEC_TIME IS_OBSOLET IS_BIND_SE IS_BIND_AW IS_SHAREAB
------------------------------ ------------- ---------- --------------- ---------- ---------- ---------- ----------
BEGIN testfindme('1'); END; 5d8ga1jv253gj 1 111 N N N Y
BEGIN testfindme('2'); END; ahw3y5yzbjkg6 2 301 N N N Y
3.再建立一個新的儲存過程
CREATE or replace PROCEDURE testfindmea( flag VARCHAR2) as
BEGIN
dbms_output.put_line ('flag='||flag);
testfindme('2');
END;
/
SQL> exec testfindmea('3');
flag=3
flag=2
flag=1
PL/SQL procedure successfully completed.
SQL> SELECT sql_text, sql_id, executions, plsql_exec_time, is_obsolete, is_bind_sensitive, is_bind_aware, is_shareable
FROM v$sql
WHERE lower(sql_text) LIKE '%testfindme%' AND sql_text NOT LIKE '%v$sql%';
SQL_TEXT SQL_ID EXECUTIONS PLSQL_EXEC_TIME IS_OBSOLET IS_BIND_SE IS_BIND_AW IS_SHAREAB
------------------------------ ------------- ---------- --------------- ---------- ---------- ---------- ----------
BEGIN testfindme('1'); END; 5d8ga1jv253gj 1 111 N N N Y
BEGIN testfindme('2'); END; ahw3y5yzbjkg6 2 301 N N N Y
SELECT addr, indx, inst_id, kg 5drw5vqu56szv 2 0 N N N Y
lhdpar, kglnaobj FROM SYS.x$kg
lob WHERE lower(KGLNAOBJ) like
'begin%testfindme%'
BEGIN testfindmea('3'); END; 95975a87vmb3b 1 184 N N N Y
--從EXECUTIONS看,雖然testfindmea('3')呼叫了testfindme('2')和testfindme('1'),但是在V$SQL中並沒有體現出來。
可以發現儲存過程存中呼叫其它儲存過程在V$SQL中並沒有體現出來!在最佳化儲存過程中給注意一下!
如果儲存過程存在遞迴呼叫看看能否在v$SQL中有記錄呢?前一陣子跟蹤程式,最佳化sql語句的過程中,
發現在儲存過程中再呼叫儲存過程,v$sql中體現不出來。
寫一個例子如下:
CREATE or replace PROCEDURE testfindme( flag VARCHAR2) as
BEGIN
IF flag = '1' THEN
dbms_output.put_line ('flag='||flag);
END IF;
IF flag = '2' THEN
dbms_output.put_line ('flag='||flag);
testfindme('1');
END IF;
END;
/
SQL> select * from v$version ;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
PL/SQL Release 11.2.0.1.0 - Production
CORE 11.2.0.1.0 Production
TNS for Linux: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production
1.檢查是否存在:
SELECT sql_text, sql_id, executions, plsql_exec_time, is_obsolete, is_bind_sensitive, is_bind_aware, is_shareable
FROM v$sql
WHERE lower(sql_text) LIKE '%testfindme%' AND lower(sql_text) NOT LIKE '%v$sql%';
no rows selected
2.測試,如果我執行exec testfindme('2'),可以確定儲存過程會呼叫testfineme('1').
SQL> set SERVEROUT on
SQL> column sql_text format a30
SQL> column is_obsolete format a10
SQL> column is_bind_sensitive format a10
SQL> column is_bind_aware format a10
SQL> column is_shareable format a10
SQL> exec testfindme('2');
flag=2
flag=1
SQL> SELECT sql_text, sql_id, executions, plsql_exec_time, is_obsolete, is_bind_sensitive, is_bind_aware, is_shareable
FROM v$sql
WHERE lower(sql_text) LIKE '%testfindme%' AND lower(sql_text) NOT LIKE '%v$sql%';
SQL_TEXT SQL_ID EXECUTIONS PLSQL_EXEC_TIME IS_OBSOLET IS_BIND_SE IS_BIND_AW IS_SHAREAB
------------------------------ ------------- ---------- --------------- ---------- ---------- ---------- ----------
BEGIN testfindme('2'); END; ahw3y5yzbjkg6 1 177 N N N Y
--可以發現並沒有呼叫testfindme('1')的情況。再執行一次:
SQL> exec testfindme('2');
flag=2
flag=1
PL/SQL procedure successfully completed.
SQL> SELECT sql_text, sql_id, executions, plsql_exec_time, is_obsolete, is_bind_sensitive, is_bind_aware, is_shareable
FROM v$sql
WHERE lower(sql_text) LIKE '%testfindme%' AND lower(sql_text) NOT LIKE '%v$sql%';
SQL_TEXT SQL_ID EXECUTIONS PLSQL_EXEC_TIME IS_OBSOLET IS_BIND_SE IS_BIND_AW IS_SHAREAB
------------------------------ ------------- ---------- --------------- ---------- ---------- ---------- ----------
BEGIN testfindme('2'); END; ahw3y5yzbjkg6 2 301 N N N Y
--奇怪並沒有記錄testfindme('1') 的語句。可以發現儲存過程存在遞迴呼叫在V$SQL中並沒有體現出來!
查詢基表:(sys使用者執行)
SQL> column KGLNAOBJ format a30
SQL> SELECT addr, indx, inst_id, kglhdpar, kglnaobj FROM SYS.x$kglob WHERE lower(KGLNAOBJ) like 'begin%testfindme%';
SQL> SELECT addr, indx, inst_id, kglhdpar, kglnaobj FROM SYS.x$kglob WHERE lower(KGLNAOBJ) like 'begin%testfindme%';
ADDR INDX INST_ID KGLHDPAR KGLNAOBJ
---------------- ---------- ---------- ---------------- ------------------------------
0000002A97467208 1402 1 00000000994F0D10 BEGIN testfindme('2'); END;
0000002A971CB900 1403 1 00000000994F0D10 BEGIN testfindme('2'); END;
3.我執行testfindme('1') 看看結果如何?
SQL> exec testfindme('1');
flag=1
PL/SQL procedure successfully completed.
SQL> SELECT sql_text, sql_id, executions, plsql_exec_time, is_obsolete, is_bind_sensitive, is_bind_aware, is_shareable
FROM v$sql
WHERE lower(sql_text) LIKE '%testfindme%' AND lower(sql_text) NOT LIKE '%v$sql%';
SQL_TEXT SQL_ID EXECUTIONS PLSQL_EXEC_TIME IS_OBSOLET IS_BIND_SE IS_BIND_AW IS_SHAREAB
------------------------------ ------------- ---------- --------------- ---------- ---------- ---------- ----------
BEGIN testfindme('1'); END; 5d8ga1jv253gj 1 111 N N N Y
BEGIN testfindme('2'); END; ahw3y5yzbjkg6 2 301 N N N Y
3.再建立一個新的儲存過程
CREATE or replace PROCEDURE testfindmea( flag VARCHAR2) as
BEGIN
dbms_output.put_line ('flag='||flag);
testfindme('2');
END;
/
SQL> exec testfindmea('3');
flag=3
flag=2
flag=1
PL/SQL procedure successfully completed.
SQL> SELECT sql_text, sql_id, executions, plsql_exec_time, is_obsolete, is_bind_sensitive, is_bind_aware, is_shareable
FROM v$sql
WHERE lower(sql_text) LIKE '%testfindme%' AND sql_text NOT LIKE '%v$sql%';
SQL_TEXT SQL_ID EXECUTIONS PLSQL_EXEC_TIME IS_OBSOLET IS_BIND_SE IS_BIND_AW IS_SHAREAB
------------------------------ ------------- ---------- --------------- ---------- ---------- ---------- ----------
BEGIN testfindme('1'); END; 5d8ga1jv253gj 1 111 N N N Y
BEGIN testfindme('2'); END; ahw3y5yzbjkg6 2 301 N N N Y
SELECT addr, indx, inst_id, kg 5drw5vqu56szv 2 0 N N N Y
lhdpar, kglnaobj FROM SYS.x$kg
lob WHERE lower(KGLNAOBJ) like
'begin%testfindme%'
BEGIN testfindmea('3'); END; 95975a87vmb3b 1 184 N N N Y
--從EXECUTIONS看,雖然testfindmea('3')呼叫了testfindme('2')和testfindme('1'),但是在V$SQL中並沒有體現出來。
可以發現儲存過程存中呼叫其它儲存過程在V$SQL中並沒有體現出來!在最佳化儲存過程中給注意一下!
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/267265/viewspace-721258/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 遞迴儲存過程中使用cursor遞迴儲存過程
- 呼叫儲存過程儲存過程
- jdbctemplate呼叫儲存過程傳遞陣列引數JDBC儲存過程陣列
- Winform呼叫儲存過程ORM儲存過程
- perl呼叫儲存過程儲存過程
- jdbc呼叫儲存過程JDBC儲存過程
- oracle父儲存過程呼叫子儲存過程procedure與輸出引數Oracle儲存過程
- SQL 儲存過程裡呼叫另一個儲存過程SQL儲存過程
- mysql如何呼叫儲存過程MySql儲存過程
- linux呼叫儲存過程Linux儲存過程
- PB中呼叫儲存過程儲存過程
- java 呼叫oracle 儲存過程JavaOracle儲存過程
- php呼叫mssql儲存過程PHPSQL儲存過程
- java中呼叫儲存過程Java儲存過程
- 在儲存過程A中呼叫儲存過程B的結果儲存過程
- SQL儲存過程迴圈SQL儲存過程
- jsp中呼叫儲存過程JS儲存過程
- Spring mybatis 呼叫儲存過程SpringMyBatis儲存過程
- 用PHP呼叫MySQL儲存過程PHPMySql儲存過程
- c / c + + 呼叫mysql儲存過程MySql儲存過程
- C#呼叫 oracle儲存過程C#Oracle儲存過程
- C#呼叫Oracle儲存過程C#Oracle儲存過程
- 動態呼叫儲存過程 sample:儲存過程
- vb呼叫儲存過程的方法儲存過程
- java中呼叫ORACLE儲存過程JavaOracle儲存過程
- 用java呼叫oracle儲存過程JavaOracle儲存過程
- Sqlsugar呼叫Oracle的儲存過程SqlSugarOracle儲存過程
- 儲存過程呼叫其他模式的儲存過程需要注意的地方儲存過程模式
- 儲存過程語法與Java程式的呼叫方式儲存過程Java
- 儲存過程與儲存函式儲存過程儲存函式
- c# 三步遞交模式呼叫同一個儲存過程C#模式儲存過程
- MySQL儲存過程語句及呼叫MySql儲存過程
- mysql 儲存過程,以及mybatis如何呼叫MySql儲存過程MyBatis
- JDBC 呼叫儲存過程程式碼示例JDBC儲存過程
- PHP呼叫MYSQL儲存過程例項PHPMySql儲存過程
- mysql-定時呼叫儲存過程MySql儲存過程
- c#呼叫儲存過程小記C#儲存過程
- mybatis呼叫檢視和儲存過程MyBatis儲存過程