在PHP中执行存储过程给出了ORA-01460。 这是php中的简化(原始有超过48个输入值)代码:
$proc_sql = "BEGIN CREATE_RECORD(:b1, :b2, :b3, :b4, :b5, :b6); END;";
$bind = array("bind 1", "bind 2", "bind 3", "bind 4", "bind 5", "OUT DUMMY");
$stmt = oci_parse($conn, $proc_sql);
$i = 1;
$outval = "";
foreach($bind as $val){
$tmp =":b".$i;
if($i < count($bind)){
oci_bind_by_name($stmt,$tmp,$val);
}else{
oci_bind_by_name($stmt, $tmp, $outval, 512);
}
$i++;
}
oci_execute($stmt);
最后一行产生警告。但是,如果我直接在SQL Developer中运行查询:
declare
re varchar2(512);
begin
CREATE_RECORD('bind 1', 'bind 2', 'bind 3', 'bind 4', 'bind 5', re);
dbms_output.put_line(re);
end;
插入已成功完成。
这是我的第一个PHP&amp;项目Oracle组合。所以我不知道我的php是不正确还是问题出在其他地方。
以下是来自phpinfo()
的OCI8信息:
oci8
OCI8 Support enabled
OCI8 DTrace Support disabled
OCI8 Version 2.0.8
Oracle Run-time Client Library Version 10.2.0.3.0
Oracle Compile-time Instant Client Version 10.2
Directive Local Value Master Value
oci8.default_prefetch 100 100
oci8.events Off Off
oci8.max_persistent -1 -1
oci8.old_oci_close_semantics Off Off
oci8.persistent_timeout -1 -1
oci8.ping_interval 60 60
oci8.privileged_connect Off Off
oci8.statement_cache_size 20 20
PHP Version 5.5.17
和Oracle 9i
请帮忙找出我收到此警告的原因。
谢谢你的阅读。
更新
以下代码也适用:
$proc_sql = "BEGIN CREATE_RECORD('bind 1', 'bind 2', 'bind 3', 'bind 4', 'bind 5', :b6); END;";
$stmt = oci_parse($conn, $proc_sql);
$outval = "";
oci_bind_by_name($stmt, ':b6', $outval, 512);
正如我上面所说,这是执行程序代码的简化版本,实际上我需要绑定48个参数IN和一个OUT参数。是否必须在OCI8设置中对statement_cache_size
执行某些操作?
我已经阅读了docs,但无法理解它是否与我的问题有关。
答案 0 :(得分:1)
请见this piece of PHP documentation,尤其是这部分:
绑定调用告诉Oracle从哪个内存地址读取数据。对于 当oci_execute()时,IN绑定地址需要包含有效数据 叫做。这意味着变量bound必须保留在范围内 直到执行。如果没有,意外的结果或错误,如 “ORA-01460:要求的未实现或不合理的转换”可以 发生。对于OUT绑定,一个症状是没有在PHP中设置值 变量
如果我很好地解释你的代码,你在循环中使用一个局部变量来循环你的IN参数,所以你不满足在循环完成后调用oci_execute时在范围内拥有所有值的要求。
答案 1 :(得分:0)
那些在 for-each
循环内绑定参数时遇到问题的人请继续阅读。
答案之一 here 有以下评论,在一个示例代码片段中,该代码片段说明了循环内的绑定参数 - 这是有道理的。
foreach ($arr as $key => $val) {
// oci_bind_by_name($stid, $key, $val) does not work
// because it binds each placeholder to the same location: $val
// instead use the actual location of the data: $arr[$key]
}
根据上述声明,以下不工作,
$arr = array(':a' => 1, ':b' => 2);
foreach ($arr as $key => $val) {
oci_bind_by_name($stid, $key, $val);
}
以下做工作,
$arr = array(':a' => 1, ':b' => 2);
foreach ($arr as $key => $val) {
oci_bind_by_name($stid, $key, $arr[$key]);
}
我希望有人会觉得这很有用 :)