合 Oracle如何让普通用户可以杀掉自己用户的会话
本文简介
普通用户想要杀掉会话必须要有ALTER SYSTEM的权限,但是该权限过大,用户可能使用该权限错杀其它用户的会话,所以,有没有其它办法可以实现该功能呢?该类问题也是DBA中常遇到的问题,下边作者给出一种解决方案。
首先,可以创建一个查询自己会话信息的视图,将该视图创建公共同义词,然后创建一个存储过程,该存储过程实现杀会话的需要,最后将该存储过程赋权给PUBLIC即可解决这个问题。
【这也是小麦苗即将出版的书中的一个小小节,提前分享给大家,o(∩_∩)o ,希望大家到时候多多捧场。】
代码分享
代码实现过程如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | CREATE OR REPLACE VIEW VW_MYOWNERSESSION_LHR AS SELECT * FROM V$SESSION WHERE USERNAME = USER; CREATE OR REPLACE PUBLIC SYNONYM SYN_MYOWNERSESSION_LHR FOR SYS.VW_MYOWNERSESSION_LHR; CREATE OR REPLACE PROCEDURE PRO_KILL_MYOWN_SESSION_LHR(P_INST IN NUMBER, P_SID IN NUMBER, P_SERIAL# IN NUMBER) IS V_IGNORE PLS_INTEGER; V_VERSION VARCHAR2(10); V_INST_ID NUMBER; BEGIN SELECT COUNT(*) INTO V_IGNORE FROM GV$SESSION D WHERE USERNAME = USER AND SID = P_SID AND SERIAL# = P_SERIAL# AND D.INST_ID = P_INST; SELECT SUBSTR(V.VERSION, 1, INSTR(V.VERSION, '.') - 1), V.INSTANCE_NUMBER INTO V_VERSION, V_INST_ID FROM V$INSTANCE V; IF (V_IGNORE = 1) THEN IF (V_VERSION = '10' AND V_INST_ID <> P_INST) THEN RAISE_APPLICATION_ERROR(-20001, 'Please connect to 【INSTANCE:' || P_INST || '】,then retry!'); ELSIF (V_VERSION = '10' AND V_INST_ID = P_INST) THEN EXECUTE IMMEDIATE 'ALTER SYSTEM DISCONNECT SESSION ''' || P_SID || ',' || P_SERIAL# || ''' IMMEDIATE'; ELSE EXECUTE IMMEDIATE 'ALTER SYSTEM DISCONNECT SESSION ''' || P_SID || ',' || P_SERIAL# || ',@' || P_INST || ''' IMMEDIATE'; END IF; ELSE RAISE_APPLICATION_ERROR(-20002, 'You do not own session ''' || P_SID || ',' || P_SERIAL# ||',@' || P_INST || ''''); END IF; END PRO_KILL_MYOWN_SESSION_LHR; / CREATE OR REPLACE PUBLIC SYNONYM PRO_KILL_SESSION_LHR FOR SYS.PRO_KILL_MYOWN_SESSION_LHR; GRANT SELECT ON SYN_MYOWNERSESSION_LHR TO PUBLIC; GRANT EXECUTE ON PRO_KILL_SESSION_LHR TO PUBLIC; |
使用方法:
1 2 3 4 5 | SELECT USERENV('INSTANCE'),USERENV('SID') FROM DUAL; SELECT V.INST_ID, SID,SERIAL#,PADDR,STATUS FROM SYN_MYOWNERSESSION_LHR V WHERE SID=1008 AND V.INST_ID=1 ;--假设上一步查询出来的SID为1008,实例号为1 EXEC PRO_KILL_SESSION_LHR(1,1008,35038);--假设上一步查询出来的SERIAL#为35038 |