在PHP中处理返回记录的PL/SQL函数

在PHP中处理返回记录的PL/SQL函数,php,plsql,record,Php,Plsql,Record,我一直在网上搜索,但没有找到答案,所以我来了 我有一个PL/SQL函数返回一条记录: create or replace package pck_test is TYPE coord_geo is record (coord_x float, coord_y float); function ArrondiGeo(coord_x float, coord_y float) return coord_geo; end pck_test; / create or replace p

我一直在网上搜索,但没有找到答案,所以我来了

我有一个PL/SQL函数返回一条记录:

create or replace package pck_test is
    TYPE coord_geo is record (coord_x float, coord_y float);
    function ArrondiGeo(coord_x float, coord_y float) return coord_geo;
end pck_test;
/

create or replace package body pck_test is
    FUNCTION ArrondiGeo(coord_x FLOAT,coord_y FLOAT) RETURN coord_geo
    IS
        temp_x FLOAT(24);
        temp_y FLOAT(24);
        rec_coord coord_geo;
    BEGIN
        temp_x := ROUND(coord_x,4)/5;
        temp_y := ROUND(coord_y,4)/5;

        temp_x := ROUND((temp_x*5),3);
        temp_y := ROUND((temp_y*5),3);

        rec_coord.coord_x := temp_x;
        rec_coord.coord_y := temp_y;

        RETURN rec_coord;
    END;
END pck_test;
/
我想在PHP函数中使用它,但我真的不知道如何

我试过这个,但不起作用:

public function get_tronc($x,$y)
    {
        $q = oci_parse($this->_db, 'begin :r := pck_test.ArrondiGeo(:x,:y); end;');
        oci_bind_by_name($q, ':x', $x);
        oci_bind_by_name($q, ':y', $y);
        oci_bind_by_name($q, ':r', $r);
        oci_execute($q);

        return $r;
    }
错误是:

Warning: oci_execute(): ORA-06550: line 1, column 13: PLS-00382: expression is of wrong type ORA-06550: line 1, column 7: PL/SQL: Statement ignored in /users/info/il3/jboeglin/Bureau/BDD/site/models/userManager.php on line 77 
这是一个自我解释的错误,但我仍然不知道如何使用它

谢谢。

对于命名的数据类型,您可能需要绑定指定
SQLT\NTY
类型的参数:

    $r = oci_new_collection($this->db, 'COORD_GEO');
    oci_bind_by_name($q, ':r', $r, -1, SQLT_NTY);
    ...
    oci_execute($q);

    // do whatever you need with your data
    $data = $elem = $collection->getElem(1);

    // then discard it
    $r->free();
有关详细信息,请参阅的手册


对于普通PL/SQL记录,您可能运气不好:根据我们的说法,您不能使用OCI获取记录。从Oracle 11g开始:

以下两种类型是PL/SQL的内部类型,OCI无法将其作为值返回:

  • 布尔值,
    SQLT\u BOL
  • 记录,
    SQLT\u REC
如果这是正确的(我不是一个普通的PHP用户),您可能需要在PL/SQ级别包装您的函数:

  • 或者,在具有所需数量的
    OUT
    参数的程序中
  • 或者,根据您的需要,在表函数中

为了完整起见,请注意。

谢谢您的回答,我尝试了SQLT\n,但它不起作用,可能是因为OCI无法像您所说的那样返回记录。。。 我将尝试查看一个表函数

编辑:我最终使用了一个程序

create or replace package pck_test is

PROCEDURE ArrondiGeo(coord_x IN FLOAT,coord_y IN FLOAT,temp_x OUT FLOAT,temp_y OUT FLOAT);

end pck_test;
/

create or replace package body pck_test is
    PROCEDURE ArrondiGeo(coord_x IN FLOAT,coord_y IN FLOAT,temp_x OUT FLOAT,temp_y OUT FLOAT)
    IS
    BEGIN
        temp_x := ROUND(coord_x,4)/5;
        temp_y := ROUND(coord_y,4)/5;

        temp_x := ROUND((temp_x*5),3);
        temp_y := ROUND((temp_y*5),3);
    END;
END pck_test;
/

这个php函数:

public function get_tronc($x,$y)
{
    $q = oci_parse($this->_db, 'begin pck_test.ArrondiGeo(:x,:y,:xm,:ym); end;');
    oci_bind_by_name($q, ':x', $x);
    oci_bind_by_name($q, ':y', $y);
    oci_bind_by_name($q, ':xm', $xm,40);
    oci_bind_by_name($q, ':ym', $ym,40);
    oci_execute($q);

    $r=array($xm,$ym);

    return $r;
}

我试过了,但得到了:警告:oci_bind_by_name():在第76行的/users/info/il3/jboeglin/Bureau/BDD/site/models/userManager.php中找不到集合属性警告:oci_execute():ORA-01008:并非所有变量都绑定在/users/info/il3/jboeglin/Bureau/BDD/site/models/userManager.php在线中77@Jérôme要使用
SQLTôNTY
您需要将变量初始化为一个变量。我已经编辑了我的答案(我所记得的最好答案),向您展示了如何做到这一点。谢谢您,我会尝试一下,即使这是一个过程