Oracle 是否可以将带有参数的游标作为过程的参数传递?
我有很多类似的处理方法要做,我想为它编写一个pl/sql脚本。 查看代码比解释代码更容易理解,因此这里是一个简化版本:Oracle 是否可以将带有参数的游标作为过程的参数传递?,oracle,plsql,Oracle,Plsql,我有很多类似的处理方法要做,我想为它编写一个pl/sql脚本。 查看代码比解释代码更容易理解,因此这里是一个简化版本: create or replace package my_test as cursor my_cursor(my_filter NUMBER) is select column1, column2 from mytable where column3 = my_filter; cursor my_cursor2(my_filter VARCHAR2) is select
create or replace package my_test as
cursor my_cursor(my_filter NUMBER) is select column1, column2 from mytable where column3 = my_filter;
cursor my_cursor2(my_filter VARCHAR2) is select column1, column2 from mytable where column4 LIKE my_filter;
-- ...
procedure test1;
procedure test2(p_cursor XXX);
function test3(test_record XXX%ROWTYPE) return number;
end my_test;
/
create or replace package body my_test as
procedure test1 is
begin
test2(my_cursor(3));
test2(my_cursor2('foo%'));
test2(my_cursor(5));
-- ...
end test1;
procedure test2(p_cursor XXX) is
tmp number;
begin
for r in p_cursor loop
--some actions
tmp := test3(r);
--some actions
end loop;
end test2;
function test3(test_record XXX%ROWTYPE) return number is
tmp_sum number;
begin
-- ...
tmp_sum := test_record.column1 + test_record.column2;
-- ...
return l_summ;
end test3;
end my_test;
/
BEGIN
my_test.test1();
END;
/
我已经尽力了,但没有成功。也许有人能帮我?有可能实现这样的事情吗?我应该放什么来代替XXX呢?光标变量非常适合您想要做的事情 下面是对部分代码的重写,演示了如何使用它们:
CREATE OR REPLACE PACKAGE my_test
AS
PROCEDURE test1;
PROCEDURE test2 (p_cursor IN OUT SYS_REFCURSOR);
END my_test;
/
CREATE OR REPLACE PACKAGE BODY my_test
AS
FUNCTION my_cursor (my_filter NUMBER)
RETURN SYS_REFCURSOR
IS
l_cursor SYS_REFCURSOR;
BEGIN
OPEN l_cursor FOR
SELECT column1, column2
FROM mytable
WHERE column3 = my_filter;
RETURN l_cursor;
END;
PROCEDURE test1
IS
BEGIN
test2 (my_cursor (3));
test2 (my_cursor (5));
END test1;
PROCEDURE test2 (p_cursor xxx)
IS
tmp NUMBER;
BEGIN
LOOP
FETCH p_cursor INTO tmp;
EXIT WHEN p_cursor%NOTFOUND;
--some actions
NULL;
END LOOP;
CLOSE p_cursor;
END test2;
END my_test;
/
您可以使用OPEN FOR语法将查询(及其结果集)与变量相关联。然后可以使用通常的操作获取、关闭对%游标属性的引用
并在完成后关闭光标。:-) 定义一个记录类型以匹配要执行的查询的投影。您可以使用它来定义
test3()
的IN参数
定义一个返回此记录类型的ref游标。您可以使用它来定义test2()
的IN参数
不是游标,而是定义返回由该游标类型定义的ref游标的函数
因此,您的软件包如下所示:
create or replace package my_test as
type t_record is record(
column1 mytable.column1%type
,column2 mytable.column2%type
);
type t_cursor is ref cursor return t_record;
function my_cursor (my_filter NUMBER) return t_cursor ;
function my_cursor2(my_filter VARCHAR2) return t_cursor ;
procedure test1;
procedure test2(p_cursor t_cursor);
function test3(test_record t_record) return number;
end my_test;
/
实现如下所示(通过一些输出使演示更易于理解):
我说的是演示吗?当然有。不仅有(真正的)快速响应,还有演示。谢谢!
create or replace package body my_test as
function my_cursor(my_filter NUMBER) return t_cursor is
rc sys_refcursor;
begin
open rc for select column1, column2 from mytable where column3 = my_filter;
return rc;
end my_cursor;
function my_cursor2(my_filter VARCHAR2) return t_cursor is
rc sys_refcursor;
begin
open rc for select column1, column2 from mytable where column4 LIKE my_filter;
return rc;
end my_cursor2;
procedure test1 is
begin
dbms_output.put_line('test2(my_cursor, 3)');
test2(my_cursor(3));
dbms_output.put_line('test2(my_cursor2, foo');
test2(my_cursor2('foo%'));
dbms_output.put_line('test2(my_cursor,5)');
test2(my_cursor(5));
-- ...
end test1;
procedure test2(p_cursor t_cursor) is
tmp number;
l_rec t_record;
begin
loop
fetch p_cursor into l_rec;
exit when p_cursor%notfound;
--some actions
tmp := test3(l_rec);
dbms_output.put_line(l_rec.column1 ||'+'||l_rec.column2||'='||tmp);
--some actions
end loop;
close p_cursor;
end test2;
function test3(test_record t_record) return number is
tmp_sum number;
begin
-- ...
tmp_sum := test_record.column1 + test_record.column2;
-- ...
return tmp_sum;
end test3;
end my_test;
/