Oracle PL/SQL 将游标(来自函数)中的每个值一一分配给另一个游标
Posted
技术标签:
【中文标题】Oracle PL/SQL 将游标(来自函数)中的每个值一一分配给另一个游标【英文标题】:Oracle PL/SQL Assign each value from a cursor(from function) to another cursor one by one 【发布时间】:2017-09-05 17:31:00 【问题描述】:我有一个名为 GET_CLIENT_IN_SED(return sys_refcursor) 的函数,它给了我一个 id 编号列表(单列)。现在,在一个过程中,我试图循环遍历每个(一个接一个)这些值并将其用于调用第二个过程(它需要一个客户端 id 参数)。
PROCEDURE GET_ORDINARY_CLIENT;
PROCEDURE GET_ORDINARY_CLIENT_BY_SED
( sed_in IN varchar2, client_sed OUT SYS_REFCURSOR )
IS
ordinary_clients sys_refcursor;
BEGIN
ordinary_clients := GET_CLIENT_IN_SED(sed_in);
for item in ordinary_clients loop
client_sed := client_sed + ordinary_clients(i);
end loop;
END;
【问题讨论】:
【参考方案1】:据我所知,您需要执行以下操作:
功能:
此函数将输入作为数字并返回一个引用。与您的要求类似。
CREATE OR REPLACE FUNCTION get_num_sysrefcur (num IN NUMBER)
RETURN SYS_REFCURSOR
AS
my_cursor SYS_REFCURSOR;
BEGIN
--
OPEN my_cursor FOR
WITH ntable
AS (SELECT 1 ID, 111 AGT, 'ABC' DESCRIP FROM DUAL
UNION ALL
SELECT 2 ID, 222 AGT, 'ABC' DESCRIP FROM DUAL
UNION ALL
SELECT 1 ID, 333 AGT, 'ABC' DESCRIP FROM DUAL)
SELECT AGT FROM ntable WHERE ID = num;
RETURN my_cursor;
END;
/
阻止(在您的情况下是程序) -- 这个匿名块将遍历从 sys_refcursor 返回的记录。类似于您希望第二个过程在哪里使用 sys_refcursor 的值并循环它(您可以创建过程来代替这个匿名块)。
DECLARE
a NUMBER := 1;
TYPE ta IS TABLE OF NUMBER
INDEX BY PLS_INTEGER;
b ta;
x SYS_REFCURSOR;
BEGIN
x := get_num_sysrefcur (a);
fetch x bulk collect into b;
for i in 1..b.count
loop
-- Displaying the result of the ref_cursor.
DBMS_OUTPUT.put_line (b(i));
end loop;
END;
【讨论】:
批量收集是我喜欢使用的另一种有效方法(我发现使用集合比使用光标简单得多!)。虽然当数据量很大时最好不要使用,因为它存储在变量而不是迭代器中。 @Dessma 您也可以使用批量收集进行迭代。您有限制子句来限制 1 go 中的数据选择,您可以遍历所有记录【参考方案2】:遍历引用游标不像遍历数组或表,这解释了为什么您的 FOR...LOOP 不起作用。
简而言之,ref_cursor 更像是集合上的“指针”或“迭代器”,而不是集合。在另一个问题中,您将找到一个使用 FETCH 迭代 ref_cursor 的非常清晰的示例。
How to use record to loop a ref cursor?
您的数据示例如下所示:
PROCEDURE GET_ORDINARY_CLIENT_BY_SED(sed_in IN VARCHAR2,
client_sed OUT SYS_REFCURSOR) IS
ordinary_clients SYS_REFCURSOR;
clt NUMBER; -- assuming your cursor contains strictly numbers
BEGIN
ordinary_clients := GET_CLIENT_IN_SED(sed_in);
LOOP
FETCH ordinary_clients
INTO clt;
EXIT WHEN ordinary_clients%NOTFOUND;
dbms_output.put_line(clt);
-- do some other things here with your number
END LOOP;
END;
【讨论】:
我不想从表中加载,我想从 sys_refcursor 返回函数中加载,因为我没有存储在任何表中的值,只是有关如何获取值的说明。所以我不能使用 table_name%ROWTYPE 抱歉,我假设您的ordinary_client
游标包含“复杂”类型,例如表格行。如果您的 refcursor 只包含简单的数据,例如数字,您可以 FETCH 到适当类型的简单变量中,并以相同的逻辑使用它们。我将使用其他信息编辑我的答案。以上是关于Oracle PL/SQL 将游标(来自函数)中的每个值一一分配给另一个游标的主要内容,如果未能解决你的问题,请参考以下文章