我尝试调用返回数字的包中的存储函数:
function LOGIN(USERNAME in varchar2 default null
, PASSWORD in varchar2 default null)
return number;
它返回 0 或负整数表示失败,返回一个正整数表示成功。这是我调用该函数的 PHP 代码:
$sql = ":v_res := PACK.LOGIN(:p_user, :p_pass)";
$bindings = [ ':p_user' => 'test', ':p_pass' => '1234', ':v_res' => & $result];
$statement oci_parse($connection, $sql);
foreach ($bindings as $k => & $v) {
oci_bind_by_name($statement, $k, $v, customSizeOf($v), determineSqlType($v));
}
oci_execute($statement);
当我使用如下所示的结果(在绑定中使用之前未定义)时,它会返回"未定义的变量"警告。如果我抑制警告并继续前进,它将绑定为 null,大小为 -1 和类型 1 (SQLT_CHR);如果我定义像 $result = -1;
这样的结果,它与 -1、PHP_INT_SIZE 的大小和类型 3 (SQLT_INT) 绑定。
无论哪种方式,在执行时都会产生此错误
ORA-01036: illegal variable name/number
这不起作用,因为您必须将调用包装在 PL/SQL 块或 SQL 查询中:
$sql = "BEGIN :v_res := PACK.LOGIN(:p_user, :p_pass); END";
或
$sql = "SELECT caller(:p_user, :p_pass) v_res FROM DUAL"
这奏效了,我已经不知道为什么了,但它有效:
$result = -1;
$sql = <<<"SQL"
begin
:V_RETURN := PACK.LOGIN(
USERNAME => :USERNAME,
PASSWORD => :PASSWORD
);
end;
SQL;
$bindings = [
':USERNAME' => $username,
':PASSWORD' => $password,
':V_RETURN' => & $result,
];
$statement oci_parse($connection, $sql);
foreach ($bindings as $k => & $v) {
oci_bind_by_name($statement, $k, $v, customSizeOf($v), determineSqlType($v));
}
oci_execute($statement);
它应该通过引用传递给数组,但仍然不知道它为什么工作,另一个抛出了绑定错误;如果有的话,它应该绑定一个内存,它不会被$result
。
更新:最好使用SQLT_LNG
类型而不是SQLT_INT
因为它可能无法在Unix系统上正常工作,并且为所有内容(溢出)提供int(-4294967295)
。与公众的看法相反,Windows对SQLT_INT
和SQLT_LNG
都很好,所以我建议兼容性问题使用SQLT_LNG
。
@Cunning : 请尝试以下选项。
- 检查 http://php.net/manual/en/oci8.examples.php 。
-
尝试更改绑定顺序
$bindings = [':v_res' => & $result, ':p_user' => 'test', ':p_pass' => '1234'];