■ Data Skill ■/PL-SQL

PL/SQL (16) - 오브젝트 타입 (BFILE)

한길(One Way) 2023. 3. 18.

1. BFILE

- 오라클 데이터베이스에 저장되는 것이 아니라 외부 운영체제에 저장된 오브젝트에 액세스한다.

- 디렉토리 오브젝트와 파일이름이 필요하고 관련 권한이 필요하다.

- Commit, Rollback 에 대한 트랜잭션을 지원하지 않는다.

- 파일은 읽기전용이다.

- too many files open 에러 발생시 init 파일에서 SESSION_MAX_OPEN_FILES 파라미터를 수정한다.

- 파일을 열었으면 반드시 닫는다.

 

 

2. 디렉토리 오브젝트

- 디렉토리 오브젝트 이름과 경로를 매핑시킨다.

- OS상 실제 경로를 지정하는 것이 아니라, 이 디렉토리 오브젝트를 호출하여 액세스한다.

 

 

3. DBMS_LOB 패키지

- DBMS_LOB 패키지를 통해 LOB을 조작할 수 있다.

 

※ BFILE 에 사용되는 함수와 프로시저

함수/프로시저
종류 / 사용가능 데이터 형
설 명
BFILENAME
Function / BFILE
PL/SQL블록이나 테이블에 파일의 위치에 대한
포인터(Locator) 생성한다.
FILEOPEN
Procedure / BFILE
Locator와 연결된 파일을 연다.
FILECLOSE
P / BFILE
Locator와 연결된 파일을 닫는다.
FILECOLSEALL
P / BFILE
BFILE을 모두 닫는다.
FILEEXISTS
F / BFILE
Locator가 가리키는 위치에 파일이 존재하는지 검사한다.
FILEISOPEN
F / BFILE
파일이 이미 열려있는지 검사한다.
FILEGETNAME
P / BFILE
디렉토리 오브젝트와 경로를 반환한다.
COMPARE
F / 모든 LOB
두개 LOB을 비교한다.
GETLENGTH
F / 모든 LOB
LOB의 길이를 반환한다.
INSTR
F / 모든 LOB
LOB에 지정된 문자스크링과 일치하는 패턴을 찾는다.
READ
P / 모든 LOB
지정한 size만큼 LOB을 버퍼로 읽어들인다.
SUBSTR
F / 모든 LOB
파라미터에 의해 지정된 전체 또는 일부 LOB을 반환한다.

 

(1) BFILENAME

- BFILENAME 함수를 통해 테이블에 BFILE에 대한 Locator를 삽입한다.

- 파일이 삭제되거나 이동될 경우 Locator는 예전 위치를 가리키고 있기 때문에 에러가 난다.

- 사용형식 : BFILENAME(디렉토리오브젝트, 파일이름)

(2) FILEOPEN

- BFILE을 사용하려면 우선 파일을 열어야한다.

- 사용형식 : FILEOPEN(Locator, DBMS_LOB.FILE_READONLY)

(3) FILECLOSE

- BFILE을 다 읽은 뒤 항상 파일을 닫는다.

- 사용형식 : FILECLOSE(Locator)

(4) FILECLOSEALL

- 모든 BFILE을 처리한 뒤 세션을 끝낼 경우, 모든 BFILE을 닫을 수 있다.

- 사용형식 : FILECLOSEALL

 

(5) FILEEXISTS

- 파일에 지정한 곳에 제대로 붙어 있는지 확인할 경우 사용한다.

- 있으면 1, 없으면 0 을 리턴한다.

- 사용형식 : FILEEXISTS(Locator)

(6) FILEISOPEN

- BFILE 사용 전에 파일이 이미 열려있는지 확인한다.

- 열려있으면 1, 닫혀있으면 다른 정수값을 리턴한다.

- 사용형식 : FILEOPEN(Locator)

(7) FILEGETNAME

- Locator와 연결된 디렉토리 오브젝트와 파일 이름을 반환한다.

- 사용형식 : FILEGETNAME(Locator, 디렉토리오브젝트, 파일이름)

(8) COMPARE

- 전체 또는 일부 LOB을 비교할 경우 사용

- 중복파일 제거를 위해 두 개 외부파일을 비교할 때 사용할 수 있다.

- 데이터가 똑같으면 0, 다르면 0이 아닌 값을 반환한다.

- 사용형식 : COMPARE(LOB1, LOB2, 비교할 byte수, LOB1 비교시작위치, LOB2 비교시작위치)

(9) GETLENGTH

- 오브젝트의 실제 길이를 byte 단위로 알 수 있다.

- 사용형식 : GETLENGTH(Locator)

(10) INSTR

- 지정한 위치부터 찾고자 하는 패턴과 일치하는 n번째 패턴을 검색한다.

- 패턴이 없으면 0, 패턴이 있으면 해당 오프셋을 반환한다.

- 사용형식 : INSTR(Locator, 패턴, 시작위치, n번째)

(11) READ

- 파일의 일부 또는 전체를 메모리로 읽어들인다.

- 사용형식 : READ(Locator, 읽을양, 시작위치, 버퍼위치)

(12) SUBSTR

- 파일에서 지정된 바이트수만큼 추출하는데 사용한다.

- 사용형식 : SUBSTR(Locator, 읽을양, 시작위치)

 

==========================================================================================

[ TEST ]

 

1. 아래와 같이 3개의 jpg 파일이 OS에 존재한다.

 

 

 

2. jpg 파일이 존재하는 경로를 가지는 디렉토리 오브젝트를 생성한다.

CREATE OR REPLACE DIRECTORY poster_dir AS
'/export/home/oracle/plsql';

 

3. 다른 사용자가 사용하게 하려면 디렉토리 오브젝트를 읽을 권한을 준다.

GRANT READ ON DIRECTORY poster_dir TO user;

 

- 현재 디렉토리 생성자가 kangyw 이므로 본인에게 권한을 주면 에러 발생.

4. 프로시저 작성

bfile_test.sql

DECLARE
        v_Imagefile     BFILE;
        v_Dirname       VARCHAR2(30);
        v_Location      VARCHAR2(1000);
        v_Fileisopen    INTEGER;
        v_Fileexists    INTEGER;
BEGIN
        v_Imagefile := BFILENAME('POSTER_DIR', 'bourne_1.jpg');
        v_Fileisopen := DBMS_LOB.FILEISOPEN(v_Imagefile);
        v_Fileexists := DBMS_LOB.FILEEXISTS(v_Imagefile);
 
        IF v_Fileexists = 1 THEN
                DBMS_OUTPUT.PUT_LINE('File Exists!!');
        ELSE
                DBMS_OUTPUT.PUT_LINE('File could not found!!');
        END IF;
 
        IF v_Fileisopen = 1 THEN
                DBMS_OUTPUT.PUT_LINE('File is already Open!!');
        ELSE
                DBMS_OUTPUT.PUT_LINE('File is not open!!');
                DBMS_LOB.FILEOPEN(v_Imagefile);
        END IF;
 
        DBMS_LOB.FILEGETNAME(v_Imagefile, v_Dirname, v_Location);
        DBMS_OUTPUT.PUT_LINE('The Directory Object is: ' || v_Dirname);
        DBMS_OUTPUT.PUT_LINE('The File Name is: ' || v_Location);
 
        DBMS_LOB.FILECLOSE(v_Imagefile);
END;
/
 

- 결과

728x90

댓글