Прикрепляет переменную variable к метке
bv_name. Такое прикрепеление позволяет повысить
производительность и избежать SQL-инъекций.
Прикрепление переменной позволяет базе данных повторно использовать
кэшированные контекстные выражения от предыдущих запросов,
даже если они первоначально были запущены другим пользователем
или процессом. Это также снижает риск SQL-инъекций, поскольку
данные в таком случае никогда не рассматриваются как инструкции SQL.
Данные не требуется экранировать или заключать в кавычки.
Прикрепленные PHP-переменные могут быть изменены и снова выполнены
без необходимости повторной обработки запроса или повторного
прикрепления.
В Oracle, прикрепление переменных обычно разделяют на
IN (прикрепляет значения, передаваемые в
базу данных) и OUT (прикрепляет значения,
возвращаемые PHP). Переменная может быть одновременно
IN и OUT. Независимо от
этого, характер прикрепленния переменных будет определен во
время выполнения.
Необходимо указать maxlength при использовании
OUT-привязки, что позволяет PHP зарезервировать
больше памяти для хранения возвращаемого значения
Для IN-привязки рекомендуется также указать
параметр maxlength, если выражение
выполняется несколько раз с раздичными значениями PHP-переменной.
В противном случае, Oracle может урезать размер данных до размера
первоначального значения переменной PHP. Если максимальная длина
значения неизвестна, рекомендуется вызывать
oci_bind_by_name() перед каждым вызовом
oci_execute().
Прикрепление неоправданно большой переменной повлияет на
процесс сохранения базы данных.
Вид прикрепления указывает Oracle как работать с памятью при
чтении данных. Для IN-прикрепления адрес в памяти должен
содержать допустимые данные при вызове
oci_execute(). Это значит, что значение переменной
должно находиться в памяти во время исполнения. Если это не так,
возможны некорректные результаты или ошибки наподобие
"ORA-01460: unimplemented or unreasonable conversion requested"
(запрошены невыполнимые или некорректные преобразования)
Для OUT-прикрепления основным признаком
является установка значения в переменную PHP.
Для многократно выполняемого выражения, привязка одних и тех
же значений может уменьшить возможности оптимизатора Oracle
по выработке наилучшего варианта выполнения инструкции. Длительное
прикрепление выражений, которые редко исполняются, может также
не принести пользы. Тем не менее, в обоих случаях, прикрепление
является более безопасным, чем конкатенация строки запроса и
непроверенных пользовательских данных.
Список параметров
statement
Допустимый идентификатор выражения OCI8.
bv_name
Метка с префиксом в виде двоеточия, используемая в выражении.
Двоеточие опционально в bv_name.
Oracle не использует знак вопроса для меток.
variable
Переменная PHP, ассоциированная с bv_name
maxlength
Устанавливает максимальный размер данных. Если указать -1,
функция будет использовать текущий размер переменной
variable в качестве максимального.
При этом переменная variable должна
существовать и содержать данные во время вызова
oci_bind_by_name().
type
Тип данных, к которому Oracle будет приводить значения.
По умолчанию type имеет значение
SQLT_CHR. Oracle приводит данные от
данного типа к типу поля (или типу переменной PL/SQL), если
это возможно.
Если необходимо прикрепить переменную абстрактного типа
(LOB/ROWID/BFILE), следует предварительно использовать
oci_new_descriptor(). Параметр
length не используется для абстрактных типов
и должен быть установлен в -1.
Допустимые значения параметра type:
SQLT_BFILEE или OCI_B_BFILE
- для BFILE-объектов;
SQLT_CFILEE или OCI_B_CFILEE
- для CFILE-объектов;
SQLT_CLOB или OCI_B_CLOB
- для CLOB-объектов;
SQLT_BLOB или OCI_B_BLOB
- для BLOB-объектов;
SQLT_RDD или OCI_B_ROWID
- для ROWID-объектов;
SQLT_NTY или OCI_B_NTY
- для именованных типов даты;
// oci_bind_by_name($stid, $key, $val) не работает, // потому что прикрепляет каждое значение в одно место: $val // Вместо этого следует указывать конкретное место: $ba[$key] oci_bind_by_name($stid, $key, $ba[$key]); }
// Поиск всех городов, начинающихся на 'South' $stid = oci_parse($conn, "SELECT city FROM locations WHERE city LIKE :bv"); $city = 'South%'; // '%' - это знак шаблона SQL oci_bind_by_name($stid, ":bv", $city); oci_execute($stid); oci_fetch_all($stid, $res);
foreach ($res['CITY'] as $c) { print $c . "<br>\n"; } // Выводом будет: // South Brunswick // South San Francisco // Southlake
Для небольшого, фиксированного количества условий в выражении IN,
используются индивидуальные имена переменных. Неизвестные значения
при исполнении могут быть установлены в NULL.
Это позволяет использовать одно выражение нескольким пользователям,
что повышает эффективность кэширования Oracle DB.
Пример #7 Прикрепление нескольких значений в выржаение IN
$stid = oci_parse($conn, 'SELECT ROWID, name FROM mytab WHERE id = :id_bv FOR UPDATE'); $id = 1; oci_bind_by_name($stid, ':id_bv', $id); oci_execute($stid); $row = oci_fetch_array($stid, OCI_ASSOC+OCI_RETURN_NULLS); $rid = $row['ROWID']; $name = $row['NAME'];
// Переведем имя в верхний регистр и зафиксируем изменения $name = strtoupper($name); $stid = oci_parse($conn, 'UPDATE mytab SET name = :n_bv WHERE ROWID = :r_bv'); oci_bind_by_name($stid, ':n_bv', $name); oci_bind_by_name($stid, ':r_bv', $rid, -1, OCI_B_ROWID); oci_execute($stid);
// Теперь таблица содержит: 1, 100, CHRIS
oci_free_statement($stid); oci_close($conn);
?>
Пример #9 OUT-прикрепление ROWID, возвращаемое при INSERT
<?php
// В данном примере добавляется запись с идентификатором и именем, // после чего увеличивается заработная плата // Создание таблицы: // CREATE TABLE mytab (id NUMBER, salary NUMBER, name VARCHAR2(40)); // // На основе собственных ROWID на примере thies[at]thieso.net (980221)
// Показать новые записи $stid = oci_parse($conn, "SELECT * FROM mytab"); oci_execute($stid); while ($row = oci_fetch_array($stid, OCI_ASSOC+OCI_RETURN_NULLS)) { var_dump($row); }
oci_free_statement($stid); oci_close($conn);
?>
Пример #10 Прикрепление для хранимой функции PL/SQL
<?php
// Перед запуском PHP-сценария, создайте хранимую функцию в // SQL*Plus или SQL Developer: // // CREATE OR REPLACE FUNCTION myfunc(p IN NUMBER) RETURN NUMBER AS // BEGIN // RETURN p * 3; // END;
// Возвращаемое значение OUT-прикреплено. По умолчаннию типом данных будет строка. // Прикрепление со значением 40 означает, что будет возвращено 40 символов. oci_bind_by_name($stid, ':r', $r, 40);
oci_execute($stid);
print "$r\n"; // выведет 24
oci_free_statement($stid); oci_close($conn);
?>
Пример #11 Прикрепление параметров для PL/SQL хранимой процедуры
<?php
// Перед запуском PHP-сценария, создайте хранимую процедуру в // SQL*Plus или SQL Developer: // // CREATE OR REPLACE PROCEDURE myproc(p1 IN NUMBER, p2 OUT NUMBER) AS // BEGIN // p2 := p1 * 2; // END;
// Второй параметр процедуры OUT-прикреплен. По умолчаннию типом данных будет строка. // Прикрепление со значением 40 означает, что будет возвращено 40 символов. oci_bind_by_name($stid, ':p2', $p2, 40);
Возвращает TRUE в случае успешного завершения или FALSE в случае возникновения ошибки.
Примечания
Внимание
Не используйте magic_quotes_gpc или
addslashes()
одновременно с oci_bind_by_name(), так как кавычек быть
не должно. Все указанные кавычки будут записаны в базу данных,
потому что oci_bind_by_name()
вставляет данные дословно и не удаляет кавычки или символы экранирования.
Замечание:
Если прикрепляется строка к CHAR-полю в
выражении WHERE, помните, что Oracle использует
при сравнении значения CHAR, дополненные пробелами.
Переменная PHP должна быть дополнена пробелами до того же размера,
что и поле, чтобы выражение WHERE выполнялось верно.
Замечание:
Переменная PHP variable является ссылкой. Некоторые
виды циклов могут работать не так, как ожидается:
В этом случае каждый ключ прикрепляется к $value,
поэтому все прикрепленные переменные указывают на значение
в последней итерации цикла. Вместо этого следует использовать:
В версиях PHP ниже 5.0.0 следует использовать
функцию ocibindbyname().
Старое имя функции также может быть использовано в текущих версиях, хотя оно уже устарело
и не рекомендуется.