Источник: Учебное пособие по компьютерным технологиям
Любой, кто использовал Oracle, знает, что в Oracle есть тип данных VARCHAR2, который используется для представления строк переменной длины. VARCHAR2 также является типом, рекомендованным Oracle. Но есть проблема с использованием VARCHAR2: он может представлять не более 4000 символов, что эквивалентно 2000 китайским символам. Если значение определенного символа в вашей программе превышает 20 002 китайских символа, VARCHAR2 не может соответствовать требованиям. На данный момент у вас есть два варианта: один — использовать несколько VARCHAR2 для его представления, а другой — использовать LOB-поля. Здесь мы рассмотрим второй метод.
Во-первых, давайте в общих чертах взглянем на LOB-поля Oracle. Типы LOB Oracle делятся на три типа: BLOB, CLOB и BFILE. CLOB называется символьным LOB, BLOB и BFILE используются для хранения двоичных данных. Максимальная длина CLOB и BLOB составляет 4 ГБ, и они хранят значения в базе данных Oracle. BFILE похож на BLOB, но помещает данные во внешний файл, поэтому его еще называют внешним BLOB (External BLOB).
Я думаю, что мы все знакомы с MYSQL. В MYSQL существуют похожие типы данных, такие как TEXT и BLOB. В функции PHP MYSQL операции с текстом/BLOB являются прямыми, как и с другими типами данных. Но в Oracle ситуация иная. Oracle рассматривает LOB как особый тип данных и не может использовать традиционные методы в операциях. Например, вы не можете напрямую вставлять значения в поля LOB в инструкции INSERT, а также не можете использовать 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 (
ИДЕНТИФИКАЦИОННЫЙ НОМЕР,
ОПИСАНИЕ VARCHAR2(100),
МИМ ВАРЧАР2(128),
ИЗОБРАЖЕНИЕ
);
Если вы хотите реализовать автоматическое увеличение ID, создайте еще одну SEQUENCE:
CREATE SEQUENCE PIC_SEQ,
а затем программный код PHP, используемый для обработки данных.
<?php
//Установим соединение с базой данных Oracle
$conn = OCILogon($user, $password, $SID
//Отправим операторы SQL в Oracle
);
//Здесь следует отметить два момента: во-первых, используйте функцию EMPTY_BLOB(). Это внутренняя функция Oracle, которая возвращает локатор LOB. При вставке большого объекта вы можете использовать этот метод только для того, чтобы сначала создать пустой локатор большого объекта, а затем работать с этим локатором. Функция EMPTY_BLOB() предназначена для типа BLOB, а для CLOB — EMPTY_CLOB(). Вторая часть — это часть после RETURNING, которая возвращает изображение, чтобы функция PHP OCI могла его обработать.
$stmt = OCIParse($conn,"INSERT INTO PICTURES (id, описание, изображение)
VALUES (pic_seq.NEXTVAL, '$description', '$lob_upload_type', EMPTY_BLOB()) RETURNING image INTO :PICTURE");
//Создаем дескриптор локального LOB-объекта. Обратите внимание на второй параметр функции: OCI_D_LOB, который означает «Создать объект LOB». Другими возможностями являются OCI_D_FILE и OCI_D_ROWID, которые соответствуют объектам BFILE и ROWID соответственно.
$lob = OCINewDescriptor($conn, OCI_D_LOB);
//Привязываем сгенерированный объект LOB к локатору, возвращенному предыдущим оператором SQL. on
OCIBindByName($stmt, ':PICTURE', &$lob, -1, OCI_B_BLOB);
OCIExecute($stmt);
//Сохраняем данные в LOB-объект. Поскольку исходными данными здесь является файл, используйте метод savefile() объекта LOB напрямую. Другие методы 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 символа, поэтому перед сохранением() или savefile() убедитесь, что значение не может быть пустым. В противном случае Oracle допустит ошибку.
Существует два способаполучения
данных из LOB. Один из них — создать LOB-объект, затем связать его с локатором, возвращаемым оператором SELECT, а затем использовать метод load() объекта LOB для получения данных; другой — напрямую использовать функцию PHP OCIFetch***. Первый способ гораздо хлопотнее второго, поэтому я расскажу непосредственно о втором способе.
По-прежнему используйте таблицу выше.
<?php
$conn = OCILogon($user, $password, $SID);
$stmt = OCIParse($conn,"SELECT * FROM PICTURES WHERE ID=$pictureid");
OCIExecute($stmt);
// Секрет кроется в третьем параметре PCIFetchInfo: OCI_RETURN_LOBS. Третий параметр — это режим FETCH. Если OCI_RETURN_LOBS, значение LOB напрямую помещается в массив результатов вместо локатора LOB, поэтому метод load() объекта LOB не требуется.
если (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="Изображение, помещенное в LOB Oracle">
Запрос
упоминался ранее, а поле LOB Oracle LIKE не может использоваться для сопоставления. Что делать? На самом деле это несложно. У Oracle есть анонимный пакет под названием DBMS_LOB, который содержит все процессы, необходимые для работы LOB.
Предположим, у вас есть такая таблица:
CREATE TABLE ARTICLES (
ИДЕНТИФИКАЦИОННЫЙ НОМЕР,
НАЗВАНИЕ ВАРЧАР2(100),
ОБЪЕМ СОДЕРЖИМОГО
);
Содержание статьи помещается в поле СОДЕРЖАНИЕ.
Теперь мы хотим найти все статьи, содержащие «Китайские пользователи PHP». Мы можем сделать это следующим образом:
<?php.
$conn = OCILogon($user, $password, $SID);
//Процедура DBMS_LOB.INSTR используется в предложении WHERE. Он имеет четыре параметра. Первые два представляют собой локатор LOB (может быть непосредственно представлен полем), а последние два представляют собой начальное смещение и количество вхождений. Следует отметить, что его возвращаемое значение должно быть оценено, то есть оно должно быть больше 0.
$stmt = OCIParse($conn,"SELECT * FROM ARTICLES WHERE DBMS_LOB.INSTR(CONTENT, 'Китайский пользователь PHP', 1, 1) > 0");
OCIExecute($stmt);
если (OCIFetchInto($stmt, $result, OCI_ASSOC+OCI_RETURN_LOBS))
{
...
}
OCIFreeStatement($stmt);
OCILogoff($conn);
?>
Oracle также предоставляет множество процедур для работы с LOB-данными, например LENGTH, SUBSTR и т. д. Что касается их подробного использования, вы можете ознакомиться с руководством по разработке Oracle.
Вот и все, что касается операций с данными типа LOB в базе данных Oracle. Поскольку я давно не общался с Oracle, в статье могут быть ошибки. Все желающие могут меня покритиковать и поправить.