Fonte: Tutorial de Informática de TI
Qualquer pessoa que já tenha usado Oracle sabe que o Oracle possui um tipo de dados chamado VARCHAR2, que é usado para representar strings de comprimento variável. VARCHAR2 também é o tipo recomendado pela Oracle. Mas há um problema ao usar VARCHAR2: ele só pode representar no máximo 4.000 caracteres, o que equivale a 2.000 caracteres chineses. Se o valor de um determinado caractere em seu programa for superior a 20.002 caracteres chineses, VARCHAR2 não poderá atender aos requisitos. Neste momento, você tem duas opções, uma é usar vários VARCHAR2 para representá-lo e a outra é usar campos LOB. Aqui damos uma olhada no segundo método.
Primeiro, vamos dar uma olhada geral nos campos LOB do Oracle. Os tipos LOB da Oracle são divididos em três tipos: BLOB, CLOB e BFILE. CLOB é chamado de caractere LOB, BLOB e BFILE são usados para armazenar dados binários. O comprimento máximo de CLOB e BLOB é de 4 GB e eles armazenam valores no banco de dados Oracle. BFILE é semelhante ao BLOB, mas coloca os dados em um arquivo externo, por isso também é chamado de BLOB externo (External BLOB).
Acho que todos estamos familiarizados com o MYSQL. Existem tipos de dados semelhantes no MYSQL, como TEXT e BLOB. Na função MYSQL do PHP, as operações em TEXT/BLOB são diretas, assim como outros tipos de dados. Mas na Oracle a situação é diferente. A Oracle trata os LOBs como um tipo de dados especial e não pode usar métodos convencionais nas operações. Por exemplo, você não pode inserir valores diretamente em campos LOB na instrução INSERT, nem pode usar LIKE para pesquisar.
Aqui estão alguns exemplos para ilustrar como usar a função OCI do PHP para inserir, recuperar e consultar dados LOB.
A inserção
não pode usar diretamente a instrução INSERT para inserir valores em campos LOB. Geralmente, existem as seguintes etapas:
1. Primeiro analise uma instrução INSERT e retorne um descritor LOB
2. Use a função OCI para gerar um objeto LOB local
3. Vincule o objeto LOB ao descritor LOB
4. Execute a instrução INSERT
5. Atribuir um valor para o objeto LOB
6. Libere o objeto LOB e o identificador da instrução SQL
O exemplo a seguir armazena o arquivo de imagem carregado pelo usuário em um BLOB (ou BFILE, a operação é um pouco diferente). Primeiro, crie uma tabela com a seguinte estrutura:
CREATE TABLE PICTURES (
NÚMERO DE IDENTIFICAÇÃO,
DESCRIÇÃO VARCHAR2(100),
MIME VARCHAR2(128),
BLOB DE IMAGEM
);
Caso queira realizar o aumento automático do ID, crie outra SEQUENCE:
CREATE SEQUENCE PIC_SEQ
e em seguida o código do programa PHP utilizado para processar os dados.
<?php
//Estabelece uma conexão com o banco de dados Oracle
$conn = OCILogon($user, $password, $SID);
//Envia instruções SQL ao Oracle;
//Dois pontos a serem observados aqui: Primeiro, use a função EMPTY_BLOB(). Esta é uma função interna do Oracle que retorna um localizador LOB. Ao inserir um LOB, você só pode usar este método para primeiro gerar um localizador LOB vazio e, em seguida, operar nesse localizador. A função EMPTY_BLOB() é para o tipo BLOB, e a correspondente para CLOB é EMPTY_CLOB(). A segunda é a parte após RETURNING, que retorna a imagem para que a função OCI do PHP possa tratá-la.
$stmt = OCIParse($conn,"INSERT INTO PICTURES (id, descrição, imagem)
VALUES (pic_seq.NEXTVAL, '$description', '$lob_upload_type', EMPTY_BLOB()) RETURNING picture INTO :PICTURE");
//Gera um descritor de um objeto LOB local. Observe o segundo parâmetro da função: OCI_D_LOB, que significa Gerar um objeto LOB. Outras possibilidades são OCI_D_FILE e OCI_D_ROWID, que correspondem aos objetos BFILE e ROWID respectivamente.
$
lob = OCINewDescriptor($conn, OCI_D_LOB);
ligado.OCIBindByName
($stmt, ':PICTURE', &$lob, -1, OCI_B_BLOB);
OCIExecute($stmt);
//Salva os dados no objeto LOB. Como os dados de origem aqui são um arquivo, use o método savefile() do objeto LOB diretamente. Outros métodos de objetos LOB incluem save() e load(), que são usados para salvar e recuperar dados respectivamente. Mas o tipo BFILE possui apenas um método, que é save()
if($lob->savefile($lob_upload)){
OCICommit($conn);
echo "Upload bem-sucedido<br>";
}outro{
echo "Falha no upload<br>";
}
//Libera o objeto LOB
OCIFreeDesc($lob);
OCIFreeStatement($stmt);
OCILogoff($conn);
?>
Há outra coisa a ser observada: o valor do campo LOB deve ter pelo menos 1 caractere, portanto antes de save() ou savefile(), certifique-se de que o valor não pode estar vazio. Caso contrário, o Oracle cometerá um erro.
Existem duas maneiras derecuperar
dados de um LOB. Uma é gerar um objeto LOB, vinculá-lo ao localizador retornado por uma instrução SELECT e, em seguida, usar o método load() do objeto LOB para recuperar os dados; a outra é usar diretamente a função OCIFetch*** do PHP. O primeiro método é muito mais problemático do que o segundo método, então falarei diretamente sobre o segundo método.
Ainda use a tabela acima.
<?php
$conn = OCILogon($usuário, $senha, $SID);
$stmt = OCIParse($conn,"SELECIONE * FROM IMAGENS ONDE ID=$pictureid");
OCIExecute($stmt);
//O segredo está no terceiro parâmetro do PCIFetchInfo: OCI_RETURN_LOBS. O terceiro parâmetro é o modo FETCH. Se OCI_RETURN_LOBS, o valor LOB é colocado diretamente na matriz de resultados em vez do localizador LOB, portanto, o método load() do objeto LOB não é necessário.
if (OCIFetchInto($stmt, $resultado, OCI_ASSOC+OCI_RETURN_LOBS))
{
echo "Tipo de conteúdo: " . StripSlashes($resultado[MIME]);
echo StripSlashes($resultado[PICTURE]);
}
OCIFreeStatement($stmt);
OCILogoff($conn);
?>
Este programa é usado para exibir dados (imagens) colocados em LOB. Método de chamada (assumindo que o nome do script seja getpicture.php):
<IMG SRC="getpicture.php?pictureid=99" ALT="Imagem colocada no Oracle LOB">
A consulta
foi mencionada anteriormente e o campo LOB do Oracle é LIKE não pode ser usado para correspondência. O que fazer? Na verdade, não é complicado. A Oracle possui um pacote anônimo chamado DBMS_LOB, que contém todos os processos necessários para operar o LOB.
Suponha que você tenha uma tabela como esta:
CREATE TABLE ARTICLES (
NÚMERO DE IDENTIFICAÇÃO,
TÍTULO VARCHAR2(100),
CLOBO DE CONTEÚDO
);
O conteúdo do artigo é colocado no campo CONTEÚDO.
Agora queremos encontrar todos os artigos que contenham "usuários chineses do PHP" no conteúdo. Podemos fazer assim:
<?php.
$conn = OCILogon($user, $password, $SID);
//O procedimento DBMS_LOB.INSTR é usado na cláusula WHERE. Possui quatro parâmetros. Os dois primeiros representam o localizador LOB (pode ser representado diretamente por um campo) e a string a ser pesquisada; os dois últimos representam o deslocamento inicial e o número de ocorrências. Ressalta-se que seu valor de retorno deve ser julgado, ou seja, deve ser maior que 0.
$stmt = OCIParse($conn,"SELECT * FROM ARTICLES WHERE DBMS_LOB.INSTR(CONTENT, 'PHP Chinese User', 1, 1) > 0");
OCIExecute($stmt);
if (OCIFetchInto($stmt, $resultado, OCI_ASSOC+OCI_RETURN_LOBS))
{
...
}
OCIFreeStatement($stmt);
OCILogoff($conn);
?>
O Oracle também fornece muitos procedimentos para operar dados LOB, como LENGTH, SUBSTR, etc. Quanto ao seu uso detalhado, você pode considerar o manual de desenvolvimento da Oracle.
Isso é tudo sobre as operações em dados do tipo LOB no banco de dados Oracle. Como não tenho contato com a Oracle há muito tempo, pode haver erros neste artigo. Todos podem me criticar e corrigir.