제16장 DBMS_LOB

내용 목차

16.1. 개요
16.2. 예외
16.3. 프러시저
16.3.1. APPEND
16.3.2. COPY
16.3.3. CONVERTTOBLOB
16.3.4. CONVERTTOCLOB
16.3.5. CREATETEMPORARY
16.3.6. ERASE
16.3.7. FILECLOSE
16.3.8. FILECLOSEALL
16.3.9. FILEGETNAME
16.3.10. FILEOPEN
16.3.11. FREETEMPORARY
16.3.12. LOADFROMFILE
16.3.13. LOADBLOBFROMFILE
16.3.14. OPEN
16.3.15. READ
16.3.16. TRIM
16.3.17. WRITE
16.3.18. WRITEAPPEND
16.4. 함수
16.4.1. CLOSE
16.4.2. COMPARE
16.4.3. FILEEXISTS
16.4.4. FILEISOPEN
16.4.5. GETLENGTH
16.4.6. INSTR
16.4.7. ISOPEN
16.4.8. ISTEMPORARY
16.4.9. SUBSTR

본 장에서는 DBMS_LOB 패키지의 기본 개념과 패키지 내의 프러시저와 함수를 사용하는 방법을 설명한다.

DBMS_LOB은 BLOB, CLOB 또는 BFILE 타입의 컬럼 데이터에 여러 가지 연산을 제공하는 패키지이다. 또한, DBMS_LOB 패키지 내의 프러시저와 함수를 이용하여 대용량 객체형의 전체 또는 일부에 읽기, 쓰기 등의 작업을 수행할 수 있다.

다음은 DBMS_LOB 패키지를 사용할 때 유의해야 할 사항이다.

LOB 데이터를 수행할 때에는 먼저 대상 LOB 데이터를 OPEN 프러시저를 이용하여 열고, 작업이 끝나면 CLOSE 프러시저를 이용하여 닫는다. 이때 OPEN 프러시저로 열린 LOB 데이터를 닫으면 데이터베이스에 갱신된 내용이 반영된다.

반면에 OPEN 프러시저를 실행하여 열지 않은 LOB 데이터에 대해 갱신 연산을 수행하면 바로 데이터베이스에 반영된다. 대개의 경우 LOB 데이터를 갱신하면 많은 디스크 작업이 수반되므로, 여러 번에 걸쳐 데이터베이스에 반영하는 것보다 한번에 모든 갱신을 데이터베이스에 반영하는 것이 효율적이다.

OPEN 프러시저를 실행하여 LOB 데이터를 연 경우에는 COMMIT 문장을 실행하기 전에 반드시 CLOSE 프러시저를 실행하여 닫아야 한다. 만약 열려있는 LOB 데이터가 있는데 COMMIT을 실행하면, 에러가 발생한다. 열려 있는 LOB 데이터가 있을 때 ROLLBACK을 실행하면 모든 갱신은 취소되고 열려 있는 LOB 데이터에 대한 정보도 없어진다.

다음은 DBMS_LOB 패키지 내에 정의된 상수이다.

  • LOBMAXSIZE

    LOB 데이터의 최대 크기이다.

    LOBMAXSIZE CONSTANT BINARY_INTEGER := 18446744073709551615

    데이터 타입은 BINARY_INTEGER이고 LOB 데이터의 최대 크기는 18446744073709551615이다.

  • LOB_READONLY

    LOB 데이터에 대한 읽기 전용의 사용 여부를 설정하는 모드이다.

    LOB_READONLY CONSTANT BINARY_INTEGER := 0

    데이터 타입은 BINARY_INTEGER이고 값이 0이면 읽기 전용으로 설정된다.

  • LOB_READWRITE

    LOB 데이터의 읽기 및 쓰기를 설정하는 모드이다.

    LOB_READWRITE CONSTANT BINARY_INTEGER := 1

    데이터 타입은 BINARY_INTEGER이고 값이 1이면 읽기 및 쓰기로 설정된다.

  • FILE_READONLY

    BFILE 을 열때 사용하는 모드이다.

    FILE_READONLY CONSTANT BINARY_INTEGER := 0

    데이터 타입은 BINARY_INTEGER이고, 파일 열기 모드이며, 읽기 모드만 존재한다.

다음은 DBMS_LOB 패키지에서 미리 제공된 예외이다. 자세한 내용은 “16.3. 프러시저”“16.4. 함수”의 "예외 사항" 항목을 참고한다.

  • INVALID_ARGVAL

  • ACCESS_ERROR

  • NOTEXIST_DIRECTORY

  • NOPRIV_DIRECTORY

  • INVALID_DIRECTORY

  • OPERATION_FAILED

  • UNOPENED_FILE

  • OPEN_TOOMANY

본 절에서는 DBMS_LOB 패키지에서 제공하는 프러시저를 알파벳 순으로 설명한다.

원본 LOB 데이터의 전체 또는 일부를 대상 LOB 데이터에 복사하는 프러시저이다. 이때 복사할 원본 LOB 데이터의 오프셋과 대상 LOB 데이터의 오프셋을 지정할 수 있다. 만약 대상 LOB 데이터의 오프셋이 대상 LOB 데이터의 길이보다 짧으면 오프셋 위치에 존재하는 이전 데이터는 갱신된다.

이와는 반대로 대상 LOB 데이터 오프셋이 대상 LOB 데이터의 길이보다 길면 중간에 0(BLOB 데이터) 또는 공백(CLOB 데이터)으로 채워진다.

COPY 프러시저의 세부 내용은 다음과 같다.

  • 프로토타입

    • BLOB 타입인 경우

      DBMS_LOB.COPY
      (
          dest_lob        IN OUT NOCOPY   BLOB,
          src_lob         IN              BLOB,
          amount          IN              INTEGER,
          dest_offset     IN              INTEGER := 1,
          src_offset      IN              INTEGER := 1
      );
    • CLOB 타입인 경우

      DBMS_LOB.COPY
      (
          dest_lob        IN OUT NOCOPY   CLOB,
          src_lob         IN              CLOB,
          amount          IN              INTEGER,
          dest_offset     IN              INTEGER := 1,
          src_offset      IN              INTEGER := 1
      );

      CLOB 데이터를 전달하는 경우 dest_lob, src_lob 파라미터의 LOB 데이터의 문자 집합이 같아야 한다.

  • 파라미터

    파라미터설명
    dest_lob대상 LOB locator이다.
    src_lob원본 LOB locator이다.
    amount복사할 Byte(BLOB 데이터) 또는 문자(CLOB 데이터)의 개수이다.
    dest_offset

    대상 LOB 데이터 내의 오프셋이다.

    (단위: Byte(BLOB 데이터) 또는 문자(CLOB 데이터))

    src_offset

    원본 LOB 데이터 내의 오프셋이다.

    (단위: Byte(BLOB 데이터) 또는 문자(CLOB 데이터))

  • 예외 상황

    예외 상황설명
    VALUE_ERROR입력 파라미터 중 하나라도 NULL인 경우이다.
    INVALID_POSsrc_offset, dest_offset의 값이 1보다 작거나 LOBMAXSIZE보다 큰 경우이다.
    INVALID_LENamount의 값이 1보다 작거나 LOBMAXSIZE보다 큰 경우이다.
  • 예제

    DECLARE
        dest_lob CLOB := 'It you would be loved, ';
        src_lob CLOB := 'be worthy to be loved';
    BEGIN
        DBMS_LOB.COPY(dest_lob, src_lob, length(src_lob), 
                      length(dest_lob) + 1, 1);
        DBMS_OUTPUT.PUT_LINE('Result = ' || dest_lob);
    END;
    /
    Result = It you would be loved, be worthy to be loved
    
    PSM completed
    SQL> 

입력으로 받은 CLOB을 BLOB으로 변환하는 프러시저이다.

CONVERTTOBLOB 프러시저의 세부 내용은 다음과 같다.

  • 프로토타입

    DBMS_LOB.CONVERTTOBLOB
    (
        dest_lob        IN OUT NO COPY  BLOB,
        src_lob         IN              CLOB,
        amount          IN              INTEGER,
        dest_offset     IN OUT          INTEGER,
        src_offset      IN OUT          INTEGER,
        blob_csid       IN              NUMBER,
        lang_context    IN OUT          INTEGER,
        warning         OUT             INTEGER
    );
  • 파라미터

    파라미터설명
    dest_lob대상 LOB locator이다.
    src_lob원본 LOB locator이다.
    amount복사할 문자의 개수이다.
    dest_offset대상 LOB 데이터 내의 오프셋이다. 출력은 대상 LOB이 저장된 마지막 주소이다. (단위: Byte(BLOB 데이터))
    src_offset원본 LOB 데이터 내의 오프셋이다. 출력은 원본 LOB을 읽은 마지막 주소이다. (단위: 문자(CLOB 데이터))
    blob_csidCLOB에서 변환된 데이터를 BLOB을 저장할 때 사용할 캐릭터 셋의 ID이다.
    lang_context미사용
    warning미사용
  • 예외 상황

    예외 상황설명
    VALUE_ERROR입력 파라미터 중 하나라도 NULL인 경우이다.
  • 예제

    declare
        src_clob                clob;
        dest_blob               blob;
        dest_clob               clob;
    
        amount                  integer;
        dest_offset             integer;
        src_offset              integer;
        blob_csid               integer;
        lang_context            integer;
        warning                 integer;
    
    begin
        src_clob := 'abcdefghijklmn';
        dbms_lob.createtemporary(dest_blob, false);
        dbms_lob.createtemporary(dest_clob, false);
    
        amount := 10;
        dest_offset := 1;
        src_offset := 1;
        blob_csid := 0;
        lang_context := 0;
        warning := 0;
    
        dbms_lob.CONVERTTOBLOB(dest_blob, src_clob, amount,
                               dest_offset, src_offset, blob_csid,
                               lang_context, warning);
    end;
    /
    
    PSM completed
    SQL> 

입력으로 받은 BLOB을 CLOB으로 변환하는 프러시저이다.

CONVERTTOCLOB 프러시저의 세부 내용은 다음과 같다.

  • 프로토타입

    DBMS_LOB.CONVERTTOCLOB
    (
        dest_lob        IN OUT NO COPY  CLOB,
        src_lob         IN              BLOB,
        amount          IN              INTEGER,
        dest_offset     IN OUT          INTEGER,
        src_offset      IN OUT          INTEGER,
        blob_csid       IN              NUMBER,
        lang_context    IN OUT          INTEGER,
        warning         OUT             INTEGER
    );
  • 파라미터

    파라미터설명
    dest_lob대상 LOB locator이다.
    src_lob원본 LOB locator이다.
    amount복사할 문자의 개수이다.
    dest_offset대상 LOB 데이터 내의 오프셋이다. 출력은 대상 LOB이 저장된 마지막 주소이다. (단위: Byte(BLOB 데이터))
    src_offset원본 LOB 데이터 내의 오프셋이다. 출력은 원본 LOB을 읽은 마지막 주소이다. (단위: 문자(CLOB 데이터))
    blob_csidCLOB에서 변환된 데이터를 BLOB로 저장할 때 사용할 캐릭터 셋의 ID이다.
    lang_context미사용
    warning미사용
  • 예외 상황

    예외 상황설명
    VALUE_ERROR입력 파라미터 중 하나라도 NULL인 경우이다.
  • 예제

    declare
        src_clob                clob;
        dest_blob               blob;
        dest_clob               clob;
        amount                  integer;
        dest_offset             integer;
        src_offset              integer;
        blob_csid               integer;
        lang_context            integer;
        warning                 integer;
    begin
        src_clob := 'abcdefghijklmn';
        dbms_lob.createtemporary(dest_blob, false);
        dbms_lob.createtemporary(dest_clob, false);
    
        amount := 10;
        dest_offset := 1;
        src_offset := 1;
        blob_csid := 0;
        lang_context := 0;
        warning := 0;
    
        dbms_output.put_line('org clob : ' || src_clob);
    
        dbms_lob.CONVERTTOBLOB(dest_blob, src_clob, amount,
                               dest_offset, src_offset, blob_csid,
                               lang_context, warning);
    
        dbms_output.put_line('dest offset : ' || dest_offset);
        dbms_output.put_line('srct offset : ' || src_offset);
    
        amount := 20;
        dest_offset := 1;
        src_offset := 1;
        blob_csid := 0;
        lang_context := 0;
        warning := 0;
    
        dbms_lob.CONVERTTOCLOB(dest_clob, dest_blob, amount,
                               dest_offset, src_offset, blob_csid,
                               lang_context, warning);
    
        dbms_output.put_line('dest clob : ' || dest_clob);
        dbms_output.put_line('dest offset : ' || dest_offset);
        dbms_output.put_line('srct offset : ' || src_offset);
    end;
    /
    
    org clob : abcdefghijklmn
    dest offset : 11
    srct offset : 11
    dest clob : abcdefghij
    dest offset : 11
    srct offset : 11
    
    PSM completed.
    
    SQL> 

LOB 데이터의 일부 또는 전체를 삭제하는 프러시저이다. 삭제된 영역은 0(BLOB 데이터) 또는 공백(CLOB 데이터)으로 채워진다. 대상 LOB 데이터의 길이가 오프셋과 삭제할 영역 크기의 합보다 짧다면 실제로 삭제된 영역의 크기는 삭제할 영역으로 입력한 크기보다 작을 수 있다. 실제로 삭제된 영역의 크기는 amount 파라미터로 출력된다.

ERASE 프러시저의 세부 내용은 다음과 같다.

  • 프로토타입

    • BLOB 타입인 경우

      DBMS_LOB.ERASE
      (
          lob         IN OUT NOCOPY   BLOB,
          amount      IN OUT NOCOPY   INTEGER,
          offset      IN              INTEGER := 1
      );
    • CLOB 타입인 경우

      DBMS_LOB.ERASE
      (
          lob         IN OUT NOCOPY   CLOB,
          amount      IN OUT NOCOPY   INTEGER,
          offset      IN              INTEGER := 1
      );
  • 파라미터

    파라미터설명
    lob대상 LOB locator이다.
    amount삭제할 Byte 또는 문자 개수이다.
    offset

    삭제할 오프셋이다.

    (단위: Byte(BLOB 데이터) 또는 문자(CLOB 데이터))

  • 예외 상황

    예외 상황설명
    VALUE_ERROR입력 파라미터가 하나라도 NULL인 경우이다.
    INVALID_POSoffset의 값이 1보다 작거나 LOBMAXSIZE보다 큰 경우이다.
    INVALID_LENamount의 값이 1보다 작거나 LOBMAXSIZE보다 큰 경우이다.
  • 예제

    DECLARE
        lob CLOB := 'Tmaxsoft Tibero';
        amount NUMBER := 7;
    BEGIN
        DBMS_OUTPUT.PUT_LINE('Length of original LOB = ' || length(lob));
        DBMS_LOB.ERASE(lob, amount, 9);
        DBMS_OUTPUT.PUT_LINE('Value of erased LOB = ' || lob);
        DBMS_OUTPUT.PUT_LINE('Length of erased LOB = ' || length(lob));
    END;
    /
    Length of original LOB = 15
    Value of erased LOB = Tmaxsoft
    Length of erased LOB = 15
    
    PSM completed
    SQL> 

File Locator로 읽기 전용, 바이너리 모드로 파일을 연다.

FILEOPEN 프러시저의 세부 내용은 다음과 같다.

  • 프로토타입

    DBMS_LOB.FILEOPEN
    (   
        file_loc     IN OUT NOCOPY   BFILE,
        open_mode    IN              BINARY_INTEGER := file_readonly
    );
  • 파라미터

    파라미터설명
    file_loc열 파일의 Locator이다.
    open_mode파일 읽기 모드(file_readonly) 파라미터만 허용한다.
  • 예외 상황

    예외 상황설명
    VALUE_ERRORFile locator가 NULL인 경우이다.
    INVALID_ARGVALopen_mode에 file_readonly 값외 다른 값이 온 경우이다.
    INVALID_DIRECTORYFile locator에 지정된 디렉터리가 유효하지 않나 존재하지 않는 경우이다.
    NOEXIST_DIRECTORYFile locator에 지정된 디렉터리 경로가 존재하 않는 경우이다.
    OPERATION_FAILED디렉터리 경로에 파일이 존재하지 않거나, 파일 열수 없는 경우이다.
  • 예제

    create directory BFILETESTDIR as '/mybasepath/bfiletest/';
    
    declare 
        f utl_file.file_type; 
    
        buffer raw(16) := '000102030405060708090A0B0C0D0E0F';
    begin 
        f := utl_file.fopen('BFILETESTDIR', 'test001.bin', 'wb');
        utl_file.put_raw(f, buffer);
        utl_file.fclose(f);
    end;
    /
    
    declare
        f1 bfile;
        amount number;
        buffer raw(16);
        result raw(16) := '000102030405060708090A0B0C0C0E0F';
    begin
       f1 := bfilename('BFILETESTDIR', 'test001.bin');
    
       dbms_lob.fileopen(f1, dbms_lob.file_readonly);
    
       amount := 16;
       dbms_lob.read(f1, amount, 1, buffer);
    
       dbms_output.put_line(amount);
       dbms_output.put_line(buffer); 
        
       dbms_lob.fileclose(f1); 
    end;
    / 
    
    16
    000102030405060708090A0B0C0D0E0F

파일 내용을 읽어서 LOB 데이터에 쓰기를 한다. 파일은 열어져 있어야 하며, LOB도 생성된 상태여야 한다. 본 프러시저에서는 문자집합 변환이 이뤄지지 않는다(CLOB의 데이터 내부 형태는 UCS2 인코딩이므로, CLOB으로 읽어들일 파일 인코딩또한 UCS2이어야 한다. 그렇지 않는 경우 동작은 정의되지 않는다).

LOADFROMFILE 프러시저의 세부 내용은 다음과 같다.

  • 프로토타입

    • BLOB 타입인 경우

      DBMS_LOB.LOADFROMFILE
      (
          dest_lob    IN OUT NOCOPY BLOB,
          src_file    IN            BFILE,
          amount      IN            INTEGER,
          dest_offset IN            INTEGER := 1,
          src_offset  IN            INTEGER := 1
      );
    • CLOB 타입인 경우

      DBMS_LOB.LOADFROMFILE
      (
          dest_lob    IN OUT NOCOPY CLOB,
          src_file    IN            BFILE,
          amount      IN            INTEGER,
          dest_offset IN            INTEGER := 1,
          src_offset  IN            INTEGER := 1
      );
  • 파라미터

    파라미터설명
    dest_lob대상 LOB locator이다.
    src_file

    LOB으로 읽어들일 bfile 타입의 파일 핸들이다.

    BLOB 및 CLOB 버전의 경우 문자집합의 변환이 없다(CLOB 버전을 사용하는 경우 입력 텍스트 파일은 UCS2 인코딩만을 지원한다).

    amount

    파일로부터 읽어들일 크기이다.

    BLOB 버전의 경우에는 바이트를 의미하고, CLOB 버전인 경우는 문자를 의미한다(문자는 UCS2 인코딩을 가정하므로, 1문자는 2Bytes이다).

    dest_offset쓸 LOB의 offset이다. (기본값: 1, 1 베이스)
    src_offset읽을 파일의 offset이다. (기본값: 1, 1 베이스)
  • 예외 상황

    예외 상황설명
    VALUE_ERROR입력 파라미터가 적절하지 않는 경우 발생한다.
  • 예제

    SQL> create directory BFILETESTDIR as '/home/tests/test_bfile/';
    
    Directory 'BFILETESTDIR' created.
    
    SQL> DECLARE 
        f UTL_FILE.FILE_TYPE; 
    
        buffer RAW(16) := '000102030405060708090A0B0C0C0E0F';
    begin 
        f := UTL_FILE.FOPEN('BFILETESTDIR', 'test001.bin', 'wb');
        UTL_FILE.PUT_RAW(f, buffer);
        UTL_FILE.FCLOSE(f);
    end;
    /
    
    PSM completed.
    
    SQL> SET SERVEROUTPUT ON 
    
    SQL> DECLARE 
        f1 BFILE;
        bl1 BLOB := HEXTORAW('AAAAAA');
        amount NUMBER;
        buffer RAW(16);
        result RAW(16) := '000102030405060708090A0B0C0C0E0F';
        buffer2 RAW(32);
        result2 RAW(32) := '000102030405060708090A0B0C0D0E0F';
    begin
       f1 := BFILENAME('BFILETESTDIR', 'test001.bin');
    
       DBMS_LOB.FILEOPEN(f1, DBMS_LOB.FILE_READONLY);
    
       amount := 16;
       DBMS_LOB.LOADFROMFILE(bl1, f1, amount);
       DBMS_LOB.READ(bl1, amount, 1, buffer);
    
       DBMS_OUTPUT.PUT_LINE(amount);
       DBMS_LOB.FILECLOSE(f1);
    end;
    /
    16
    
    PSM completed.
    
    SQL> DECLARE 
        lob CLOB;
    BEGIN
        DBMS_LOB.CREATETEMPORARY(lob, false);
        DBMS_LOB.FREETEMPORARY(lob);
    END;
    /
    
    PSM completed.
    
    SQL> DECLARE
        f UTL_FILE.FILE_TYPE; 
    
        buffer RAW(16) := '00610062006300640065006600670068';
    BEGIN 
        f := UTL_FILE.FOPEN('BFILETESTDIR', 'ucs2_file.bin', 'wb');
        UTL_FILE.PUT_RAW(f, buffer);
        UTL_FILE.FCLOSE(f);
    END;
    /
    
    PSM completed.
    
    SQL> SET SERVEROUTPUT ON 
    SQL> DECLARE
        f1 BFILE;
        bl1 CLOB := 'init'; 
        amount NUMBER;
    BEGIN
       F1 := BFILENAME('BFILETESTDIR', 'ucs2_file.bin');
    
       DBMS_LOB.FILEOPEN(f1, DBMS_LOB.FILE_READONLY);
    
       AMOUNT := 8;
       DBMS_LOB.LOADFROMFILE(bl1, f1, amount);
    
       DBMS_OUTPUT.PUT_LINE (bl1);
    
       DBMS_LOB.FILECLOSE(f1);
    END;
    /
    abcdefgh
    
    PSM completed.
    
    SQL> 

파일 내용을 읽어서, BLOB 데이터에 쓰기를 한다. 파일은 열어져 있어야 하며, LOB도 생성된 상태여야 한다.

LOADBLOBFROMFILE 프러시저의 세부 내용은 다음과 같다.

  • 프로토타입

    DBMS_LOB.LOADBLOBFROMFILE
    (
        dest_lob    IN OUT NOCOPY BLOB,
        src_file    IN            BFILE,
        amount      IN            INTEGER,
        dest_offset IN OUT        INTEGER,
        src_offset  IN OUT        INTEGER
    );
  • 파라미터

    파라미터설명
    dest_lob대상 LOB locator이다.
    src_fileLOB으로 읽어들일 bfile 타입의 파일 핸들이다. 문자집합의 변환이 없다.
    amount파일로부터 읽어들일 크기(바이트)이다.
    dest_offset쓸 LOB의 offset이다(1 베이스). 프러시저가 완료된 후 offset은 쓰여진 만큼 수정된다.
    src_offset읽을 파일의 offset이다(1 베이스). 프러시저가 완료된 후 offset은 읽혀진 만큼 수정된다.
  • 예외 상황

    예외 상황설명
    VALUE_ERROR입력 파라미터가 적절하지 않는 경우 발생한다.
  • 예제

    SQL> SET SERVEROUTPUT ON  
    
    SQL> create directory BFILETESTDIR as '/home/tests/test_bfile/';
    
    Directory 'BFILETESTDIR' created.
    
    SQL> DECLARE 
        f UTL_FILE.FILE_TYPE; 
    
        buffer RAW(16) := '000102030405060708090A0B0C0C0E0F';
    begin 
        f := UTL_FILE.FOPEN('BFILETESTDIR', 'test001.bin', 'wb');
        UTL_FILE.PUT_RAW(f, buffer);
        UTL_FILE.FCLOSE(f);
    end;
    /
    
    PSM completed.
    
    SQL> DECLARE 
        f1 BFILE;
        bl1 BLOB := HEXTORAW('AAAAAA');
        amount NUMBER;
        buffer RAW(16);
        result RAW(16) := '000102030405060708090A0B0C0C0E0F';
        buffer2 RAW(32);
        result2 RAW(32) := '000102030405060708090A0B0C0D0E0F';
        src_ofst NUMBER;
        dst_ofst NUMBER;
    begin
       f1 := BFILENAME('BFILETESTDIR', 'test001.bin');
    
       DBMS_LOB.FILEOPEN(f1, dbms_lob.file_readonly);
    
       amount := 16;
        src_ofst := 1;
        dst_ofst := 1;
    
       DBMS_LOB.LOADBLOBFROMFILE(bl1, f1, amount, dst_ofst,  src_ofst);
       DBMS_LOB.READ(bl1, amount, 1, buffer);
    
       DBMS_OUTPUT.PUT_LINE(amount);
       DBMS_OUTPUT.PUT_LINE(src_ofst);
       DBMS_OUTPUT.PUT_LINE(dst_ofst);
    
        
       DBMS_LOB.FILECLOSE(f1);
    end;
    /
    16
    17
    17
    
    PSM completed.
    
    SQL> 

File Locator로 읽기 전용, 바이너리 모드로 파일을 연다.

OPEN 프러시저의 세부 내용은 다음과 같다.

  • 프로토타입

    DBMS_LOB.OPEN
    (   
        file_loc     IN OUT NOCOPY   BFILE,
        open_mode    IN              BINARY_INTEGER := file_readonly
    );
  • 파라미터

    파라미터설명
    file_loc열 파일의 locator이다.
    open_mode파일 읽기 모드(file_readonly) 파라미터만 허용한다.
  • 예외 상황

    예외 상황설명
    VALUE_ERRORFile locator가 NULL인 경우이다.
    INVALID_ARGVALopen_mode에 file_readonly 값외 다른 값이 온 우이다.
    INVALID_DIRECTORYFile locator에 지정된 디렉터리가 유효하지 않나 존재하지 않는 경우이다.
    NOEXIST_DIRECTORYFile locator에 지정된 디렉터리 경로가 존재하 않는 경우이다.
    OPERATION_FAILED디렉터리 경로에 파일이 존재하지 않거나, 파일 열수 없는 경우이다.
  • 예제

    create directory BFILETESTDIR as '/mybasepath/bfiletest/';
    
    declare 
        f utl_file.file_type; 
    
        buffer raw(16) := '000102030405060708090A0B0C0D0E0F';
    begin 
        f := utl_file.fopen('BFILETESTDIR', 'test001.bin', 'wb');
        utl_file.put_raw(f, buffer);
        utl_file.fclose(f);
    end;
    /
    
    declare
        f1 bfile;
        amount number;
        buffer raw(16);
        result raw(16) := '000102030405060708090A0B0C0C0E0F';
    begin
       f1 := bfilename('BFILETESTDIR', 'test001.bin');
    
       dbms_lob.open(f1, dbms_lob.file_readonly);
    
       amount := 16;
       dbms_lob.read(f1, amount, 1, buffer);
    
       dbms_output.put_line(amount);
       dbms_output.put_line(buffer); 
        
       dbms_lob.close(f1);
    end;
    / 
    
    16
    000102030405060708090A0B0C0D0E0F

대상 LOB 데이터의 일부 또는 전체를 읽어 출력 파라미터의 버퍼에 저장하는 프러시저이다. 만약 읽기를 시작하는 오프셋과 읽을 크기의 합이 대상 LOB 데이터의 크기보다 커서 LOB 데이터의 끝을 지나가게 되면, 실제 읽은 데이터의 크기는 파라미터로 주어진 읽을 크기보다 작을 수 있다. 이때 실제로 읽어온 데이터의 크기는 입출력 파라미터 amount에 저장되어 반환된다. 만약 읽을 오프셋의 위치가 대상 LOB 데이터의 크기보다 크다면 NO_DATA_FOUND 예외 상황이 발생한다.

CLOB 데이터로부터 읽은 데이터를 클라이언트에 전송하는 경우 클라이언트의 문자 집합으로 자동 변환된다. 이 경우 실제로 읽어온 데이터와 달라질 수 있다.

READ 프러시저의 세부 내용은 다음과 같다.

  • 프로토타입

    • BLOB 타입인 경우

      DBMS_LOB.READ
      (
          lob_loc     IN              BLOB,
          amount      IN OUT NOCOPY   BINARY_INTEGER,
          offset      IN              INTEGER,
          buffer      OUT             RAW
      );
    • CLOB 타입인 경우

      DBMS_LOB.READ
      (
          lob_loc     IN              CLOB,
          amount      IN OUT NOCOPY   BINARY_INTEGER,
          offset      IN              INTEGER,
          buffer      OUT             VARCHAR2
      );
    • CLOB 타입인 경우

      DBMS_LOB.READ
      (
          file_loc    IN              CLOB,
          amount      IN OUT NOCOPY   BINARY_INTEGER,
          offset      IN              INTEGER,
          buffer      OUT             VARCHAR2
      );
  • 파라미터

    파라미터설명
    lob_loc읽을 대상 LOB locator이다.
    file_loc읽을 대상 File locator이다.
    amount

    읽을 크기를 입력하고 실제로 읽어온 크기를 출력한다.

    (단위: Byte(BLOB 데이터, FILE 데이터) 또는 문자(CLOB 데이터) 개수)

    offset

    읽을 대상 LOB 데이터 내의 오프셋이다.

    (단위: Byte(BLOB 데이터, FILE 데이터) 또는 문자(CLOB 데이터))

    buffer읽을 데이터를 저장하는 출력 버퍼이다.
  • 예외 상황

    예외 상황설명
    VALUE_ERROR입력 파라미터 중 하나라도 NULL인 경우이다.
    INVALID_POSoffset의 값이 1보다 작거나 LOBMAXSIZE보다 큰 경우이다.
    INVALID_LEN
    • amount의 값이 1보다 작거나 MAXBUFSIZE보다 큰 경우이다.

    • amount의 값이 버퍼의 크기보다 큰 경우이다.

    NO_DATA_FOUNDoffset이 대상 LOB 데이터의 크기보다 큰 경우이다.
    UNOPENED_FILE열리지 않은 File Locator로 연산을 수행하려 한 경우이다.
  • 예제

    DECLARE
        lob CLOB := 'TIBERO fighting!!!';
        buffer VARCHAR2(256);
        amount BINARY_INTEGER := 8;
    BEGIN
        DBMS_LOB.READ(lob, amount, 8, buffer);
        DBMS_OUTPUT.PUT_LINE('Value to be read = ' || buffer);
    END;
    /
    Value to be read = fighting
    
    PSM completed
    SQL> 

대상 LOB 데이터의 지정된 오프셋 위치에 주어진 데이터를 지정된 크기만큼 저장하는 프러시저이다. 새로운 데이터가 저장되는 위치에 존재하는 이전 데이터는 소멸된다. BLOB 데이터에 대한 오프셋 및 크기는 Byte 단위이며, CLOB 데이터에 대해서는 문자 단위이다.

주어진 데이터의 실제 크기보다 지정된 크기가 큰 경우에는 에러가 발생하며, 지정된 크기가 작은 경우에는 지정된 크기만큼만 저장된다. 지정된 오프셋이 대상 LOB 데이터의 크기보다 큰 경우에는 중간에 0(BLOB 데이터) 또는 공백(CLOB 데이터)으로 채워진다.

이 프러시저를 CLOB 데이터에 대하여 실행할 때 CLOB 데이터의 문자 집합과 저장할 데이터의 문자 집합은 같아야 한다. 이 프러시저를 클라이언트 쪽에서 호출하는 경우 저장할 데이터가 클라이언트 쪽의 문자 집합으로부터 CLOB 데이터 문자 집합으로 변환된 후에 저장된다.

WRITE 프러시저의 세부 내용은 다음과 같다.

  • 프로토타입

    • BLOB 타입인 경우

      DBMS_LOB.WRITE
      (
          lob             IN OUT NOCOPY   BLOB,
          amount          IN              BINARY_INTEGER,
          offset          IN              INTEGER,
          buffer          IN              RAW
      );
    • CLOB 타입인 경우

      DBMS_LOB.WRITE
      (
          lob             IN OUT NOCOPY   CLOB,
          amount          IN              BINARY_INTEGER,
          offset          IN              INTEGER,
          buffer          IN              VARCHAR
      );
  • 파라미터

    파라미터설명
    lob대상 LOB locator이다.
    amount

    저장할 데이터의 크기이다.

    (단위: Byte(BLOB 데이터) 또는 문자(CLOB 데이터))

    offset

    데이터를 저장할 오프셋이다.

    (단위: Byte(BLOB 데이터) 또는 문자(CLOB 데이터))

    buffer저장할 데이터이다.
  • 예외 상황

    예외 상황설명
    VALUE_ERROR파라미터 중 하나라도 NULL인 경우이다.
    INVALID_POSoffset의 값이 1보다 작거나 LOBMAXSIZE보다 큰 경우이다.
    INVALID_LENamount의 값이 1보다 작거나 MAXBUFSIZE보다 큰 경우이다.
  • 예제

    DECLARE
        lob CLOB;
        buffer VARCHAR2(100);
    BEGIN
        DBMS_LOB.CREATETEMPORARY(lob, false);
        buffer := 'Love is friendship set on fire';
        DBMS_LOB.WRITE(lob, length(buffer), 1, buffer);
        DBMS_OUTPUT.PUT_LINE(lob);
    END;
    /
    Love is friendship set on fire
    
    PSM completed
    SQL> 

대상 LOB 데이터의 끝에 주어진 데이터를 지정된 크기만큼 저장하는 프러시저이다. 이 프러시저는 WRITE 프러시저의 파라미터 오프셋을 대상 LOB 데이터의 길이로 설정한 것과 같다. BLOB 데이터의 크기는 Byte 단위이며, CLOB 데이터는 문자 단위이다.

주어진 데이터의 실제 크기보다 지정된 크기가 큰 경우에는 에러가 발생하며, 지정된 크기가 작은 경우에는 지정된 크기만큼만 저장된다.

이 프러시저를 CLOB 데이터에 대하여 실행할 때에 CLOB 데이터의 문자 집합과 저장할 데이터의 문자 집합은 같아야 한다. 이 프러시저를 클라이언트 쪽에서 호출하는 경우 저장할 데이터가 클라이언트 쪽의 문자 집합에서 CLOB 데이터 문자 집합으로 변환된 후에 저장된다.

WRITEAPPEND 프러시저의 세부 내용은 다음과 같다.

  • 프로토타입

    • BLOB 타입인 경우

      DBMS_LOB.WRITEAPPEND 
      (
          lob         IN OUT NOCOPY   BLOB,
          amount      IN              BINARY_INTEGER,
          buffer      IN              RAW
      );
    • CLOB 타입인 경우

      DBMS_LOB.WRITEAPPEND 
      (
          lob         IN OUT NOCOPY   CLOB,
          amount      IN              BINARY_INTEGER,
          buffer      IN              VARCHAR2
      );
  • 파라미터

    파라미터설명
    lob대상 LOB locator이다.
    amount

    저장할 데이터의 크기이다.

    (단위: Byte(BLOB 데이터) 또는 문자(CLOB 데이터) 개수)

    buffer

    저장할 데이터이다.

    (단위: Byte(BLOB 데이터) 또는 문자(CLOB 데이터))

  • 예외 상황

    예외 상황설명
    VALUE_ERROR파라미터 중 하나라도 NULL인 경우이다.
    INVALID_LENamount 값이 1보다 작거나 MAXBUFSIZE보다 큰 경우이다.
  • 예제

    DECLARE
        lob CLOB := 'Parting is such ';
        buffer VARCHAR2(100) := 'sweet sorrow';
    BEGIN
        DBMS_LOB.WRITEAPPEND(lob, length(buffer), buffer);
        DBMS_OUTPUT.PUT_LINE('Result = ' || lob);
    END;
    /
    Result = Parting is such sweet sorrow
    
    PSM completed
    SQL> 

본 절에서는 DBMS_LOB 패키지에서 제공하는 함수를 알파벳 순으로 설명한다.

두 개의 LOB 데이터의 전체 또는 일부를 비교하는 함수이다. 같은 타입의 LOB 데이터 간에만 비교가 가능하다.

COMPARE 함수의 세부 내용은 다음과 같다.

  • 프로토타입

    • BLOB 타입인 경우

      DBMS_LOB.COMPARE
      (
          lob_1           IN          BLOB, 
          lob_2           IN          BLOB,
          amount          IN          INTEGER := 4294967295,
          offset_1        IN          INTEGER := 1,
          offset_2        IN          INTEGER := 1
      ) 
      RETURN INTEGER;
    • CLOB 타입인 경우

      DBMS_LOB.COMPARE
      (
          lob_1           IN          CLOB,
          lob_2           IN          CLOB,
          amount          IN          INTEGER := 4294967295,
          offset_1        IN          INTEGER := 1,
          offset_2        IN          INTEGER := 1
      ) 
      RETURN INTEGER;

      CLOB 데이터를 전달하는 경우 lob_1, lob_2 파라미터의 LOB 데이터의 문자 집합이 같아야 한다.

  • 파라미터

    파라미터설명
    lob_1비교 대상인 첫 번째 LOB locator이다.
    lob_2비교 대상인 두 번째 LOB locator이다.
    amount비교할 Byte의 크기(BLOB 데이터) 또는 문자(CLOB 데이터) 개수이다.
    offset_1

    비교를 시작할 첫 번째 LOB 데이터 오프셋이다.

    (단위: Byte(BLOB 데이터) 또는 문자(CLOB 데이터))

    offset_2

    비교를 시작할 두 번째 LOB 데이터 오프셋이다.

    (단위: Byte(BLOB 데이터) 또는 문자(CLOB 데이터))

  • 반환값

    반환값설명
    0lob_1, lob_2의 LOB 데이터가 동일한 경우에 반환한다.
    N < 0 or N > 0lob_1, lob_2의 LOB 데이터가 동일하지 않은 경우에 반환한다.

    NULL

    • amount가 1보다 작은 경우에 반환한다.

    • amount가 LOBMAXSIZE보다 큰 경우에 반환한다.

    • offset_1 또는 offset_2가 1보다 작은 경우에 반환한다.

    • offset_1 또는 offset_2가 LOBMAXSIZE보다 큰 경우에 반환한다.

  • 예제

    DECLARE
        lob_1 CLOB := 'abcdefgh';
        lob_2 CLOB := 'abcdefgg';
    BEGIN
        IF DBMS_LOB.COMPARE(lob_1, lob_2) = 0 then
            DBMS_OUTPUT.PUT_LINE('LOB_1 equals LOB_2');
        ELSE 
            DBMS_OUTPUT.PUT_LINE('LOB_1 does not equals LOB_2');
        END IF;
    END;
    /
    LOB_1 does not equals LOB_2
    
    PSM completed
    SQL> 

대상 LOB 데이터 내에서 주어진 패턴이 n 번째로 나타나는 오프셋을 반환하는 함수이다. 패턴을 탐색하는 위치는 대상 LOB 데이터의 처음일 수도 있고 입력 파라미터로 지정된 위치일 수도 있다. 이때 탐색할 대상 패턴은 LIKE 연산자에서 사용되는 퍼센트(%) 또는 언더바(_)와 같은 와일드 카드 문자 등을 포함할 수 없다.

INSTR 함수의 세부 내용은 다음과 같다.

  • 프로토타입

    • BLOB 타입인 경우

      DBMS_LOB.INSTR
      (
          lob         IN      BLOB,
          pattern     IN      RAW,
          offset      IN      INTEGER := 1,
          nth         IN      INTEGER := 1
      ) 
      RETURN INTEGER;
    • CLOB 타입인 경우

      DBMS_LOB.INSTR
      (
          lob         IN      CLOB,
          pattern     IN      VARCHAR,
          offset      IN      INTEGER := 1,
          nth         IN      INTEGER := 1
      ) 
      RETURN INTEGER;
  • 파라미터

    파라미터설명
    lob패턴을 탐색할 대상 LOB locator이다.
    pattern탐색할 패턴이다.
    offset

    LOB 데이터 내의 탐색을 시작할 오프셋이다.

    (단위: Byte(BLOB 데이터) 또는 문자(CLOB 데이터))

    nth

    탐색할 패턴의 개수이다.

    1 이상의 값을 가지며, 1이면 첫 번째 패턴의 오프셋을 반환한다.

  • 반환값

    반환값설명
    INTEGER패턴과 일치하는 부분을 찾은 경우 해당 패턴이 시작되는 오프셋을 반환한다. 만약 찾지 못한 경우에는 0을 반환한다.
    NULL
    • IN 파라미터 중 하나라도 NULL인 경우에 반환한다.

    • offset이 1보다 작거나 LOBMAXSIZE보다 큰 경우에 반환한다.

    • nth가 1보다 작거나 LOBMAXSIZE보다 큰 경우에 반환한다.

  • 예제

    DECLARE
        lob CLOB := 'Corporate floor';
        result NUMBER;
    BEGIN
        result := DBMS_LOB.INSTR(lob, 'or', 3, 2);
        DBMS_OUTPUT.PUT_LINE('Result offset = ' || result);
    END;
    /
    Result offset = 14
    
    PSM completed
    SQL> 

대상 LOB 데이터의 지정된 오프셋의 위치로부터 지정된 크기만큼의 데이터를 반환하는 함수이다. 반환될 최대 크기는 32767bytes이며, CLOB 데이터의 경우 반환될 최대 문자 개수는 32767을 2로 나눈 값이다. CLOB 데이터에 대하여 이 함수를 호출하면 같은 문자 집합의 문자열이 반환된다.

이 함수는 하나의 파라미터라도 NULL이 넘겨지거나, 파라미터 amount 또는 offset의 값이 1보다 작거나 LOBMAXSIZE보다 큰 경우에 NULL을 반환한다.

이 함수를 CLOB 데이터에 대해 클라이언트 쪽에서 호출한 경우 만약 클라이언트 쪽에 설정된 문자 집합가 CLOB 데이터 문자 집합과 다르다면 데이터 전송 중에 자동적으로 문자 집합의 변환이 일어난다.

SUBSTR 함수의 세부 내용은 다음과 같다.

  • 프로토타입

    • BLOB 타입인 경우

      DBMS_LOB.SUBSTR
      (
          lob         IN          BLOB,
          amount      IN          INTEGER := 32767,
          offset      IN          INTEGER := 1
      ) 
      RETURN RAW;
    • CLOB 타입인 경우

      DBMS_LOB.SUBSTR
      (
          lob         IN          CLOB,
          amount      IN          INTEGER := 32767,
          offset      IN          INTEGER := 1
      ) 
      RETURN VARCHAR2;
  • 파라미터

    파라미터설명
    lob대상 LOB 데이터이다.
    amount

    읽을 데이터의 크기이다.

    (단위: Byte(BLOB 데이터) 또는 문자(CLOB 데이터) 개수)

    offset

    데이터를 읽을 LOB 데이터 내의 오프셋이다.

    (단위: Byte(BLOB 데이터) 또는 문자(CLOB 데이터))

  • 반환값

    반환값설명
    RAW/VARCHAR2 데이터SUBSTR 함수가 성공적으로 종료된 경우에 반환한다.
    NULL
    • 입력 파라미터가 하나라도 NULL인 경우에 반환한다.

    • amount가 1보다 작거나 32767bytes보다 큰 경우에 반환한다.

    • offset이 1보다 작거나 LOBMAXSIZE보다 큰 경우에 반환한다.

  • 예제

    DECLARE
        lob CLOB := 'Your friend is too young';
        buffer VARCHAR2(100);
    BEGIN
        buffer := DBMS_LOB.SUBSTR(lob, 6, 6);
        DBMS_OUTPUT.PUT_LINE('My favorite word is ' || UPPER(buffer));
    END;
    /
    My favorite word is FRIEND
    
    PSM completed
    SQL>