如何通过存储过程名得到session id

| No Comments | No TrackBacks

有同事问我"有没有办法,通过存储过程名,取session id"。

答案是有办法的,通过v$access

 

Session 1

SQL> conn caipra/acca@ipratest;

Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.4.0

Connected as caipra

 

SQL> select * from scott.emp;

 

EMPNO ENAME      JOB         MGR HIREDATE          SAL      COMM DEPTNO

----- ---------- --------- ----- ----------- --------- --------- ------

 7369 SMITH      CLERK      7902 1980-12-17     800.00               20

 7499 ALLEN      SALESMAN   7698 1981-2-20     1600.00    300.00     30

 7566 JONES      MANAGER    7839 1981-4-2      2975.00               20

 7654 MARTIN     SALESMAN   7698 1981-9-28     1250.00   1400.00     30

 7698 BLAKE      MANAGER    7839 1981-5-1      2850.00               30

 7782 CLARK      MANAGER    7839 1981-6-9      2450.00               10

 7788 SCOTT      ANALYST    7566 1987-4-19     3000.00               20

 7839 KING       PRESIDENT       1981-11-17    5000.00               10

 7876 ADAMS      CLERK      7788 1987-5-23     1100.00               20

 7900 JAMES      CLERK      7698 1981-12-3      950.00               30

 7902 FORD       ANALYST    7566 1981-12-3     3000.00               20

 7934 MILLER     CLERK      7782 1982-1-23     1300.00               10

 

12 rows selected

 

SQL> select * from scott.bonus;

 

ENAME      JOB              SAL       COMM

---------- --------- ---------- ----------

 

SQL> create or replace procedure P_GET_SID_BY_PNAME is

  2 

  3    vc_name varchar2(10);

  4 

  5  begin

  6 

  7    update scott.emp set sal=1000 where ename='SMITH';

  8    insert into scott.bonus(ENAME,JOB,SAL,COMM) values('SMITH','CLERK',1000,15);

  9 

 10    commit;

 11 

 12    while 1=1 loop

 13      select ename into vc_name from scott.emp where empno=7499;

 14 

 15      if ( vc_name <> 'CUIHUA') then

 16        dbms_lock.sleep(30);

 17      else

 18        exit;

 19      end if;

 20    end loop;

 21 

 22  end P_GET_SID_BY_PNAME;

 23  /

 

Procedure created

 

SQL> select sid from v$mystat where rownum<2;

 

       SID

----------

       408

 

SQL> exec P_GET_SID_BY_PNAME;

Executing......

 

现在我们session 1sid408,我们在这个session中执行了存储过程P_GET_SID_BY_PNAME

 

现在我们要通过这个存储过程的名字P_GET_SID_BY_PNAMEsession 2中把session 1sid给找到,即要得到408

Session 2:

SQL> conn caipra/acca@ipratest;

Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.4.0

Connected as caipra

 

SQL> select sid from v$access where object='P_GET_SID_BY_PNAME';

 

       SID

----------

       408

 

看到了吗,这里我们如愿得到了我们想要的sid

v$access实际上是来源于:

select distinct s.inst_id,s.ksusenum,o.kglnaown,o.kglnaobj,
decode(o.kglobtyp,   0, 'CURSOR',    1, 'INDEX',    2, 'TABLE',    3, 'CLUSTER',   
4, 'VIEW',    5, 'SYNONYM',    6, 'SEQUENCE',    7, 'PROCEDURE',    8, 'FUNCTION',   
9, 'PACKAGE',    10,'NON-EXISTENT',    11,'PACKAGE BODY',    12,'TRIGGER',   
13,'TYPE',    14,'TYPE BODY',    15,'OBJECT',    16,'USER',    17,'DBLINK',   
18,'PIPE',    19,'TABLE PARTITION',    20,'INDEX PARTITION',    21,'LOB',   
22,'LIBRARY',    23,'DIRECTORY',    24,'QUEUE',    25,'INDEX-ORGANIZED TABLE',   
26,'REPLICATION OBJECT GROUP',    27,'REPLICATION PROPAGATOR',    28,'JAVA SOURCE',   
29,'JAVA CLASS',    30,'JAVA RESOURCE',    31,'JAVA JAR',    'INVALID TYPE')
from x$ksuse s,x$kglob o,x$kgldp d,x$kgllk l
where l.kgllkuse=s.addr and l.kgllkhdl=d.kglhdadr
and l.kglnahsh=d.kglnahsh and o.kglnahsh=d.kglrfhsh and o.kglhdadr=d.kglrfhdl;

 

注意这个例子中session 1是一直在执行存储过程P_GET_SID_BY_PNAME,其实这里只要session 1执行过P_GET_SID_BY_PNAME,不管是不是正在执行,有没有执行完毕,只要session 1没断开,v$access里始终会有上述那条sid408的记录。但一旦session 1断开了,v$access里那条记录就没有了。

No TrackBacks

TrackBack URL: http://dbsnake.com/cgi-bin/mt/mt-tb.cgi/15

Leave a comment