2013년 10월 23일 수요일

[ORACLE 외부파일 BFILE 강좌]BFILE을 이용하여 이미지를 DB에 저장/저장된 BFILE을 이용하여 새로운 이미지 생성

 [ORACLE 외부파일 BFILE 강좌]BFILE을 이용하여 이미지를 DB에 저장/저장된 BFILE을 이용하여 새로운 이미지 생성



BFILE을 이용하여 이미지를 DB에 저장/저장된 BFILE을 이용하여 새로운 이미지 생성

아래의 두 PL/SQL 프로시저는 OS의 binary file을 DB의 BFILE 컬럼과 연계하여 작업을 하는 예제 입니다.

Load_BFILE_FROM_Image 프로시저

이 프로시저는 디스크 상의 이미지 파일을 BFILE 컬럼에 저장하는 역할을 합니다. 이 프로시저는 SQL문장안에서 BFILENAME 함수를 사용 하여 BFILE 컬럼을 UPDATE 합니다. 여기서 주의 할 점은 이미지가 디스크 상에 존재 할 뿐 DB에는 저장 되지 않는 다는 것을 명심해야 합니다. 즉 BFILE 컬럼은 OS상의 파일에 대한 포인터를 저장 한다고 보면 됩니다.


Write_BFILE_To_File 프로시저

이 프러시저는 그래픽 파일 등을 내용을 기 저장된 BFILE 참조를 이용하여 어떻게 다시 디스크에 쓰는지에 대해 예를 들고 있습니다. 이때 UTL_FILE.PUT_RAW 프로시저를 이용하여 BFILE 컬럼의 포인터를 읽어 하나씩 디스크에 기록 하게 됩니다.

또한 DBMS_LOB.READ 함수를 이용하여 BFILE 참조로부터 낱낱이 읽어 들여 이를PL/SQL RAW 변수에 넣습니다.

아래의 예를 참고 합니다.

1.        테스트를 위한 테이블, 디렉토리를 만듭니다.

SQL> CREATE TABLE test_bfile (
  2        id          NUMBER(15)
  3      , file_name    VARCHAR2(1000)
  4      , image        BFILE
  5      , timestamp    DATE
  6  )
  7  /

테이블이 생성되었습니다.

SQL> CREATE OR REPLACE DIRECTORY
  2      EXAMPLE_LOB_DIR
  3      AS
  4  'd:\LOBs'
  5  /

디렉토리가 생성되었습니다.


2.        Load_BFILE_From_Image 프러시저를 만듭니다.
(d:\LOBs 폴더에 oraclejava_logo.gif 파일을 복사해 둡니다. 파일 이름은 적절히 수정 하시면 됩니다)

CREATE OR REPLACE PROCEDURE Load_BFILE_From_Image
IS
BEGIN
    DBMS_OUTPUT.ENABLE(100000);
    INSERT INTO test_bfile (id, file_name, image, timestamp)
        VALUES (1001, 'oracle9i_logo.gif', null, sysdate);
    UPDATE test_bfile
        SET image = BFILENAME('EXAMPLE_LOB_DIR', 'oraclejava_logo.gif')
        WHERE id = 1001;
END;


3.        Write_BFILE_To_File 프러시저를 만듭니다.


  CREATE OR REPLACE PROCEDURE Write_BFILE_To_File
  IS
    source_pic      BFILE;
    buffer          RAW(32767);
    buffer_size    CONSTANT BINARY_INTEGER := 32767;
    amount          BINARY_INTEGER;
    offset          NUMBER(38);
    file_handle    UTL_FILE.FILE_TYPE;
    directory_name  CONSTANT VARCHAR2(80) := 'EXAMPLE_LOB_DIR';
    image_filename  CONSTANT VARCHAR2(80) := 'oraclejava_logo2.gif';
    dest_pic        BFILE;
  BEGIN
      DBMS_OUTPUT.ENABLE(100000);
      -- -----------------
      -- GET BFILE LOCATOR
      -- -----------------
      SELECT image INTO source_pic
          FROM test_bfile
          WHERE id = 1001;
      -- ---------------------------------------
      -- OPEN ORIGINAL BFILE IMAGE USING LOCATOR
      -- ---------------------------------------
      DBMS_LOB.FILEOPEN(
          file_loc  => source_pic,
          open_mode  => DBMS_LOB.FILE_READONLY);
      -- ---------------------------------
      -- OPEN NEW IMAGE FILE IN WRITE MODE
      -- ---------------------------------
      file_handle := UTL_FILE.FOPEN(
          location    => directory_name,
          filename    => image_filename,
          open_mode    => 'w',
          max_linesize => buffer_size);
      amount := buffer_size;
      offset := 1;
      -- ---------------------------------------------------
      -- READ FROM BFILE IMAGE / WRITE OUT NEW IMAGE TO DISK
      -- ---------------------------------------------------
      WHILE amount >= buffer_size
      LOOP
          DBMS_LOB.READ(
              file_loc  => source_pic,
              amount    => amount,
              offset    => offset,
              buffer    => buffer);
          offset := offset + amount;
          UTL_FILE.PUT_RAW(
              file      => file_handle,
              buffer    => buffer,
              autoflush => false);
      END LOOP;
      UTL_FILE.FCLOSE(file => file_handle);
      DBMS_LOB.FILEOPEN(file_loc => source_pic);
      -- --------------------------------------------
      -- INSERT THE NEW IMAGE FILE AS A SECOND RECORD
      -- --------------------------------------------
      INSERT INTO test_bfile (id, file_name, image, timestamp)
          VALUES (1002, 'oraclejava_logo2.gif', null, sysdate);
      UPDATE test_bfile
          SET image = BFILENAME('EXAMPLE_LOB_DIR', 'oraclejava_logo2.gif' )
          WHERE id = 1002;
      COMMIT;
* END;
  /

프로시저가 생성되었습니다.

4.        SQL*Plus 에서 테스트 합니다.

SQL> set serveroutput on
SQL> exec Load_BFILE_From_Image

PL/SQL 처리가 정상적으로 완료되었습니다.

SQL> exec Write_BFILE_To_File

PL/SQL 처리가 정상적으로 완료되었습니다.

SQL>
SQL>
SQL> SELECT id, DBMS_LOB.GETLENGTH(image) Length FROM test_bfile;

        ID    LENGTH
---------- ----------
      1001        910
      1002        916

참고) 이제 탐색기에서 보면 oraclejava_logo2.gif가 생겨 났음을 확인 할 수 있습니다. 그런데 이 파일은 원래의 oraclejava_logo.gif 보다 사이즈가 조금 큰데 그 이유는 UTL_FILE.PUT_RAW 프러시저에서 CR/LF가 추가 되어서 그러합니다.

오라클자바커뮤니티에서 설립한 개발자교육6년차 오엔제이프로그래밍 실무교육센터(오라클SQL,튜닝,힌트,자바프레임워크,안드로이드,아이폰,닷넷 실무개발강의)  


[기타 다른 강좌는 아래 해당 카테고리를 클릭해주세요]

댓글 없음:

댓글 쓰기