2014년 1월 3일 금요일

(오라클교육)DBMS_PIPE를 이용한 내부 세션 통신 (ORACLE교육) DBMS_PIPE를 이용한...

(오라클교육)DBMS_PIPE를 이용한 내부 세션 통신 (ORACLE교육)

 DBMS_PIPE를 이용한 내부 세션 통신

DBMS_PIPE 패키지는 내부 세션 통신을 위한 알고리즘을 제공하는데(물론 보안은 되지 않습니다.) … 두 가지 정도의 pipe level이 존재하며 다음과 같습니다.

- Public pipe : DBMS_PIPE에 대하 실행 권한을 가진 User가 접근 가능
- Private pipe : pipe를 만든 User에서만 실행 가능

아래 예제는 CREATE_PIPE 함수를 이용한 public, private pipe 예제 입니다.


DECLARE
  l_result  INTEGER;
BEGIN
  -- Explicit public pipe.
  l_result := DBMS_PIPE.create_pipe(pipename => 'explicit_public_pipe',
                                    private  => FALSE);

  -- Explicit private pipe.
  l_result := DBMS_PIPE.create_pipe(pipename => 'explicit_private_pipe');
END;
/

PL/SQL procedure successfully completed.

COLUMN name FORMAT A30
SELECT * FROM v$db_pipes;

  OWNERID NAME                          TYPE    PIPE_SIZE
---------- ------------------------------ ------- ----------
        55 EXPLICIT_PRIVATE_PIPE          PRIVATE        358
          EXPLICIT_PUBLIC_PIPE          PUBLIC        357

2 rows selected.


V$DB_PIPES 뷰는 pipe에 대한 정보를 보여주는 동적 뷰입니다.

다음 예제는 REMOVE_PIPE를 이용한 삭제 예입니다.

DECLARE
  l_result  INTEGER;
BEGIN
  -- Explicit public pipe.
  l_result := DBMS_PIPE.remove_pipe(pipename => 'explicit_public_pipe');

  -- Explicit private pipe.
  l_result := DBMS_PIPE.remove_pipe(pipename => 'explicit_private_pipe');
END;
/

PL/SQL procedure successfully completed.

COLUMN name FORMAT A30
SELECT * FROM v$db_pipes;

no rows selected




아래 예제에서 PACK_MESSAGE함수를 사용하여 버퍼에 메시지를 packing하며 SEND_MESSAGE를 이용하여 메시지를 보내며 RECEIVE_MESSAGE 함수를 이용하여 unpacking하여 메시지를 받습니다.

우선 아래 예제를 참고하세요~

CREATE OR REPLACE PACKAGE message_api AS
  PROCEDURE send (p_number  IN  NUMBER,
                  p_text    IN  VARCHAR2,
                  p_date    IN  DATE DEFAULT SYSDATE);
  PROCEDURE receive;
END message_api;
/
SHOW ERRORS


CREATE OR REPLACE PACKAGE BODY message_api AS
  PROCEDURE send (p_number  IN  NUMBER,
                  p_text    IN  VARCHAR2,
                  p_date    IN  DATE DEFAULT SYSDATE) AS
    l_status  NUMBER;
  BEGIN
    DBMS_PIPE.pack_message(p_number);
    DBMS_PIPE.pack_message(p_text);
    DBMS_PIPE.pack_message(p_date);

    l_status := DBMS_PIPE.send_message('message_pipe');
    IF l_status != 0 THEN
      RAISE_APPLICATION_ERROR(-20001, 'message_pipe error');
    END IF;
  END;
 
  PROCEDURE receive AS
    l_result  INTEGER;
    l_number  NUMBER;
    l_text    VARCHAR2(32767);
    l_date    DATE;
  BEGIN
    l_result := DBMS_PIPE.receive_message (
                  pipename => 'message_pipe',
                  timeout  => DBMS_PIPE.maxwait);
   
    IF l_result = 0 THEN
      -- Message received successfully.
      DBMS_PIPE.unpack_message(l_number);
      DBMS_PIPE.unpack_message(l_text);
      DBMS_PIPE.unpack_message(l_date);
     
      DBMS_OUTPUT.put_line('l_number: ' || l_number);
      DBMS_OUTPUT.put_line('l_text  : ' || l_text);
      DBMS_OUTPUT.put_line('l_date  : ' || l_date);
    ELSE
      RAISE_APPLICATION_ERROR(-20002, 'message_api.receive was unsuccessful. Return result: ' || l_result);
    END IF;             
  END receive;
END message_api;
/

SQL>SHOW ERRORS

SQL>CONN test/test
SQL>SET SERVEROUTPUT ON
SQL>EXEC message_api.receive;
In another session, run the following code to send a message.
SQL>CONN test/test
SQL>BEGIN
  message_api.send(p_number => 12345,
                  p_text  => 'This is a test.',
                  p_date  => SYSDATE);
END;
/

SQL> CONN test/test
Connected.

SQL> SET SERVEROUTPUT ON

SQL> EXEC message_api.receive;
l_number: 12345
l_text  : This is a test.
l_date  : 20-NOV-2005 13:35:57

PL/SQL procedure successfully completed.

댓글 없음:

댓글 쓰기