PL/SQL 打印出存储过程返回的引用游标
Posted
技术标签:
【中文标题】PL/SQL 打印出存储过程返回的引用游标【英文标题】:PL/SQL print out ref cursor returned by a stored procedure 【发布时间】:2011-08-14 21:37:17 【问题描述】:如何从存储过程(OUT 变量)返回的引用游标中获取数据并将结果行打印到 SQL*PLUS 中的 STDOUT?
ORACLE 存储过程:
PROCEDURE GetGrantListByPI(p_firstname IN VARCHAR2, p_lastname IN VARCHAR2,
p_orderby IN VARCHAR2, p_cursor OUT grantcur);
PL/SQL:
SET SERVEROUTPUT ON;
DECLARE
TYPE r_cursor IS REF CURSOR;
refCursor r_cursor;
CURSOR grantCursor IS
SELECT last_name, first_name
FROM ten_year_pis
WHERE year_added = 2010;
last_name VARCHAR2(100);
first_name VARCHAR2(100);
BEGIN
OPEN grantCursor;
FETCH grantCursor INTO last_name, first_name;
WHILE grantCursor%FOUND LOOP
PMAWEB_PKG.GetGrantListByPI(last_name, first_name, 'last_name', refCursor);
--HOW DO I LOOP THROUGH THE RETURNED REF CURSOR (refCursor)
--AND PRINT THE RESULTING ROWS TO STDOUT?
FETCH grantCursor into last_name, first_name;
END LOOP;
CLOSE grantCursor;
END;
/
【问题讨论】:
【参考方案1】:注意:此代码未经测试
为您的 refCursor 返回类型定义一条记录,称为rec。例如:
TYPE MyRec IS RECORD (col1 VARCHAR2(10), col2 VARCHAR2(20), ...); --define the record
rec MyRec; -- instantiate the record
一旦你从你的过程中返回了 refcursor,你就可以在你的 cmets 所在的位置添加以下代码:
LOOP
FETCH refCursor INTO rec;
EXIT WHEN refCursor%NOTFOUND;
dbms_output.put_line(rec.col1||','||rec.col2||','||...);
END LOOP;
【讨论】:
问题是存储过程返回一个引用游标作为两个表之间连接的结果。如何引用连接表的返回类型? 您需要了解光标中的类型和大小才能理解它。使用联接中的字段定义记录,并将行提取到记录中。 感谢@DCookie,但如果我必须从每一行中只读取一列,那么我能做什么。我需要创建整个结构吗? 您必须创建记录类型以镜像您选择的数据。 请注意,您需要在 SQL Developer 中声明的顶部添加此行:SET SERVEROUTPUT ON【参考方案2】:您可以在 SQLPlus 级别使用绑定变量来执行此操作。当然,您几乎无法控制输出的格式。
VAR x REFCURSOR;
EXEC GetGrantListByPI(args, :x);
PRINT x;
【讨论】:
你知道如何在一个过程中应用同样的逻辑吗?我需要它作为 ETL 工具(Pentaho 数据集成) @YorfrankBastidas 你看过上面的答案了吗 - ***.com/a/5822771/6568?这讨论了在 PL/SQL 代码中使用 refcursor。【参考方案3】:如果要打印 select 子句中的所有列,可以使用 autoprint 命令。
CREATE OR REPLACE PROCEDURE sps_detail_dtest(v_refcur OUT sys_refcursor)
AS
BEGIN
OPEN v_refcur FOR 'select * from dummy_table';
END;
SET autoprint on;
--calling the procedure
VAR vcur refcursor;
DECLARE
BEGIN
sps_detail_dtest(vrefcur=>:vcur);
END;
希望这能给你一个替代解决方案
【讨论】:
【参考方案4】:更简单的选择是使用 DBMS_SQL.return_result();
假设您的包/过程/游标规格如下。
create or replace PACKAGE my_package IS
TYPE my_ref_cursor_type IS REF CURSOR;
PROCEDURE my_procedure (
p_in_param1 IN VARCHAR2,
p_in_param2 IN VARCHAR2,
p_in_param3 IN VARCHAR2,
p_my_ref_cursor OUT my_ref_cursor_type,
p_err_code OUT NUMBER,
p_err_msg OUT VARCHAR2
);
END my_package;
尝试从您的 sql 开发人员 WORKSHEET 中调用该过程
SET SERVEROUTPUT ON;
DECLARE
P_MY_REF_CURSOR my_schema.my_package.my_ref_cursor_type;
P_ERR_CODE NUMBER;
P_ERR_MSG VARCHAR2(200);
BEGIN
my_package.my_procedure(
'VALUE1',
'VALUE2',
'VALUE3',
P_MY_REF_CURSOR => P_MY_REF_CURSOR,
P_ERR_CODE => P_ERR_CODE,
P_ERR_MSG => P_ERR_MSG
);
DBMS_OUTPUT.PUT_LINE(P_ERR_MSG);
DBMS_OUTPUT.PUT_LINE(P_ERR_CODE);
DBMS_SQL.return_result(P_MY_REF_CURSOR);
END;
希望这会有所帮助!
【讨论】:
以上是关于PL/SQL 打印出存储过程返回的引用游标的主要内容,如果未能解决你的问题,请参考以下文章