何时在 PHP 中使用 OCI_B_INT?
When to use OCI_B_INT in PHP?
我有一个具有以下结构的 Oracle table:
column type key
---------------------------------------------
id integer primary key
user_id integer foreign key
colony_id number(14) foreign key
last_upd_username varchar2(50)
last_upd_date date
我没有创建 table 但我认为 colony_id
也应该是 integer
- 而不是 number
(现在太晚了无论如何都要改变它).
我有一个插入多行的查询 table:
$colonies = array_map("intval", $post['colonies']);
# Assign colonies to $user_id
$sql = "INSERT INTO user_colonies (
id,
user_id,
colony_id,
last_upd_username,
last_upd_date
) VALUES (
user_colonies_seq.NEXTVAL,
:user_id,
:colony_id,
:username,
sysdate
)";
$stmt = oci_parse($conn, $sql);
oci_bind_by_name($stmt, ":user_id", $user_id);
oci_bind_by_name($stmt, ":colony_id", $colony);
oci_bind_by_name($stmt, ":username", $username);
foreach($colonies as $colony) {
$r = oci_execute($stmt, OCI_DEFAULT);
if(!$r) {
$e = oci_error($stmt);
$result['err'][] = $e['message'];
}
}
$result['msg'] = 'success';
oci_commit($conn);
oci_free_statement($stmt);
echo json_encode($result);
这种工作因为查询运行良好 ($e['message']
) 总是 null
。但是,当我查看插入的行时,colony_id
没有任何意义,它们只是一堆从 1 到 9 的随机整数,而我期待的是实际 ID(应该是数千个)。
我能够通过更改
使其工作
oci_bind_by_name($stmt, ":colony_id", $colony);
进入
oci_bind_by_name($stmt, ":colony_id", $colony, -1, OCI_B_INT);
通过使用 OCI_B_INT
,使用了正确的 ID,一切正常。我不明白何时以及如何使用该标志,因为绑定 $user_id
到 ":user_id"
在没有标志的情况下工作正常。我能看到的唯一区别是数据类型(integer
vs number(14)
)。
这确实不是 OCI_B_INT
标志的问题。真正的罪魁祸首是 maxlength
参数。
You must specify maxlength
when using an OUT bind so that PHP
allocates enough memory to hold the returned value.
For IN binds it is recommended to set the maxlength
length if the
statement is re-executed multiple times with different values for the
PHP variable. Otherwise Oracle may truncate data to the length of the
initial PHP variable value. If you don't know what the maximum length
will be, then re-call oci_bind_by_name()
with the current data size
prior to each oci_execute()
call. Binding an unnecessarily large
length will have an impact on process memory in the database.
foreach($colonies as $colony) {
oci_bind_by_name($stmt, ":colony_id", $colony, -1, OCI_B_INT);
$r = oci_execute($stmt, OCI_DEFAULT);
}
我有一个具有以下结构的 Oracle table:
column type key
---------------------------------------------
id integer primary key
user_id integer foreign key
colony_id number(14) foreign key
last_upd_username varchar2(50)
last_upd_date date
我没有创建 table 但我认为 colony_id
也应该是 integer
- 而不是 number
(现在太晚了无论如何都要改变它).
我有一个插入多行的查询 table:
$colonies = array_map("intval", $post['colonies']);
# Assign colonies to $user_id
$sql = "INSERT INTO user_colonies (
id,
user_id,
colony_id,
last_upd_username,
last_upd_date
) VALUES (
user_colonies_seq.NEXTVAL,
:user_id,
:colony_id,
:username,
sysdate
)";
$stmt = oci_parse($conn, $sql);
oci_bind_by_name($stmt, ":user_id", $user_id);
oci_bind_by_name($stmt, ":colony_id", $colony);
oci_bind_by_name($stmt, ":username", $username);
foreach($colonies as $colony) {
$r = oci_execute($stmt, OCI_DEFAULT);
if(!$r) {
$e = oci_error($stmt);
$result['err'][] = $e['message'];
}
}
$result['msg'] = 'success';
oci_commit($conn);
oci_free_statement($stmt);
echo json_encode($result);
这种工作因为查询运行良好 ($e['message']
) 总是 null
。但是,当我查看插入的行时,colony_id
没有任何意义,它们只是一堆从 1 到 9 的随机整数,而我期待的是实际 ID(应该是数千个)。
我能够通过更改
使其工作oci_bind_by_name($stmt, ":colony_id", $colony);
进入
oci_bind_by_name($stmt, ":colony_id", $colony, -1, OCI_B_INT);
通过使用 OCI_B_INT
,使用了正确的 ID,一切正常。我不明白何时以及如何使用该标志,因为绑定 $user_id
到 ":user_id"
在没有标志的情况下工作正常。我能看到的唯一区别是数据类型(integer
vs number(14)
)。
这确实不是 OCI_B_INT
标志的问题。真正的罪魁祸首是 maxlength
参数。
You must specify
maxlength
when using an OUT bind so that PHP allocates enough memory to hold the returned value.For IN binds it is recommended to set the
maxlength
length if the statement is re-executed multiple times with different values for the PHP variable. Otherwise Oracle may truncate data to the length of the initial PHP variable value. If you don't know what the maximum length will be, then re-calloci_bind_by_name()
with the current data size prior to eachoci_execute()
call. Binding an unnecessarily large length will have an impact on process memory in the database.
foreach($colonies as $colony) {
oci_bind_by_name($stmt, ":colony_id", $colony, -1, OCI_B_INT);
$r = oci_execute($stmt, OCI_DEFAULT);
}