I'm working on converting a stored procedure from SQL server to Oracle. This stored procedure provides a direct resultset. I mean that if you call the stored procedure in eg Management Studio you directly obtain the resultset.
我正在努力将存储过程从SQL服务器转换为Oracle。此存储过程提供直接结果集。我的意思是,如果您在例如Management Studio中调用存储过程,则直接获取结果集。
By converting to Oracle I walk against the problem that I in Oracle will not display the resultset
通过转换为Oracle,我可以解决Oracle中不显示结果集的问题
I searched on the Internet and have seen that the stored procedure should yield a REF CURSOR, but I still walk with the problem to write a little piece of code to obtain the resultset en process that.
我在互联网上搜索并看到存储过程应该产生一个REF CURSOR,但我仍然在解决问题,编写一小段代码来获得结果集。
Pseudo Code:
Call stored procedure and obtain cursor Do something with that cursor so that my resultset appears
调用存储过程并获取游标使用该游标执行某些操作,以便显示我的结果集
Someone an idea?
有人有想法吗?
5 个解决方案
#1
In SQL Plus:
在SQL Plus中:
SQL> create procedure myproc (prc out sys_refcursor)
2 is
3 begin
4 open prc for select * from emp;
5 end;
6 /
Procedure created.
SQL> var rc refcursor
SQL> execute myproc(:rc)
PL/SQL procedure successfully completed.
SQL> print rc
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- ----------- ---------- ---------- ----------
7839 KING PRESIDENT 17-NOV-1981 4999 10
7698 BLAKE MANAGER 7839 01-MAY-1981 2849 30
7782 CLARKE MANAGER 7839 09-JUN-1981 2449 10
7566 JONES MANAGER 7839 02-APR-1981 2974 20
7788 SCOTT ANALYST 7566 09-DEC-1982 2999 20
7902 FORD ANALYST 7566 03-DEC-1981 2999 20
7369 SMITHY CLERK 7902 17-DEC-1980 9988 11 20
7499 ALLEN SALESMAN 7698 20-FEB-1981 1599 3009 30
7521 WARDS SALESMAN 7698 22-FEB-1981 1249 551 30
7654 MARTIN SALESMAN 7698 28-SEP-1981 1249 1400 30
7844 TURNER SALESMAN 7698 08-SEP-1981 1499 0 30
7876 ADAMS CLERK 7788 12-JAN-1983 1099 20
7900 JAMES CLERK 7698 03-DEC-1981 949 30
7934 MILLER CLERK 7782 23-JAN-1982 1299 10
6668 Umberto CLERK 7566 11-JUN-2009 19999 0 10
9567 ALLBRIGHT ANALYST 7788 02-JUN-2009 76999 24 10
#2
Oracle is not sql server. Try the following in SQL Developer
Oracle不是sql server。在SQL Developer中尝试以下操作
variable rc refcursor;
exec testproc(:rc2);
print rc2
#3
In SQL Plus:
在SQL Plus中:
SQL> var r refcursor
SQL> set autoprint on
SQL> exec :r := function_returning_refcursor();
Replace the last line with a call to your procedure / function and the contents of the refcursor will be displayed
通过调用过程/函数替换最后一行,将显示refcursor的内容
#4
Hi I know this was asked a while ago but I've just figured this out and it might help someone else. Not sure if this is exactly what you're looking for but this is how I call a stored proc and view the output using SQL Developer.
In SQL Developer when viewing the proc, right click and choose 'Run' or select Ctrl+F11 to bring up the Run PL/SQL window. This creates a template with the input and output params which you need to modify. My proc returns a sys_refcursor. The tricky part for me was declaring a row type that is exactly equivalent to the select stmt / sys_refcursor being returned by the proc:
嗨,我知道这是前一段时间被问到的,但我只是想出来了,这可能对其他人有所帮助。不确定这是否正是您正在寻找的,但这是我如何调用存储过程并使用SQL Developer查看输出。在SQL Developer中查看proc时,右键单击并选择“Run”或选择Ctrl + F11以显示“运行PL / SQL”窗口。这将创建一个模板,其中包含您需要修改的输入和输出参数。我的proc返回一个sys_refcursor。对我来说棘手的部分是声明一个行类型,它完全等同于proc返回的select stmt / sys_refcursor:
DECLARE
P_CAE_SEC_ID_N NUMBER;
P_FM_SEC_CODE_C VARCHAR2(200);
P_PAGE_INDEX NUMBER;
P_PAGE_SIZE NUMBER;
v_Return sys_refcursor;
type t_row is record (CAE_SEC_ID NUMBER,FM_SEC_CODE VARCHAR2(7),rownum number, v_total_count number);
v_rec t_row;
BEGIN
P_CAE_SEC_ID_N := NULL;
P_FM_SEC_CODE_C := NULL;
P_PAGE_INDEX := 0;
P_PAGE_SIZE := 25;
CAE_FOF_SECURITY_PKG.GET_LIST_FOF_SECURITY(
P_CAE_SEC_ID_N => P_CAE_SEC_ID_N,
P_FM_SEC_CODE_C => P_FM_SEC_CODE_C,
P_PAGE_INDEX => P_PAGE_INDEX,
P_PAGE_SIZE => P_PAGE_SIZE,
P_FOF_SEC_REFCUR => v_Return
);
-- Modify the code to output the variable
-- DBMS_OUTPUT.PUT_LINE('P_FOF_SEC_REFCUR = ');
loop
fetch v_Return into v_rec;
exit when v_Return%notfound;
DBMS_OUTPUT.PUT_LINE('sec_id = ' || v_rec.CAE_SEC_ID || 'sec code = ' ||v_rec.FM_SEC_CODE);
end loop;
END;
#5
My solution was to create a pipelined function. The advantages are that the query can be a single line:
我的解决方案是创建一个流水线功能。优点是查询可以是单行:
select * from table(yourfunction(param1, param2));
- You can join your results to other tables or filter or sort them as you please..
- the results appear as regular query results so you can easily manipulate them.
select * from table(yourfunction(param1,param2));
您可以将结果加入其他表格,也可以根据需要对其进行过滤或排序。
结果显示为常规查询结果,因此您可以轻松地操作它们。
To define the function you would need to do something like the following:
要定义函数,您需要执行以下操作:
-- Declare the record columns
TYPE your_record IS RECORD(
my_col1 VARCHAR2(50),
my_col2 varchar2(4000)
);
TYPE your_results IS TABLE OF your_record;
-- Declare the function
function yourfunction(a_Param1 varchar2, a_Param2 varchar2)
return your_results pipelined is
rt your_results;
begin
-- Your query to load the table type
select s.col1,s.col2
bulk collect into rt
from your_table s
where lower(s.col1) like lower('%'||a_Param1||'%');
-- Stuff the results into the pipeline..
if rt.count > 0 then
for i in rt.FIRST .. rt.LAST loop
pipe row (rt(i));
end loop;
end if;
-- Add more results as you please....
return;
end find;
And as mentioned above, all you would do to view your results is:
如上所述,您只需查看结果即可:
select * from table(yourfunction(param1, param2)) t order by t.my_col1;
#1
In SQL Plus:
在SQL Plus中:
SQL> create procedure myproc (prc out sys_refcursor)
2 is
3 begin
4 open prc for select * from emp;
5 end;
6 /
Procedure created.
SQL> var rc refcursor
SQL> execute myproc(:rc)
PL/SQL procedure successfully completed.
SQL> print rc
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- ----------- ---------- ---------- ----------
7839 KING PRESIDENT 17-NOV-1981 4999 10
7698 BLAKE MANAGER 7839 01-MAY-1981 2849 30
7782 CLARKE MANAGER 7839 09-JUN-1981 2449 10
7566 JONES MANAGER 7839 02-APR-1981 2974 20
7788 SCOTT ANALYST 7566 09-DEC-1982 2999 20
7902 FORD ANALYST 7566 03-DEC-1981 2999 20
7369 SMITHY CLERK 7902 17-DEC-1980 9988 11 20
7499 ALLEN SALESMAN 7698 20-FEB-1981 1599 3009 30
7521 WARDS SALESMAN 7698 22-FEB-1981 1249 551 30
7654 MARTIN SALESMAN 7698 28-SEP-1981 1249 1400 30
7844 TURNER SALESMAN 7698 08-SEP-1981 1499 0 30
7876 ADAMS CLERK 7788 12-JAN-1983 1099 20
7900 JAMES CLERK 7698 03-DEC-1981 949 30
7934 MILLER CLERK 7782 23-JAN-1982 1299 10
6668 Umberto CLERK 7566 11-JUN-2009 19999 0 10
9567 ALLBRIGHT ANALYST 7788 02-JUN-2009 76999 24 10
#2
Oracle is not sql server. Try the following in SQL Developer
Oracle不是sql server。在SQL Developer中尝试以下操作
variable rc refcursor;
exec testproc(:rc2);
print rc2
#3
In SQL Plus:
在SQL Plus中:
SQL> var r refcursor
SQL> set autoprint on
SQL> exec :r := function_returning_refcursor();
Replace the last line with a call to your procedure / function and the contents of the refcursor will be displayed
通过调用过程/函数替换最后一行,将显示refcursor的内容
#4
Hi I know this was asked a while ago but I've just figured this out and it might help someone else. Not sure if this is exactly what you're looking for but this is how I call a stored proc and view the output using SQL Developer.
In SQL Developer when viewing the proc, right click and choose 'Run' or select Ctrl+F11 to bring up the Run PL/SQL window. This creates a template with the input and output params which you need to modify. My proc returns a sys_refcursor. The tricky part for me was declaring a row type that is exactly equivalent to the select stmt / sys_refcursor being returned by the proc:
嗨,我知道这是前一段时间被问到的,但我只是想出来了,这可能对其他人有所帮助。不确定这是否正是您正在寻找的,但这是我如何调用存储过程并使用SQL Developer查看输出。在SQL Developer中查看proc时,右键单击并选择“Run”或选择Ctrl + F11以显示“运行PL / SQL”窗口。这将创建一个模板,其中包含您需要修改的输入和输出参数。我的proc返回一个sys_refcursor。对我来说棘手的部分是声明一个行类型,它完全等同于proc返回的select stmt / sys_refcursor:
DECLARE
P_CAE_SEC_ID_N NUMBER;
P_FM_SEC_CODE_C VARCHAR2(200);
P_PAGE_INDEX NUMBER;
P_PAGE_SIZE NUMBER;
v_Return sys_refcursor;
type t_row is record (CAE_SEC_ID NUMBER,FM_SEC_CODE VARCHAR2(7),rownum number, v_total_count number);
v_rec t_row;
BEGIN
P_CAE_SEC_ID_N := NULL;
P_FM_SEC_CODE_C := NULL;
P_PAGE_INDEX := 0;
P_PAGE_SIZE := 25;
CAE_FOF_SECURITY_PKG.GET_LIST_FOF_SECURITY(
P_CAE_SEC_ID_N => P_CAE_SEC_ID_N,
P_FM_SEC_CODE_C => P_FM_SEC_CODE_C,
P_PAGE_INDEX => P_PAGE_INDEX,
P_PAGE_SIZE => P_PAGE_SIZE,
P_FOF_SEC_REFCUR => v_Return
);
-- Modify the code to output the variable
-- DBMS_OUTPUT.PUT_LINE('P_FOF_SEC_REFCUR = ');
loop
fetch v_Return into v_rec;
exit when v_Return%notfound;
DBMS_OUTPUT.PUT_LINE('sec_id = ' || v_rec.CAE_SEC_ID || 'sec code = ' ||v_rec.FM_SEC_CODE);
end loop;
END;
#5
My solution was to create a pipelined function. The advantages are that the query can be a single line:
我的解决方案是创建一个流水线功能。优点是查询可以是单行:
select * from table(yourfunction(param1, param2));
- You can join your results to other tables or filter or sort them as you please..
- the results appear as regular query results so you can easily manipulate them.
select * from table(yourfunction(param1,param2));
您可以将结果加入其他表格,也可以根据需要对其进行过滤或排序。
结果显示为常规查询结果,因此您可以轻松地操作它们。
To define the function you would need to do something like the following:
要定义函数,您需要执行以下操作:
-- Declare the record columns
TYPE your_record IS RECORD(
my_col1 VARCHAR2(50),
my_col2 varchar2(4000)
);
TYPE your_results IS TABLE OF your_record;
-- Declare the function
function yourfunction(a_Param1 varchar2, a_Param2 varchar2)
return your_results pipelined is
rt your_results;
begin
-- Your query to load the table type
select s.col1,s.col2
bulk collect into rt
from your_table s
where lower(s.col1) like lower('%'||a_Param1||'%');
-- Stuff the results into the pipeline..
if rt.count > 0 then
for i in rt.FIRST .. rt.LAST loop
pipe row (rt(i));
end loop;
end if;
-- Add more results as you please....
return;
end find;
And as mentioned above, all you would do to view your results is:
如上所述,您只需查看结果即可:
select * from table(yourfunction(param1, param2)) t order by t.my_col1;