如何使用oracle从存储函数中检索多行
我试图在oracle中创建一个返回多行的存储函数 我的问题与非常类似,只是我想获取一个select*查询 简而言之,我想创建一个函数,返回这个查询的结果如何使用oracle从存储函数中检索多行,oracle,plsql,Oracle,Plsql,我试图在oracle中创建一个返回多行的存储函数 我的问题与非常类似,只是我想获取一个select*查询 简而言之,我想创建一个函数,返回这个查询的结果 select * from t_email_queue select * from table(email_queue.lock_and_get); 我试过的是: create or replace PACKAGE email_queue AS type t_email_queue_type is table of T_EMAIL_
select * from t_email_queue
select * from table(email_queue.lock_and_get);
我试过的是:
create or replace
PACKAGE email_queue AS
type t_email_queue_type is table of T_EMAIL_QUEUE%ROWTYPE;
FUNCTION lock_and_get return t_email_queue_type;
END email_queue;
create or replace
PACKAGE BODY email_queue AS
FUNCTION lock_and_get RETURN t_email_queue_type AS
queue_obj t_email_queue_type;
cursor c (lockid in varchar2) is select * from t_email_queue where lockedby = lockid;
lockid varchar2(100) := 'alf';
BEGIN
OPEN c(lockid);
FETCH c bulk collect INTO queue_obj;
return queue_obj;
END lock_and_get;
END email_queue;
这个包编译得很好,但是当我试图用这个查询调用它时
select * from t_email_queue
select * from table(email_queue.lock_and_get);
Oracle抛出以下错误
ORA-00902: invalid datatype
00902. 00000 - "invalid datatype"
*Cause:
*Action:
Error at Line: 1 Column: 20
我认为Oracle希望我在模式级别创建返回类型,但当我尝试这样做时
create type t_email_queue_type is table of T_EMAIL_QUEUE%ROWTYPE;
甲骨文抱怨
Type IMAIL.T_EMAIL_QUEUE_TYPE@imail dev
Error(1): PL/SQL: Compilation unit analysis terminated
Error(2,37): PLS-00329: schema-level type has illegal reference to IMAIL.T_EMAIL_QUEUE
有人能给我指一下正确的方向吗?我错过了什么
谢谢你的阅读 对于SQL类型,您不能使用%ROWTYPE,您必须键入每一列以匹配表* *把sys.anydataset放在一边。但是沿着这条路线走下去的编码要复杂得多 e、 如果你的桌子是空的
create table foo (id number, cola varchar2(1));
然后
并使用该表email_queue_type_选项卡作为函数的输出
但我建议使用流水线函数,因为您当前的代码不可伸缩
例如:
如果您对SQL类型不太感兴趣,可以使用sys\u refcursor: 从SQL*Plus中,您可以将其称为:
var cur refcursor;
exec :cur := email_queue.lock_and_get;
print cur
由于exec是一个简单匿名块的简写,如果您也可以从其他PL/SQL对象调用它,那么就可以调用它。但你不能做的是:
select * from table(email_queue.lock_and_get);
我不熟悉从PHP调用函数,但从Java可以直接使用它作为可调用语句的返回,因此根本不需要select*from表构造。我不知道是否可以在PHP调用中执行匿名块,比如begin$cur=email\u queue.lock\u和\u get;终止并将$cur作为您的结果集,然后您可以对其进行迭代
我意识到这不是一个完整的答案,因为PHP方面太模糊了,但可能会给您一些想法。如果您使用PHP并且希望访问oracle存储函数。你可以利用这样的东西
//Your connection details
$conn = oci_connect($username, $password, '(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = 127.0.0.1)(PORT = 1521))(CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = XE)))' );
/* Your query string; you can use oci_bind_by_name to bind parameters or just pass the variable in it*/
$query = "begin :cur := functionName('".$param1."','".$param2."','".$param3."'); end;";
$stid = oci_parse($conn, $query);
$OUTPUT_CUR = oci_new_cursor($conn);
oci_bind_by_name($stid, ':cur', $OUTPUT_CUR, -1, OCI_B_CURSOR);
oci_execute($stid);
oci_execute($OUTPUT_CUR);
oci_fetch_all($OUTPUT_CUR, $res);
// To get your result
var_dump($res);
我希望这能有所帮助。这个解决方案的问题是,当我必须向表t\u email\u队列中添加一列时,我还必须修改我的类型email\u queue\u type,这很痛苦;当我修改类型和包时,我必须停止我的PHP脚本调用包,这不是一个选项。@Alfwed您在11g上吗。如果是这样的话,版本就意味着你可以在不停止PHP应用程序的情况下更新type+package/type。我们大约每秒钟调用一次这个函数。您是说我可以在两次调用之间编辑表、类型和包?@Alfwed您以前遇到过表问题,但正如我所说的,对于editions,您可以在新版本中编辑类型+包,因此运行的代码无法看到它。完成后,您将其设置为活动,以便任何新呼叫都能看到它。例如,呼叫A进入,然后您在新版本中编辑类型,然后呼叫B进入。呼叫B仍将看到旧类型。我建议你读一下。我看这是个好答案。我目前正在使用这种技术,但我不太喜欢它,因为从PHP调用这种函数有点奇怪。因此,我的问题是关于表返回类型。@Alfwed-可能是一个没有意义的区别,但是在过程中返回ref游标作为out参数也是一个选项。在PHP中可能同样奇怪,但我不知道*8-
//Your connection details
$conn = oci_connect($username, $password, '(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = 127.0.0.1)(PORT = 1521))(CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = XE)))' );
/* Your query string; you can use oci_bind_by_name to bind parameters or just pass the variable in it*/
$query = "begin :cur := functionName('".$param1."','".$param2."','".$param3."'); end;";
$stid = oci_parse($conn, $query);
$OUTPUT_CUR = oci_new_cursor($conn);
oci_bind_by_name($stid, ':cur', $OUTPUT_CUR, -1, OCI_B_CURSOR);
oci_execute($stid);
oci_execute($OUTPUT_CUR);
oci_fetch_all($OUTPUT_CUR, $res);
// To get your result
var_dump($res);