aci_bind_by_name¶
aci_bind_by_name — 绑定一个 PHP 变量到一个 数据库 位置标志符
说明¶
aci_bind_by_name(
resource $statement,
string $bv_name,
mixed &$variable,
int $maxlength = -1,
int $type = SQLT_CHR
): bool
将 PHP 变量 variable 绑定到位置标志符 bv_name 。绑定操作对数据库性能很重要,同时也是避免 SQL 注入安全问题的一种方式。
aci_bind_by_name() 将 PHP 变量 variable 绑定到的位置标志符 ph_name。 该变量是否会被用作输入输出是在运行时决定的,并且函数给该变量分配必要的存储空间。length参数确定该绑定的最大长度,如果将 length设为 -1,aci_bind_by_name() 会用 variable 变量的当前长度确定绑定的最大长度。
如果要绑定一个抽象数据类型(LOB/ROWID/BFILE),需要先用 aci_new_descriptor()。函数分配空间。 length没有用于抽象数据类型,应被设为 -1。type 参数告诉 数据库要使用什么样的描述符。
可能的值为:
SQLT_FILE - 对应于 BFILE;
SQLT_CFILE - 对应于 CFILE;
SQLT_CLOB - 对应于 CLOB;
SQLT_BLOB - 对应于 BLOB;
SQLT_ROWID - 对应于 ROWID;
SQLT_NTY - 对应于有名字的数据类型;
SQLT_INT - 对应于 integers;
SQLT_CHR - 对应于 VARCHARs;
SQLT_BIN - 对应于 RAW 列;
SQLT_LNG - 对应于 LONG 列;
SQLT_LBI - 对应于 LONG RAW 列;
SQLT_RSET - 对应于游标,是之前由 aci_new_cursor() 创建的。
范例¶
示例 #1 aci_bind_by_name() 例子
<?php
/* aci_bind_by_name example thies at thieso dot net (980221)
inserts 3 records into emp, and uses the ROWID for updating the
records just after the insert.
*/
$conn = aci_connect('sysdba', 'szoscar55', 'localhost:2003/OSRDB') ;
$stmt = aci_parse($conn, "
INSERT INTO
emp (empno, ename)
VALUES
(:empno,:ename)
RETURNING
ROWID
INTO
:rid
");
$data = array(
1111 => "Larry",
2222 => "Bill",
3333 => "Jim"
);
$rowid = aci_new_descriptor($conn, OCI_D_ROWID);
aci_bind_by_name($stmt, ":empno", $empno, 32);
aci_bind_by_name($stmt, ":ename", $ename, 32);
aci_bind_by_name($stmt, ":rid", $rowid, -1, OCI_B_ROWID);
$update = aci_parse($conn, "
UPDATE
emp
SET
sal = :sal
WHERE
ROWID = :rid
");
aci_bind_by_name($update, ":rid", $rowid, -1, OCI_B_ROWID);
aci_bind_by_name($update, ":sal", $sal, 32);
$sal = 10000;
foreach ($data as $empno => $ename) {
aci_execute($stmt);
aci_execute($update);
}
$rowid->free();
aci_free_statement($update);
aci_free_statement($stmt);
$stmt = aci_parse($conn, "
SELECT
*
FROM
emp
WHERE
empno
IN
(1111,2222,3333)
");
aci_execute($stmt);
while ($row = aci_fetch_assoc($stmt)) {
var_dump($row);
}
oci_free_statement($stmt);
/* delete our "junk" from the emp table.... */
$stmt = aci_parse($conn, "
DELETE FROM
emp
WHERE
empno
IN
(1111,2222,3333)
");
aci_execute($stmt);
aci_free_statement($stmt);
aci_close($conn);
?>
记住,本函数删除了行尾的空白字符。见以下例子:
示例 #2 aci_bind_by_name() 例子
<?php
$connection =aci_connect('sysdba', 'szoscar55', 'localhost:2003/OSRDB') ;
$query = "INSERT INTO test_table VALUES(:id, :text)";
$statement = aci_parse($query);
aci_bind_by_name($statement, ":id", 1);
aci_bind_by_name($statement, ":text", "trailing spaces follow ");
aci_execute($statement);
/*
This code will insert into DB string 'trailing spaces follow', without
trailing spaces
*/
?>
示例 #3 aci_bind_by_name() 例子
<?php
$connection = aci_connect('sysdba', 'szoscar55', 'localhost:2003/OSRDB') ;
$query = "INSERT INTO test_table VALUES(:id, 'trailing spaces follow ')";
$statement = aci_parse($query);
aci_bind_by_name($statement, ":id", 1);
aci_execute($statement);
/*
And this code will add 'trailing spaces follow ', preserving
trailing whitespaces
*/
?>
警告
警告: 不要将 magic_quotes_gpc 或 addslashes() 与 aci_bind_by_name() 同时使用,因为不需要转义,任何自动加上的引号都会被写入数据库中,因为 aci_bind_by_name() 不能分辨有意加上的引号和魔术引号。
成功时返回 true, 或者在失败时返回 false。
注意:
在 PHP 5.0.0 之前的版本必须使用 acibindbyname() 替代本函数。
该函数名仍然可用,为向下兼容作为 aci_bind_by_name() 的别名。不过其已被废弃,不推荐使用。
参数¶
有效的ACI8语句标识符。
语句中使用的带冒号前缀的绑定变量占位符。冒号在 bv_name 中是可选的。不使用问号作为占位符。
要与 bv_name 关联的PHP变量
设置数据的最大长度。如果将其设置为-1,此函数将使用变量的当前长度来设置最大长度。 在这种情况下,当调用**aci_bind_by_name()**时,变量必须存在并包含数据。
数据库将数据视为的数据类型。使用的默认 type 是**SQLT_CHR**。如果可能,数据库将在该类型和数据库列(或PL/SQL变量类型)之间转换数据。
如果需要绑定抽象数据类型(LOB/ROWID/BFILE),则需要首先使用aci_new_descriptor()函数分配它。length不用于抽象数据类型,应设置为-1。
类型的可能值为:
SQLT_FILE - 对应于 BFILE;
SQLT_CFILE - 对应于 CFILE;
SQLT_CLOB - 对应于 CLOB;
SQLT_BLOB - 对应于 BLOB;
SQLT_ROWID - 对应于 ROWID;
SQLT_NTY - 对应于有名字的数据类型;
SQLT_INT - 对应于 integers;
SQLT_CHR - 对应于 VARCHARs;
SQLT_BIN - 对应于 RAW 列;
SQLT_LNG - 对应于 LONG 列;
SQLT_LBI - 对应于 LONG RAW 列;
SQLT_RSET - 对应于游标,是之前由 aci_new_cursor() 创建的。
返回值¶
成功时返回 true, 或者在失败时返回 false。
范例¶
示例 #4 使用aci_bind_by_name()插入数据
<?php
// Create the table with:
// CREATE TABLE mytab (id NUMBER, text VARCHAR2(40));
$conn = aci_connect('sysdba', 'szoscar55', 'localhost:2003/OSRDB') ;
if (!$conn) {
$m = aci_error();
trigger_error(htmlentities($m['message']), E_USER_ERROR);
}
$stid = aci_parse($conn,"INSERT INTO mytab (id, text) VALUES(:id_bv, :text_bv)");
$id = 1;
$text = "Data to insert ";
aci_bind_by_name($stid, ":id_bv", $id);
aci_bind_by_name($stid, ":text_bv", $text);
aci_execute($stid);
// Table now contains: 1, 'Data to insert '
?>
示例 #5多次执行绑定一次
<?php
// Create the table with:
// CREATE TABLE mytab (id NUMBER);
$conn = aci_connect('hr', 'welcome', 'localhost/XE');
if (!$conn) {
$m = aci_error();
trigger_error(htmlentities($m['message']), E_USER_ERROR);
}
$a = array(1,3,5,7,11); // data to insert
$stid = aci_parse($conn, 'INSERT INTO mytab (id) VALUES (:bv)');
aci_bind_by_name($stid, ':bv', $v, 20);
foreach ($a as $v) {
$r = aci_execute($stid, OCI_DEFAULT); // don't auto commit
}
aci_commit($conn); // commit everything at once
// Table contains five rows: 1, 3, 5, 7, 11
aci_free_statement($stid);
aci_close($conn);
?>
示例 #6 使用foreach()循环绑定
<?php
$conn = aci_connect('sysdba', 'szoscar55', 'localhost:2003/OSRDB') ;
if (!$conn) {
$m = aci_error();
trigger_error(htmlentities($m['message']), E_USER_ERROR);
}
$sql = 'SELECT * FROM departments WHERE department_name = :dname AND location_id = :loc';
$stid = aci_parse($conn, $sql);
$ba = array(':dname' => 'IT Support', ':loc' => 1700);
foreach ($ba as $key => $val) {
aci_bind_by_name($stid, $key, $ba[$key]);
}
aci_execute($stid);
$row = aci_fetch_array($stid, OCI_ASSOC+OCI_RETURN_NULLS);
foreach ($row as $item) {
print $item."<br>\n";
}
aci_free_statement($stid);
aci_close($conn);
?>
示例 #7 WHERE子句中的绑定
<?php
$conn = aci_connect('sysdba', 'szoscar55', 'localhost:2003/OSRDB') ;
if (!$conn) {
$m = aci_error();
trigger_error(htmlentities($m['message']), E_USER_ERROR);
}
$sql = 'SELECT last_name FROM employees WHERE department_id = :didbv ORDER BY last_name';
$stid = aci_parse($conn, $sql);
$didbv = 60;
aci_bind_by_name($stid, ':didbv', $didbv);
aci_execute($stid);
while (($row = aci_fetch_array($stid, OCI_ASSOC)) != false) {
echo $row['LAST_NAME'] ."<br>\n";
}
// Output is
// Austin
// Ernst
// Hunold
// Lorentz
// Pataballa
aci_free_statement($stid);
aci_close($conn);
?>
示例 #8 与LIKE子句绑定
<?php
$conn = aci_connect('sysdba', 'szoscar55', 'localhost:2003/OSRDB') ;
if (!$conn) {
$m = aci_error();
trigger_error(htmlentities($m['message']), E_USER_ERROR);
}
// Find all cities that begin with 'South'
$stid = aci_parse($conn, "SELECT city FROM locations WHERE city LIKE :bv");
$city = 'South%'; // '%' is a wildcard in SQL
aci_bind_by_name($stid, ":bv", $city);
aci_execute($stid);
aci_fetch_all($stid, $res);
foreach ($res['CITY'] as $c) {
print $c . "<br>\n";
}
// Output is
// South Brunswick
// South San Francisco
// Southlake
aci_free_statement($stid);
aci_close($conn);
?>
示例 #9 与REGEXP_LIKE绑定
<?php
$conn = aci_connect('sysdba', 'szoscar55', 'localhost:2003/OSRDB') ;
if (!$conn) {
$m = aci_error();
trigger_error(htmlentities($m['message']), E_USER_ERROR);
}
// Find all cities that contain 'ing'
$stid = aci_parse($conn, "SELECT city FROM locations WHERE REGEXP_LIKE(city, :bv)");
$city = '.*ing.*';
aci_bind_by_name($stid, ":bv", $city);
aci_execute($stid);
aci_fetch_all($stid, $res);
foreach ($res['CITY'] as $c) {
print $c . "<br>\n";
}
// Output is
// Beijing
// Singapore
aci_free_statement($stid);
aci_close($conn);
?>
对于少量固定数量的IN子句条件,请使用单独的绑定变量。 运行时未知的值可以设置为NULL。这允许所有应用程序用户使用一条语句,从而最大限度地提高数据库缓存效率。
示例 #10 在in子句中绑定多个值
<?php
$conn = aci_connect('sysdba', 'szoscar55', 'localhost:2003/OSRDB') ;
if (!$conn) {
$m = aci_error();
trigger_error(htmlentities($m['message']), E_USER_ERROR);
}
$sql = 'SELECT last_name FROM employees WHERE employee_id in (:e1, :e2, :e3)';
$stid = aci_parse($conn, $sql);
$mye1 = 103;
$mye2 = 104;
$mye3 = NULL; // pretend we were not given this value
aci_bind_by_name($stid, ':e1', $mye1);
aci_bind_by_name($stid, ':e2', $mye2);
aci_bind_by_name($stid, ':e3', $mye3);
aci_execute($stid);
aci_fetch_all($stid, $res);
foreach ($res['LAST_NAME'] as $name) {
print $name ."<br>\n";
}
// Output is
// Ernst
// Hunold
aci_free_statement($stid);
aci_close($conn);
?>
示例 #11 绑定查询返回的ROWID
<?php
// Create the table with:
// CREATE TABLE mytab (id NUMBER, salary NUMBER, name VARCHAR2(40));
// INSERT INTO mytab (id, salary, name) VALUES (1, 100, 'Chris');
// COMMIT;
$conn = aci_connect('sysdba', 'szoscar55', 'localhost:2003/OSRDB') ;
if (!$conn) {
$m = aci_error();
trigger_error(htmlentities($m['message']), E_USER_ERROR);
}
$stid = aci_parse($conn, 'SELECT ROWID, name FROM mytab WHERE id = :id_bv FOR UPDATE');
$id = 1;
aci_bind_by_name($stid, ':id_bv', $id);
aci_execute($stid);
$row = aci_fetch_array($stid, OCI_ASSOC+OCI_RETURN_NULLS);
$rid = $row['ROWID'];
$name = $row['NAME'];
// Change name to upper case & save the changes
$name = strtoupper($name);
$stid = aci_parse($conn, 'UPDATE mytab SET name = :n_bv WHERE ROWID = :r_bv');
aci_bind_by_name($stid, ':n_bv', $name);
aci_bind_by_name($stid, ':r_bv', $rid, -1, OCI_B_ROWID);
aci_execute($stid);
// The table now contains 1, 100, CHRIS
aci_free_statement($stid);
aci_close($conn);
?>
示例 #12 在INSERT上绑定ROWID
<?php
// This example inserts an id & name, and then updates the salary
// Create the table with:
// CREATE TABLE mytab (id NUMBER, salary NUMBER, name VARCHAR2(40));
//
// Based on original ROWID example by thies at thieso dot net (980221)
$conn = aci_connect('sysdba', 'szoscar55', 'localhost:2003/OSRDB') ;
if (!$conn) {
$m = aci_error();
trigger_error(htmlentities($m['message']), E_USER_ERROR);
}
$sql = "INSERT INTO mytab (id, name) VALUES(:id_bv, :name_bv)
RETURNING ROWID INTO :rid";
$ins_stid = aci_parse($conn, $sql);
$rowid = aci_new_descriptor($conn, OCI_D_ROWID);
aci_bind_by_name($ins_stid, ":id_bv", $id, 10);
aci_bind_by_name($ins_stid, ":name_bv", $name, 32);
aci_bind_by_name($ins_stid, ":rid", $rowid, -1, OCI_B_ROWID);
$sql = "UPDATE mytab SET salary = :salary WHERE ROWID = :rid";
$upd_stid = aci_parse($conn, $sql);
aci_bind_by_name($upd_stid, ":rid", $rowid, -1, OCI_B_ROWID);
aci_bind_by_name($upd_stid, ":salary", $salary, 32);
// ids and names to insert
$data = array(1111 => "Larry",
2222 => "Bill",
3333 => "Jim");
// Salary of each person
$salary = 10000;
// Insert and immediately update each row
foreach ($data as $id => $name) {
aci_execute($ins_stid);
aci_execute($upd_stid);
}
$rowid->free();
aci_free_statement($upd_stid);
aci_free_statement($ins_stid);
// Show the new rows
$stid = aci_parse($conn, "SELECT * FROM mytab");
aci_execute($stid);
while ($row = aci_fetch_array($stid, OCI_ASSOC+OCI_RETURN_NULLS)) {
var_dump($row);
}
aci_free_statement($stid);
aci_close($conn);
?>
示例 #13 PL/SQL存储函数的绑定
<?php
// Before running the PHP program, create a stored function in
// SQL*Plus or SQL Developer:
//
// CREATE OR REPLACE FUNCTION myfunc(p IN NUMBER) RETURN NUMBER AS
// BEGIN
// RETURN p * 3;
// END;
$conn = aci_connect('sysdba', 'szoscar55', 'localhost:2003/OSRDB') ;
if (!$conn) {
$e = aci_error();
trigger_error(htmlentities($e['message']), E_USER_ERROR);
}
$p = 8;
$stid = aci_parse($conn, 'begin :r := myfunc(:p); end;');
aci_bind_by_name($stid, ':p', $p);
// The return value is an OUT bind. The default type will be a string
// type so binding a length 40 means that at most 40 digits will be
// returned.
aci_bind_by_name($stid, ':r', $r, 40);
aci_execute($stid);
print "$r\n"; // prints 24
aci_free_statement($stid);
aci_close($conn);
?>
示例 #14 PL/SQL存储过程的绑定参数
<?php
// Before running the PHP program, create a stored procedure in
// SQL*Plus or SQL Developer:
//
// CREATE OR REPLACE PROCEDURE myproc(p1 IN NUMBER, p2 OUT NUMBER) AS
// BEGIN
// p2 := p1 * 2;
// END;
$conn = aci_connect('sysdba', 'szoscar55', 'localhost:2003/OSRDB') ;
if (!$conn) {
$e = aci_error();
trigger_error(htmlentities($e['message']), E_USER_ERROR);
}
$p1 = 8;
$stid = aci_parse($conn, 'begin myproc(:p1, :p2); end;');
aci_bind_by_name($stid, ':p1', $p1);
// The second procedure parameter is an OUT bind. The default type
// will be a string type so binding a length 40 means that at most 40
// digits will be returned.
aci_bind_by_name($stid, ':p2', $p2, 40);
aci_execute($stid);
print "$p2\n"; // prints 16
aci_free_statement($stid);
aci_close($conn);
?>
示例 #15 绑定CLOB列
<?php
// Before running, create the table:
// CREATE TABLE mytab (mykey NUMBER, myclob CLOB);
$conn = aci_connect('sysdba', 'szoscar55', 'localhost:2003/OSRDB') ;
if (!$conn) {
$e = aci_error();
trigger_error(htmlentities($e['message']), E_USER_ERROR);
}
$mykey = 12343; // arbitrary key for this example;
$sql = "INSERT INTO mytab (mykey, myclob)
VALUES (:mykey, EMPTY_CLOB())
RETURNING myclob INTO :myclob";
$stid = aci_parse($conn, $sql);
$clob = aci_new_descriptor($conn, OCI_D_LOB);
aci_bind_by_name($stid, ":mykey", $mykey, 5);
aci_bind_by_name($stid, ":myclob", $clob, -1, OCI_B_CLOB);
aci_execute($stid, OCI_DEFAULT);
$clob->save("A very long string");
aci_commit($conn);
// Fetching CLOB data
$query = 'SELECT myclob FROM mytab WHERE mykey = :mykey';
$stid = aci_parse ($conn, $query);
aci_bind_by_name($stid, ":mykey", $mykey, 5);
aci_execute($stid);
print '<table border="1">';
while ($row = aci_fetch_array($stid, OCI_ASSOC+OCI_RETURN_LOBS)) {
print '<tr><td>'.$row['MYCLOB'].'</td></tr>';
// In a loop, freeing the large variable before the 2nd fetch reduces PHP's peak memory usage
unset($row);
}
print '</table>';
?>
示例 #16 绑定PL/SQL布尔
<?php
$conn = aci_connect('sysdba', 'szoscar55', 'localhost:2003/OSRDB') ;
if (!$conn) {
$e = aci_error();
trigger_error(htmlentities($e['message']), E_USER_ERROR);
}
$plsql =
"begin
:output1 := true;
:output2 := false;
end;";
$s = aci_parse($c, $plsql);
aci_bind_by_name($s, ':output1', $output1, -1, OCI_B_BOL);
aci_bind_by_name($s, ':output2', $output2, -1, OCI_B_BOL);
aci_execute($s);
var_dump($output1); // true
var_dump($output2); // false
?>
返回值¶
成功时返回 true, 或者在失败时返回 false。
注释¶
警告
警告 不要同时使用magic_quotes_gpc或addslashes()和aci_bind_by_name(),因为不需要引号。 由于aci_bind_by_name()逐字插入数据,并且不会删除引号或转义字符,因此任何神奇应用的引号都将写入数据库。
注意:
如果在WHERE子句中将字符串绑定到CHAR列,请记住数据库对CHAR列使用空白填充的比较语义。要使WHERE子句成功,您的PHP变量应该空白填充到与列相同的宽度。
注意:
PHP变量参数是一个引用。某些形式的循环无法按预期工作
<?php
foreach ($myarray as $key => $value) {
aci_bind_by_name($stid, $key, $value);
}
?>
这将每个键绑定到$value的位置,因此所有绑定的变量最终都指向最后一个循环迭代的值。相反,请使用以下内容:
<?php
foreach ($myarray as $key => $value) {
aci_bind_by_name($stid, $key, $myarray[$key]);
}
?>
参见¶
- aci_bind_array_by_name() - 将PHP数组绑定到PL/SQL数组参数
- aci_parse() - 配置语句预备执行