DBMS_SESSION包小議(一)
除了使用ALTER SESSION設定會話的狀態,利用V$SESSION查詢會話狀態,Oracle還提供了PL/SQL介面DBMS_SESSION來查詢和設定會話相關的狀態。
描述UNIQUE_SESSION_ID和IS_SESSION_ACTIVE函式。
一般來說設定會話級的狀態都是透過ALTER SESSION語句,也有個別的例外,比如角色的設定是透過SET語句實現的。Oracle除了提供SQL的方法外,還提供了PL/SQL的介面,DBMS_SESSION包,將會話狀態的設定和查詢整合在這個包中。
首先看一下UNIQUE_SESSION_ID函式:
SQL> SELECT DBMS_SESSION.UNIQUE_SESSION_ID FROM DUAL;
UNIQUE_SESSION_ID
----------------------------------------------------------------
0051466F0001
這個函式很簡單,返回的值在資料庫的一個會話的宣告週期中是唯一確定的。
不過光有這個值似乎沒有什麼意義,因為無法關聯到V$SESSION檢視,因此找不到和會話之前的關係。
檢查這個值,最後四位0001比較可疑,似乎是一個序列號之類的東西,而前面的應該和會話的資訊有關。
顯然這是一個十六進位制的數值,將其轉化為十進位制:
SQL> SELECT TO_NUMBER('0051466F', 'XXXXXXXX') FROM DUAL;
TO_NUMBER('0051466F','XXXXXXXX')
--------------------------------
5326447
這個數值也看不出什麼特點,不過既然懷疑這個值和V$SESSION會話有關,而V$SESSION中唯一確定會話資訊的是SID和SERIAL#兩個值,不妨將兩個值都取出來觀察一下:
SQL> SELECT SID, SERIAL#, SID*SERIAL# FROM V$SESSION
2 WHERE SID IN (SELECT SID FROM V$MYSTAT WHERE ROWNUM = 1);
SID SERIAL# SID*SERIAL#
---------- ---------- -----------
81 18031 1460511
這裡將SID和SERIAL#相乘沒有什麼其他的含義,只是簡單的測試,比較剛才得到的數值比較大,而SID和SERIAL#都是比較小的資料。
而相乘後得到的結果比較有意思,雖然並不等於上面的值,但是顯然和上面的值的資料級是一樣的,而且要小於上面的值。看來上面得到的值很可能就是SID和SERIAL#兩個值構成的:
SQL> SELECT 81*65536 FROM DUAL;
81*65536
----------
5308416
SQL> SELECT 81*65536 + 18031 FROM DUAL;
81*65536+18031
--------------
5326447
選擇65536是因為65536是大於18031且是16的冪的最小值。果然得到的結果就是SID*65536 + SERIAL#:
SQL> SELECT SID * 65536 + SERIAL#
2 FROM V$SESSION
3 WHERE SID IN
4 (SELECT SID
5 FROM V$MYSTAT
6 WHERE ROWNUM = 1);
SID*65536+SERIAL#
-----------------
5326447
其實不轉化為10進位制也可以很方便的構造出DBMS_SESSION.UNIQUE_SESSION_ID的結果:
SQL> SELECT LTRIM(TO_CHAR(SID, '0XXX')) || LTRIM(TO_CHAR(SERIAL#, '0XXX')) || '0001' M_ID,
2 DBMS_SESSION.UNIQUE_SESSION_ID S_ID
3 FROM V$SESSION
4 WHERE SID =
5 (SELECT SID
6 FROM V$MYSTAT
7 WHERE ROWNUM = 1);
M_ID S_ID
-------------- ------------------------------
0051466F0001 0051466F0001
根據UNIQUE_SESSION_ID的結果,可以檢查會話是否存活:
SQL> SET SERVEROUT ON
SQL> DECLARE
2 V_RESULT BOOLEAN;
3 BEGIN
4 V_RESULT := DBMS_SESSION.IS_SESSION_ALIVE('&UNQIE_SESSION_ID');
5 IF V_RESULT THEN
6 DBMS_OUTPUT.PUT_LINE('ACTIVE');
7 ELSIF NOT V_RESULT THEN
8 DBMS_OUTPUT.PUT_LINE('NOT ACTIVE');
9 ELSE
10 DBMS_OUTPUT.PUT_LINE('NULL RESULT');
11 END IF;
12 END;
13 /
輸入 unqie_session_id 的值: 0051466F0001
原值 4: V_RESULT := DBMS_SESSION.IS_SESSION_ALIVE('&UNQIE_SESSION_ID');
新值 4: V_RESULT := DBMS_SESSION.IS_SESSION_ALIVE('0051466F0001');
ACTIVE
PL/SQL 過程已成功完成。
重新啟動一個會話:
SQL> SET SQLP 'SQL2> '
SQL2> SELECT DBMS_SESSION.UNIQUE_SESSION_ID FROM DUAL;
UNIQUE_SESSION_ID
--------------------------------------------------------------------------------
00723D6D0001
對這個會話ID執行檢查:
SQL> DECLARE
2 V_RESULT BOOLEAN;
3 BEGIN
4 V_RESULT := DBMS_SESSION.IS_SESSION_ALIVE('&UNQIE_SESSION_ID');
5 IF V_RESULT THEN
6 DBMS_OUTPUT.PUT_LINE('ACTIVE');
7 ELSIF NOT V_RESULT THEN
8 DBMS_OUTPUT.PUT_LINE('NOT ACTIVE');
9 ELSE
10 DBMS_OUTPUT.PUT_LINE('NULL RESULT');
11 END IF;
12 END;
13 /
輸入 unqie_session_id 的值: 00723D6D0001
原值 4: V_RESULT := DBMS_SESSION.IS_SESSION_ALIVE('&UNQIE_SESSION_ID');
新值 4: V_RESULT := DBMS_SESSION.IS_SESSION_ALIVE('00723D6D0001');
ACTIVE
PL/SQL 過程已成功完成。
將會話2斷開連線:
SQL2> DISC
從 Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options 斷開
SQL2>
再次檢查DBMS_SESSION.IS_SESSION_ALIVE的值:
SQL> DECLARE
2 V_RESULT BOOLEAN;
3 BEGIN
4 V_RESULT := DBMS_SESSION.IS_SESSION_ALIVE('&UNQIE_SESSION_ID');
5 IF V_RESULT THEN
6 DBMS_OUTPUT.PUT_LINE('ACTIVE');
7 ELSIF NOT V_RESULT THEN
8 DBMS_OUTPUT.PUT_LINE('NOT ACTIVE');
9 ELSE
10 DBMS_OUTPUT.PUT_LINE('NULL RESULT');
11 END IF;
12 END;
13 /
輸入 unqie_session_id 的值: 00723D6D0001
原值 4: V_RESULT := DBMS_SESSION.IS_SESSION_ALIVE('&UNQIE_SESSION_ID');
新值 4: V_RESULT := DBMS_SESSION.IS_SESSION_ALIVE('00723D6D0001');
NOT ACTIVE
PL/SQL 過程已成功完成。
需要注意,這裡檢查的值和V$SESSION檢視中STATUS列的值沒有關係,V$SESSION檢視中STATUS列指出當前這個會話是否處於活動狀態,而IS_SESSION_ALIVE的值指出這個會話是否還存在,於當前是否活動無關。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4227/viewspace-629866/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- DBMS_SESSION包小議(八)Session
- DBMS_SESSION包小議(七)Session
- DBMS_SESSION包小議(六)Session
- DBMS_SESSION包小議(五)Session
- DBMS_SESSION包小議(四)Session
- DBMS_SESSION包小議(三)Session
- DBMS_SESSION包小議(二)Session
- 小議Linux安全防護(一)Linux
- tshark 抓包 mysql 協議包MySql協議
- WireShark——IP協議包分析(Ping分析IP協議包)協議
- 小議服務程式與會話(一)會話
- 小議IMP操作引數COMMIT=Y(一)MIT
- 小議解析parse
- oracle nomount小議Oracle
- 深入理解 web 協議(一)- http 包體傳輸Web協議HTTP
- HTTP協議資料包HTTP協議
- 小議Oracle外來鍵約束脩改行為(一)Oracle
- TCP協議小結TCP協議
- UDP協議抓包分析 -- wiresharkUDP協議
- Javascript 閉包小結JavaScript
- WCF Data Service 使用小結 (一)—— 瞭解OData協議協議
- 【譯】寫一款小眾的 flutter 圖示包Flutter
- [譯] 建立併釋出一個小而美的 npm 包NPM
- 小知識二、Then協議協議
- 資料庫安全小議資料庫
- 小議“資料開放”
- 小議星型轉換
- 小議軟體測試
- Http網路協議包 (快速理解)HTTP協議
- 使用WireShark抓包分析TCP協議TCP協議
- Wireshark中的TCP協議包分析TCP協議
- Android開發一點小技巧和建議獻上Android
- python閉包小例子Python
- 微信小程式抓包-windows微信小程式Windows
- 智慧小程式檔案館——小程式包更新
- 如何減小微信小程式程式碼包大小微信小程式
- Wireshark資料抓包分析(網路協議篇)第1章網路協議抓包概述協議
- 小議分析函式中排序對結果的影響(一)函式排序