출처: IT 컴퓨터 튜토리얼
Oracle을 사용해 본 사람이라면 누구나 Oracle에 가변 길이 문자열을 나타내는 데 사용되는 VARCHAR2라는 데이터 유형이 있다는 것을 알고 있습니다. VARCHAR2는 Oracle에서 권장하는 유형이기도 합니다. 그러나 VARCHAR2를 사용하면 문제가 있습니다. 최대 4000자만 표현할 수 있으며 이는 한자 2000자와 동일합니다. 프로그램의 특정 문자 값이 한자 20,002자보다 큰 경우 VARCHAR2는 요구 사항을 충족할 수 없습니다. 이때 두 가지 옵션이 있습니다. 하나는 여러 개의 VARCHAR2를 사용하여 표현하는 것이고, 다른 하나는 LOB 필드를 사용하는 것입니다. 여기서는 두 번째 방법을 살펴보겠습니다.
먼저 오라클의 LOB 필드를 전반적으로 살펴보겠습니다. Oracle의 LOB 유형은 BLOB, CLOB 및 BFILE의 세 가지 유형으로 구분됩니다. CLOB는 문자 LOB라고 하며, BLOB, BFILE은 바이너리 데이터를 저장하는 데 사용됩니다. CLOB, BLOB의 최대 길이는 4GB이며 Oracle 데이터베이스에 값을 저장합니다. BFILE은 BLOB과 유사하지만 데이터를 외부 파일에 저장하므로 외부 BLOB(External BLOB)이라고도 합니다.
우리 모두는 MYSQL에 익숙하다고 생각합니다. MYSQL에는 TEXT 및 BLOB와 같은 유사한 데이터 유형이 있습니다. PHP의 MYSQL 함수에서 TEXT/BLOB에 대한 작업은 다른 유형의 데이터와 마찬가지로 직접적입니다. 하지만 오라클에서는 상황이 다르다. Oracle은 LOB를 특별한 데이터 유형으로 취급하며 작업 시 기존 방법을 사용할 수 없습니다. 예를 들어 INSERT 문에서 LOB 필드에 직접 값을 삽입할 수 없으며 LIKE를 사용하여 검색할 수도 없습니다.
다음은 PHP의 OCI 함수를 사용하여 LOB 데이터를 삽입, 검색 및 쿼리하는 방법을 보여주는 몇 가지 예입니다.
삽입은
INSERT 문을 직접 사용하여 LOB 필드에 값을 삽입할 수 없습니다. 일반적으로 다음 단계로 진행됩니다.
1. 먼저 INSERT 문을 분석하고 LOB 설명자를 반환합니다
. 2. OCI 함수를 사용하여 로컬 LOB 개체를 생성합니다
. 3. LOB 개체를 LOB 설명자에 바인딩합니다
. 4. INSERT 문을 실행합니다
. 5. 할당 LOB 객체에 대한 값
6. LOB 객체와 SQL 문 핸들을 해제합니다.
다음 예에서는 사용자가 업로드한 이미지 파일을 BLOB(또는 BFILE, 작업이 약간 다름)에 저장합니다. 먼저, 다음 구조로 테이블을 생성합니다:
CREATE TABLE PICTURES (
ID 번호,
설명 VARCHAR2(100),
MIME VARCHAR2(128),
그림 BLOB
);
ID의 자동 증가를 구현하려면 또 다른 SEQUENCE를 생성하세요:
CREATE SEQUENCE PIC_SEQ,
그런 다음 데이터를 처리하는 데 사용되는 PHP 프로그램 코드.
<?php
//Oracle 데이터베이스 연결 설정
$conn = OCILogon($user, $password, $SID)
//SQL 문을 Oracle에 제출합니다.
//여기서 주목해야 할 두 가지 사항: 먼저 EMPTY_BLOB() 함수를 사용합니다. 이는 LOB 위치자를 반환하는 Oracle의 내부 함수입니다. LOB를 삽입할 때 이 방법을 사용하여 먼저 빈 LOB 위치 지정자를 생성한 다음 이 위치 지정자에서 작업할 수 있습니다. EMPTY_BLOB() 함수는 BLOB 유형에 대한 함수이고 CLOB에 해당하는 함수는 EMPTY_CLOB()입니다. 두 번째는 RETURNING 다음 부분으로, PHP의 OCI 함수가 처리할 수 있도록 그림을 반환하는 부분입니다.
$stmt = OCIParse($conn,"사진에 삽입(ID, 설명, 사진)
VALUES (pic_seq.NEXTVAL, '$description', '$lob_upload_type', EMPTY_BLOB()) RETURNING picture INTO :PICTURE");
//로컬 LOB 개체의 설명자를 생성합니다. 함수의 두 번째 매개변수인 OCI_D_LOB에 유의하세요. LOB 객체 생성을 의미합니다. 다른 가능성은 각각 BFILE 및 ROWID 객체에 해당하는 OCI_D_FILE 및 OCI_D_LOB입니다.
//
생성된 LOB 객체를 이전 SQL 문에서 반환된 위치에 바인딩합니다. on.OCIBindByName
($stmt, ':PICTURE', &$lob, -1, OCI_B_BLOB);
OCIExecute($stmt);
//LOB 객체에 데이터를 저장합니다. 여기서 소스 데이터는 파일이므로 LOB 객체의 savefile() 메소드를 직접 사용합니다. LOB 객체의 다른 메소드로는 각각 데이터를 저장하고 검색하는 데 사용되는 save() 및 load()가 있습니다. 그러나 BFILE 유형에는 save()
if($lob->savefile($lob_upload)){
라는 하나의 메소드만 있습니다.
OCICommit($conn);
echo "업로드 성공<br>";
}또 다른{
echo "업로드 실패<br>";
}
//LOB 객체를 해제합니다
. OCIFreeDesc($lob);
OCIFreeStatement($stmt);
OCILogoff($conn);
?>
또 한 가지 주의할 점은 LOB 필드의 값은 1자 이상이어야 하므로 save() 또는 savefile() 전에 값이 비어 있으면 안 된다는 것입니다. 그렇지 않으면 Oracle에서 오류가 발생합니다.
LOB에서 데이터를
검색하는
방법에는 두 가지가 있습니다.하나는 LOB 객체를 생성한 후 SELECT 문에서 반환된 위치 지정자에 바인딩한 다음 LOB 객체의 load() 메서드를 사용하여 데이터를 검색하는 것이고, 다른 하나는 PHP의 OCIFetch*** 함수를 직접 사용하는 것입니다. 첫 번째 방법이 두 번째 방법보다 훨씬 번거로워서 두 번째 방법에 대해 직접 이야기해보겠습니다.
여전히 위의 표를 사용하세요.
<?php
$conn = OCILogon($user, $password, $SID);
$stmt = OCIParse($conn,"SELECT * FROM 사진에서 ID=$pictureid");
OCIExecute($stmt);
//비밀은 PCIFetchInfo의 세 번째 매개변수인 OCI_RETURN_LOBS에 있습니다. 세 번째 매개변수는 FETCH 모드입니다. OCI_RETURN_LOBS인 경우 LOB 위치자 대신 LOB 값을 결과 배열에 직접 넣기 때문에 LOB 객체의 load() 메소드가 필요하지 않습니다.
if (OCIFetchInto($stmt, $result, OCI_ASSOC+OCI_RETURN_LOBS))
{
echo "콘텐츠 유형: " . StripSlashes($result[MIME]);
echo StripSlashes($result[PICTURE]);
}
OCIFreeStatement($stmt);
OCILogoff($conn);
?>
이 프로그램은 LOB에 있는 데이터(그림)를 표시하는 데 사용됩니다. 호출 방법(스크립트 이름이 getpicture.php라고 가정):
<IMG SRC="getpicture.php?pictureid=99" ALT="Picture located in Oracle LOB">
쿼리는
앞서 언급한 바 있으며, Oracle의 LOB 필드는 다음과 같습니다. LIKE는 일치에 사용할 수 없습니다. 무엇을 해야 할까요? 실제로 오라클에는 LOB 운영에 필요한 모든 프로세스가 포함된 DBMS_LOB라는 익명 패키지가 있습니다.
다음과 같은 테이블이 있다고 가정해 보겠습니다.
CREATE TABLE ARTICLES (
ID 번호,
제목 VARCHAR2(100),
콘텐츠 CLOB
);
기사의 내용은 CONTENT 필드에 배치됩니다.
이제 콘텐츠에 "PHP 중국 사용자"가 포함된 모든 기사를 찾으려면 다음과 같이 할 수 있습니다.
<?php
$conn = OCILogon($user, $password, $SID);
//WHERE 절에서는 DBMS_LOB.INSTR 프로시저가 사용됩니다. 여기에는 4개의 매개변수가 있습니다. 처음 두 개는 LOB 위치 지정자(필드로 직접 표시될 수 있음)를 나타내고, 후자 두 개는 시작 오프셋과 발생 횟수를 나타냅니다. 반환값은 반드시 0보다 커야 한다는 판단이 필요하다는 점에 유의해야 한다.
$stmt = OCIParse($conn,"SELECT * DBMS_LOB.INSTR(CONTENT, 'PHP 중국 사용자', 1, 1) > 0");
OCIExecute($stmt);
if (OCIFetchInto($stmt, $result, OCI_ASSOC+OCI_RETURN_LOBS))
{
...
}
OCIFreeStatement($stmt);
OCILogoff($conn);
?>
오라클은 LENGTH, SUBSTR 등 LOB 데이터를 운용하기 위한 다양한 프로시저도 제공합니다. 자세한 사용법은 Oracle의 개발 매뉴얼을 참조하세요.
이것이 Oracle 데이터베이스의 LOB 유형 데이터에 대한 작업에 관한 것입니다. 오랫동안 오라클과 접촉하지 않았기 때문에 이 글에는 오류가 있을 수 있습니다. 여러분의 비판과 정정을 환영합니다.