DBMS_APPLICATION_INFO 패키지는 의미하는 바와 같이, 애플리케이션의 정보를 제공할 수 있게 한다. DBMS_APPLICATION_INFO 패키지를 통해 설정된 값은 V$SESSION, V$SQLAREA에 조회해 출력할 수도 있고, 패키지내의 제공된 컴포넌트로 출력해 볼 수도 있다. 이에 대한 내용은 아래의 예제를 보면 쉽게 알 수 있으므로, 별도의 설명이 필요없으리라 생각된다. 여기서는 SQL*PLUS상에서 패키지의 사용법에 대해 설명한뒤, PL/SQL, PRO*C에서 사용법을 차례로 설명하겠다.
DBMS_APPLICATION_INFO패키지가 제공하는 Subprogram은 다음과 같다.
set_module(module_name in varchar2, action_name in varchar2) 현재 실행중인 모듈명을 설정 모듈명은 식별하기 용이한 아무이름이나 지정할 수 있다.
set_action 현재 모듈내에서 진행중인 작업명을 설정. 작업에 맞게 적당한 이름(select중.., update중..)을 아무이름이나 지정하면 된다.
read_module set_module에서 지정한 모듈명을 읽어옴
set_client_info 세션의 client_info필드를 설정
read_client_info 세션의 client_info필드를 읽어옴
set_session_longops long operations에 대한 설정인데 여기에 대해선 설명을 따로 하지 않겠다. 필요하면 스스로 알아보기 바란다.
V_SESSION : module, action, client_info V$SQLAREA : module, action
[예제] SQL> conn system/manager Connected. SQL> @?/rdbms/admin/dbmsutil.sql
SQL> connect kang/xxxxxx Connected. SQL> exec dbms_application_info.set_module('dbakorea','test...');
PL/SQL procedure successfully completed.
SQL> col module format a20 SQL> col action format a20 SQL> col client_info format a20 SQL> select module, action, client_info from v$session where module is not null;
MODULE ACTION CLIENT_INFO -------------------- -------------------- -------------------- T.O.A.D. T.O.A.D. dbakorea test...
SQL> exec dbms_application_info.set_action('select member table..');
PL/SQL procedure successfully completed.
SQL> select module, action, client_info from v$session 2 where module is not null;
MODULE ACTION CLIENT_INFO -------------------- -------------------- -------------------- T.O.A.D. T.O.A.D. dbakorea select member table. .
SQL> select * from member;
ID PASS NAME ---------- ---------- ---------- maddog 1111 강명규 superman 1111 슈퍼맨 dbakorea 1111 강명규
SQL> exec dbms_application_info.set_action('update member table');
PL/SQL procedure successfully completed.
SQL> select module, action, client_info from v$session 2 where module is not null;
MODULE ACTION CLIENT_INFO -------------------- -------------------- -------------------- T.O.A.D. T.O.A.D. dbakorea update member table
SQL> update member set name='superman' where name='슈퍼맨';
1 행이 갱신되었습니다.
SQL> commit;
Commit complete.
SQL> col sql_text format a50 SQL> col action format a20 SQL> select sql_text, disk_reads, module, action from v$sqlarea where module='dbakorea';
SQL_TEXT DISK_READS MODULE ACTION -------------------------------------------------- ---------- -------------------- -------------------- BEGIN dbms_application_info.set_action('select mem 0 dbakorea test... ber table..'); END;
select * from member 0 dbakorea test... select module, action, client_info from v$session 0 dbakorea test... where module is not null
select sql_text, disk_reads, module, action from v 0 dbakorea update member table $sqlarea where module='dbakorea'
위에서는 client_info에 대한 설정을 하지 않았는데, 마저 설정하고 다시 v$session을 보자.
SQL> exec dbms_application_info.set_client_info('test.. by myunggyu');
PL/SQL procedure successfully completed.
SQL> select module, action, client_info from v$session where module is not null;
MODULE ACTION CLIENT_INFO -------------------- -------------------- -------------------- T.O.A.D. T.O.A.D. dbakorea update member table test.. by myunggyu
SQL>
v$session과 v$sqlarea에서 얻을 수 있는 정보는 dbms_application_info패키지내의 read_module, read_client_info컴포넌트로부터 얻을 수도 있다. 그럼, session과 v$sqlarea대신 read_module, read_client_info를 이용해 출력해 보겠다.
SQL> set serveroutput on SQL> var module_name varchar2(48) SQL> var action_name varchar2(32) SQL> var client_info varchar2(64) SQL> exec dbms_application_info.read_module(:module_name, :action_name);
PL/SQL procedure successfully completed.
SQL> print module_name
MODULE_NAME -------------------------------------------------------------------------------------------------------------------------------- dbakorea
SQL> print action_name
ACTION_NAME -------------------------------- update member table
SQL> exec dbms_application_info.read_client_info(:client_info);
PL/SQL procedure successfully completed.
SQL> print client_info
CLIENT_INFO -------------------- test.. by myunggyu
[적용사례] SQL*PLUS에서 매번 위와 같이 하기 보다는 PL/SQL이나 PRO*C에서 사용하면 유용할 것이다. 오래 걸리는 작업이나 락 걸린 프로세스의 현재 진행과정을 파악하면 어디에서 문제가 되는지 파악하기 용이할 것이다. 아래에 PL/SQL을 이용하는 프로시저의 예를 보였다.
SQL> create or replace procedure add_member( 2 v_id varchar2, 3 v_pass varchar2, 4 v_name varchar2 5 ) 6 AS 7 begin 8 dbms_application_info.set_module('add_member', 'insert data into member'); 9 insert into member(id, pass, name) values (v_id, v_pass, v_name); 10 dbms_application_info.set_module('',''); 11 end; 12 /
Procedure created.
SQL> exec add_member('america', '1111', '깡패');
PL/SQL procedure successfully completed.
위와 같이 했을때 insert 과정에서 오래 걸린다면(그럴리가 거의 없겠지만), v$session과 v$sqlarea를 조회하면 'insert data into member'작업중 hang이 걸린다는 것을 파악할 수 있을 것이다. INSERT가 금방 끝난다면 INSERT후 모듈명,작업명이 둘다 NULL로 변경될 것이다. 음.. 결론을 내리자면, dbms_application_info는 디버그용으로 Oracle trace, SQL trace에서 이용된다고 하겠다.
PRO*C에서는 다음과 같은 방식으로 하면 되겠다.
int connect_DB(char *uid, char *passwd) { /* DB서버에 접속 */ EXEC SQL WHENEVER SQLERROR DO sql_error("ORACLE error--\n"); EXEC SQL CONNECT :uid IDENTIFIED BY :passwd; EXEC SQL CALL DBMS_APPLICATION_INFO.SET_MODULE('PROC_APP', 'CONNECTED'); return 1; }
int select_DB(char *id) { varchar name[11]; EXEC SQL CALL DBMS_APPLICATION_INFO.SET_ACTION('SELECT MEMBER TABLE'); EXEC SQL select name INTO :name from member where id = :id; if(sqlca.sqlcode == 1403) { err_print("존재하지 않는 ID: [%s]\n", id); return -1; } else { out_print("[%s] ID를 가진 사람의 이름은 [%.*s]입니다.\n", id, name.len, name.arr); return 1; } }
|