php oci_bind_by_name无法循环工作

时间:2017-05-15 12:57:36

标签: php oracle

我试图在foreach循环中按名称绑定,但这似乎没有用。

旧方式工作:

oci_bind_by_name($result, ':exemptionid', $exemption_id, 10, SQLT_INT);
oci_bind_by_name($result, ':seq', $seq, 10, SQLT_INT);
oci_bind_by_name($result, ':action', $action, 20, SQLT_CHR);
oci_bind_by_name($result, ':s_zone',$sourceZones,48,SQLT_CHR);
oci_bind_by_name($result, ':s_seczone',$szone1,32,SQLT_CHR);
oci_bind_by_name($result, ':d_zone',$destinationZones,48,SQLT_CHR);
oci_bind_by_name($result, ':d_seczone',$dzone1,32,SQLT_CHR);
if($protocol_id != null) {
    oci_bind_by_name($result, ':protocolid', $protocol_id, 10, SQLT_INT);
}
if($ports != null) {
    oci_bind_by_name($result, ':ports', $ports, 32, SQLT_CHR);
}
if($note != null) {
    oci_bind_by_name($result, ':note', $note, 128, SQLT_CHR);
}
oci_bind_by_name($result, ':method', $method, 1, SQLT_CHR);
$authuser = authUser();
oci_bind_by_name($result, ':authuser', $authuser, 64, SQLT_CHR);

但是当我把这个全部放入一个数组并放入函数并尝试在循环中处理它时,它会失败绑定整数。

不工作

function bind($resource, $binds){
    foreach ($binds as $placeholder => $varibale){
        oci_bind_by_name($resource,$placeholder, $varibale[0],$varibale[1],$varibale[2]);
    }
}

$binds = [
    ':exemptionid' => [
        $exemption_id,
        10,
        SQLT_INT
    ],
    ':source' => [
        ($source != "") ? $source : $sourceZones,
        strlen ($source),
        SQLT_CHR
    ],
    ':destination' => [
        ($destination != "" ) ? $destination : $destinationZones,
        strlen ($destination),
        SQLT_CHR
    ]
];

if ($protocol_id != null) {
    $binds [':protocolid'] = [
        $protocol_id,
        10,
        SQLT_INT
    ];
}
if ($ports != null) {
    $binds [':ports'] = [
        $ports,
        32,
       SQLT_CHR
    ];
}

bind($resource, $binds); // not working

我得到的错误是oci_execute(): ORA-01438: value larger than specified precision allowed for this column,但我的列都没有小数,而且我没有传递任何小数。

更新

为什么我必须通过ref?

function bind($resource, $binds)
{
    foreach ($binds as $key => $val) {
        $variable = &$binds[$key][0];
        $length = (isset($binds[$key][1])) ? $binds[$key][1] : -1;
        $type = (isset($binds[$key][2])) ? $binds[$key][2] : SQLT_CHR;
        oci_bind_by_name($resource, $key, $variable, $length, $type);
                        }
}

1 个答案:

答案 0 :(得分:4)

Example #3 Binding with a foreach() loop评论oci_bind_by_name手册页上记录了这一点(虽然模糊不清):

foreach ($ba 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: $ba[$key]
    oci_bind_by_name($stid, $key, $ba[$key]);
}

所以你应该改变你的功能(vars重命名以避免换行):

function bind($resource, $binds)
{
    foreach ($binds as $key => $val) {
        oci_bind_by_name($resource, $key, $binds[$key][0], $binds[$key][1], $binds[$key][2]);
    }
}