plsql — обрабатывает функцию PL / SQL, возвращающую запись в переполнении стека

Я искал в Интернете, и я не нашел ответа, так что я здесь.

У меня есть функция 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

Так что это самоочевидная ошибка, но я все еще не могу понять, как я могу ее использовать.

Спасибо.

0

Решение

Для названный тип данных, вам, вероятно, нужно связать свой параметр, указав 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();

Смотрите руководство функция oci_bind_by_name для деталей.


За гладкий PL / SQL записей, вам, вероятно, не повезло: согласно Документация Oracle Вы не можете использовать OCI для получения записи. Начиная с Oracle 11g:

Следующие два типа являются внутренними для PL / SQL и не могут быть возвращены в качестве значений OCI:

  • Boolean, SQLT_BOL
  • Запись, SQLT_REC

Если это правильно (я не обычный пользователь PHP), вам, вероятно, придется обернуть свою функцию на уровне PL / SQ:

  • либо в процедуре с необходимым количеством OUT параметры;
  • или, может быть, в зависимости от ваших потребностей, в табличная функция.

Для полноты, пожалуйста, обратите внимание, что Oracle 12c + OCI8 2.0.7 убирает ограничение, которое ранее не позволяло возвращать логическое значение.

1

Другие решения

Спасибо за ваш ответ, я пробовал SQLT_NTY, но он не работает, вероятно, потому что 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;
}
0

По вопросам рекламы [email protected]