Oracle 11g View resultset of table from Stored procedure in Toad - oracle

I am a novice to Oracle 11g and would like to view the resultset of a table output from a stored procedure. I have created the procedure and executed it. I just want to view the output in the form of a grid like in SQL Server. Please help me out.
This is the declaration of my procedure:
Spec:
TYPE ret_cursor IS REF CURSOR;
procedure get_data(
p_start_dt in varchar2,
p_end_dt in varchar2,
p_results out ret_cursor,
p_err_no out number,
p_err_msg out varchar2
);
Body:
PROCEDURE get_data(
p_start_dt IN VARCHAR2,
p_end_dt IN VARCHAR2,
p_results OUT ret_cursor,
p_err_no OUT NUMBER,
p_err_msg OUT VARCHAR2
)

IF you are using TOAD ,then its very easy to see output of refcursor .
First copy below code in Toad Editor
DECLARE
v_err_no number;
v_err_msg VARCHAR2(200);
BEGIN
get_data(
p_start_dt => SYSDATE, --depend on you
p_end_dt => SYSDATE+10, --depend on you
p_results => :ret_cursor,
p_err_no => v_err_no,
p_err_msg => v_err_msg
);
--print error message
END;
Now goto Editor-->Execute Statement f9 ,and click
Popup appear ,and asking you for ret_cursor type,select type as cursor ,do as shown below in the screenshot
Click OK ,and then you can see result in the datagrid .

If you want simply look at the result you can use SQL*Plus and it's REFCURSOR bind variable and PRINT command:
SQL> create or replace procedure p
2 (
3 x out sys_refcursor
4 )
5 is
6 begin
7 open x for select 1 a, 'a' b from dual;
8 end;
9 /
Procedure created.
SQL> var rc refcursor
SQL> exec p(:rc)
PL/SQL procedure completed.
SQL> print rc
A B
---------- -
1 a

Related

ORACLE - can i pass cursor in a parameter and how to use it?

Here is one of oracle procedure. There is a cursor called r_ba.
DECLARE
r_ba SYS_REFCURSOR;
BEGIN
OPEN r_ba FOR
SELECT head.*,
line.jenis_pekerjaan,
line.deskripsi_pekerjaan,
line.akun,
line.rate_ppn,
line.dpp,
line.ppn,
line.total_realisasi,
line.major,
line.minor,
line.sla
FROM idm_ap_mtc_acl_header_tmp head, idm_ap_mtc_acl_lines_tmp line
WHERE head.no_ba = line.no_ba AND head.req_id = line.req_id AND head.req_id = n_req_id;
create_invoice_ap2 (
p_org_id => p_org_id,
p_user_id => p_user_id,
p_branch_code => v_branch_code,
r_ba => r_ba);
END;
and how call that cursor in this procedure ?
PROCEDURE create_invoice_ap2 (p_org_id IN NUMBER,
p_user_id IN NUMBER,
p_branch_code IN VARCHAR2,
r_ba IN SYS_REFCURSOR)
IS
r_tax_info rt_tax_info;
rt_ba SYS_REFCURSOR;
BEGIN
------------ setup ------------
r_tax_info := get_tax_code (
p_date => rt_ba.tgl_ba,
p_group_tax_name => rt_ba.tax_name,
p_ppn_rate => rt_ba.ppn_rate,
p_dc_code => rt_ba.dc_code);
END;
oracle give me error
[Error] PLS-00487 (707: 64): PLS-00487: Invalid reference to variable 'RT_BA'
Anyone could suggest me a way to accomplish this?
Thanks
If you're passing refcursor into a parameter named r_ba, then - I believe - you should use it, not declare another (rt_ba):
PROCEDURE create_invoice_ap2 (p_org_id IN NUMBER,
p_user_id IN NUMBER,
p_branch_code IN VARCHAR2,
r_ba IN SYS_REFCURSOR)
IS
r_tax_info rt_tax_info;
-- rt_ba SYS_REFCURSOR; --> you don't need it
BEGIN
------------ setup ------------
r_tax_info := get_tax_code (
p_date => r_ba.tgl_ba,
p_group_tax_name => r_ba.tax_name,
p_ppn_rate => r_ba.ppn_rate,
p_dc_code => r_ba.dc_code);
END; ----
^
|
r_ba, not rt_ba
Also, note that you should generally avoid select * because it can lead to ambiguity if there are columns with the same name as columns in other tables, so Oracle doesn't know which one you want to use.
The same goes for typos; for example, in anonymous PL/SQL block you're selecting line.rate_ppn, while procedure uses p_ppn_rate => r_ba.ppn_rate (rate_ppn vs. ppn_rate). Maybe it is OK because there's ppn_rate column in head table (which is in select head.*) but - once again - that's difficult to debug.
Furthermore, you can't use refcursor that way - you have to fetch from it. Have a look at example based on Scott's sample schema. Here's a procedure that accepts refcursor as a parameter and does something with it:
SQL> create or replace procedure p_test (r_ba in sys_refcursor)
2 is
3 l_dname varchar2(20);
4 begin
5 l_dname := r_ba.dname;
6 end;
7 /
Warning: Procedure created with compilation errors.
SQL> show err
Errors for PROCEDURE P_TEST:
LINE/COL ERROR
-------- -----------------------------------------------------------------
5/3 PL/SQL: Statement ignored
5/19 PLS-00487: Invalid reference to variable 'R_BA'
SQL>
See? The same error you got. Therefore, fetch:
SQL> create or replace procedure p_test (r_ba in sys_refcursor)
2 is
3 l_row dept%rowtype;
4 begin
5 loop
6 fetch r_ba into l_row;
7 exit when r_ba%notfound;
8 dbms_output.put_line(l_row.deptno ||', '|| l_row.dname ||', '|| l_row.loc);
9 end loop;
10 end;
11 /
Procedure created.
SQL> declare
2 r_ba sys_refcursor;
3 begin
4 open r_ba for select deptno, dname, loc from dept;
5 p_test (r_ba);
6 end;
7 /
10, ACCOUNTING, NEW YORK
20, RESEARCH, DALLAS
30, SALES, CHICAGO
40, OPERATIONS, BOSTON
PL/SQL procedure successfully completed.
SQL>
Now it is OK.
I don't know what you're doing with r_tax_info, how many rows refcursor contains (whether you need to use a loop or not), but - that's the general idea. Fetch first, use it next.

SQLDeveloper execute procedure with parameters

I'm struggling to find a way to execute a procedure that has a SYS_REFCURSOR
I found different ways and it appears is easier in sqlplus but I wanted to do it through a query in sqldeveloper
The query takes 3 parameters and has a 4th that is a SYS_REFCURSOR
procedure_example(var1 number,var2 varchar2,var3 varchar2,result out sys_refcursor)
How would I execute something like this in SQLDEVELOPER?
As this is a procedure with an OUT parameter, you'll have to use another PL/SQL block which has DECLARE section (so that you'd have "something" to accept what your procedure returns).
declare
l_rc sys_refcursor;
begin
procedure_example(var1 => 1,
var2 => 2,
var3 => 3,
result => l_rc);
end;
/
(You'd pass meaningful values to IN parameters, of course.)
Another option is to declare a variable, use it while executing the procedure and print its contents. For example (based on Scott's sample schema):
The GUI way...using #littlefoot's code:
create or replace procedure p_test(
par_deptno in number,
par_rc out sys_refcursor)
is
begin
open par_rc for
select employee_id,
first_name,
last_name,
job_id,
salary
from employees
where department_id = par_deptno;
end;
Open in the database (or file), and hit the RUN button.
Set the input parameter, then click 'Ok' - the procedure will run, and you can see your refcursor below.

Following procedure gives error using call invoicetest.wj_get_invoicedatatest(1,:InvoicesCur ); call invoicetest.wj_get_invoice_cbodataidstest('X');

I have got error after using call for boyh procedures
CREATE OR REPLACE PACKAGE invoicetest
IS
TYPE InvoiceCBOIDCurs IS REF CURSOR;
TYPE InvoicesCur IS REF CURSOR;
PROCEDURE wj_get_invoice_cbodataidstest
(
InvoiceCBOIDs out InvoiceCBOIDCurs
);
PROCEDURE wj_get_invoicedatatest
(
Invoice out InvoicesCur,
CBOID IN INTEGER
);
END invoicetest;
/
CREATE OR REPLACE PACKAGE BODY invoicetest IS
PROCEDURE wj_get_invoice_cbodataidstest
(
InvoiceCBOIDs out InvoiceCBOIDCurs
)
IS
BEGIN
OPEN InvoiceCBOIDs FOR
Select 1 from dual;
END wj_get_invoice_cbodataidstest;
PROCEDURE wj_get_invoicedatatest
(
Invoice out InvoicesCur,
CBOID IN INTEGER
)as
begin
OPEN Invoice FOR
select cboid from dual;
end wj_get_invoicedatatest;
END invoicetest;
/
Error after call:
invoicetest.wj_get_invoicedatatest(1,:InvoicesCur ); call
invoicetest.wj_get_invoice_cbodataidstest('X');
Your procedures are OK, but you are calling them in a wrong way; in one case you are using parameters in the wrong order, while in the other one you are passing a varchar while the procedure needs a cursor parameter.
This is a correct way to call your procedures:
SQL> declare
2 vCurCBO invoicetest.InvoiceCBOIDCurs;
3 vCur invoicetest.InvoicesCur;
4 begin
5 invoicetest.wj_get_invoicedatatest(vCur, 1);
6 --
7 invoicetest.wj_get_invoice_cbodataidstest(vCurCBO);
8 --
9 /* what you need to do with your cursors */
10 end;
11 /
PL/SQL procedure successfully completed.
SQL>
To avoid confusion, you could pass parameters by explicitly using their names:
...
invoicetest.wj_get_invoicedatatest(
Invoice =>vCur,
CBOID => 1
);
--
invoicetest.wj_get_invoice_cbodataidstest(
InvoiceCBOIDs => vCurCBO
);
...
If you need to use the CALL:
SQL> VARIABLE vCurCBO REFCURSOR;
SQL> VARIABLE vCur REFCURSOR;
SQL> CALL invoicetest.wj_get_invoice_cbodataidstest(
2 InvoiceCBOIDs => :vCurCBO
3 );
Call completed.
SQL> CALL invoicetest.wj_get_invoicedatatest(
2 Invoice =>:vCur,
3 CBOID => 1
4 );
Call completed.
SQL>

SQL Developer Oracle, how to call procedure? [duplicate]

This question already has answers here:
Calling a stored PROCEDURE in Toad
(2 answers)
Closed 7 years ago.
I have delcared function like this:
CREATE or replace PROCEDURE proc
(
P_ID IN INTEGER,
NAME OUT CHAR,
SURNAME OUT CHAR,
TOTAL OUT CHAR
)
AS
BEGIN
SELECT NAME, SURNAME, sum(TOTAL) AS TOT
INTO NAME,SURNAME,TOTAL
FROM STATISTICS, PLAYERS, PERSON
WHERE STATISTICS.SID=P_ID AND PERSON.ID=PLAYERS.SID AND
STATISTICS.PLAYERS_SID=PLAYERS.SID
GROUP BY NAME,SURNAME;
END;
Select statement works corectly, but how to call this procedure in Oracle?
I tried something like
EXEC proc(4);
AND
DECLARE
NAME OUT CHAR,
SURNAME OUT CHAR,
TOTAL OUT CHAR
BEGIN
P_ID := 12 ;
proc (
P_ID => P_ID,
NAME => NAME,
SURNAME => SURNAME,
TOTAL => TOTAL
);
END;
but without any success.
EXEC proc(4);
EXECUTE is a SQL*Plus command.
You have following options:
EXECUTE in SQL*Plus
Call it in an anonymous PL/SQL block.
Run in SQL Developer client tool
Let's see all the three ways:
In SQL*Plus:
SQL> variable v_ename varchar2(20);
SQL> exec get_emp(7788, :v_ename);
PL/SQL procedure successfully completed.
SQL> print v_ename;
V_ENAME
--------------------------------
SCOTT
In an anonymous PL/SQL block:
SQL> CREATE OR REPLACE PROCEDURE get_emp(
2 i_empno IN emp.empno%TYPE,
3 o_ename OUT emp.ename%TYPE)
4 AS
5 BEGIN
6 SELECT ename INTO o_ename FROM emp WHERE empno = i_empno;
7 END;
8 /
Procedure created.
SQL> SET serveroutput ON
SQL> DECLARE
2 v_ename VARCHAR2(20);
3 BEGIN
4 get_emp(7788, v_ename);
5 dbms_output.put_line('Employee name is '||v_ename);
6 END;
7 /
Employee name is SCOTT
PL/SQL procedure successfully completed.
In SQL Developer client tool:
Go to connections on the left pane.
Expand the Procedures.
Right click on the procedure and select "Run".
It will open a new window, provide the Input value and click OK.
The output will be shown in Output Log at the bottom as "Output Variables".

Oracle procedure input is comma delimited, not returning any values

the procedure Im working has an input variable that is comma delimited. As of right now when I go to run a test script, I dont get any values back. Here is what I have so far.
procedure get_patient(
p_statusmnemonic_in in membermedicalreconcilationhdr.reconciliationstatusmnemonic%type,
p_return_cur_out out sys_refcursor,
p_err_code_out out number,
p_err_mesg_out out varchar2)
is
begin
open p_return_cur_out for
select h.primarymemberplanid,
h.assigneduserid,
h.accountorgid,
h.reconciliationstatusmnemonic,
h.estimatedenddt,
h.actualenddt,
h.inserteddt,
h.insertedby,
h.updateddt,
h.updatedby
from membermedicalreconcilationhdr h
where h.reconciliationstatusmnemonic in (p_statusmnemonic_in);
p_err_code_out := 0;
exception
when others then
p_err_code_out := -1;
p_err_mesg_out := 'error in get_patient=> ' || sqlerrm;
end get_patient;
Here is the test script:
set serveroutput on
declare
type tempcursor is ref cursor;
v_cur_result tempcursor;
errcode number;
errmesg varchar2(1000);
p_primarymemberplanid_in membermedicalreconcilationhdr.primarymemberplanid%type;
p_assigneduserid_in membermedicalreconcilationhdr.assigneduserid%type;
p_accountorgid_in membermedicalreconcilationhdr.accountorgid%type;
p_reconstatusmnemonic_in membermedicalreconcilationhdr.reconciliationstatusmnemonic%type;
p_estimatedenddt_in membermedicalreconcilationhdr.estimatedenddt%type;
p_actualenddt_in membermedicalreconcilationhdr.actualenddt%type;
p_inserteddate_in membermedicalreconcilationhdr.inserteddt%type;
p_insertedby_in membermedicalreconcilationhdr.insertedby%type;
p_updateddate_in membermedicalreconcilationhdr.updateddt%type;
p_updatedby_in membermedicalreconcilationhdr.updatedby%type;
begin
get_patient
('COMPLETE,SUSPENDED_PRIOR_TO_COMPARE',v_cur_result, errcode, errmesg);
--('COMPLETE',v_cur_result, errcode, errmesg);
loop
fetch v_cur_result into p_primarymemberplanid_in,p_assigneduserid_in,p_accountorgid_in,p_reconstatusmnemonic_in,
p_estimatedenddt_in,p_actualenddt_in,p_inserteddate_in,p_insertedby_in,
p_updateddate_in,p_updatedby_in;
dbms_output.put_line(' planid '||p_primarymemberplanid_in||' userid '||p_assigneduserid_in);
exit when v_cur_result%notfound;
end loop;
dbms_output.put_line(' error code '||errcode||' message '||errmesg);
end;
As of right now I get values back when I just have one input value, but when I try to do two I dont get anything. Ive done research and it looks like my select statement is correct so Im at a loss as to what Im doing wrong. Any help is appreciated, thanks.
If you can change the definition of the procedure, you are better served passing in a proper collection.
CREATE TYPE status_tbl IS TABLE OF VARCHAR2(100);
procedure get_patient(
p_statusmnemonic_in in status_tbl,
p_return_cur_out out sys_refcursor,
p_err_code_out out number,
p_err_mesg_out out varchar2)
is
begin
open p_return_cur_out for
select h.primarymemberplanid,
h.assigneduserid,
h.accountorgid,
h.reconciliationstatusmnemonic,
h.estimatedenddt,
h.actualenddt,
h.inserteddt,
h.insertedby,
h.updateddt,
h.updatedby
from membermedicalreconcilationhdr h
where h.reconciliationstatusmnemonic in (SELECT *
FROM TABLE(p_statusmnemonic_in));
...
Otherwise, you would either have to resort to using dynamic SQL (which would have security and performance implications) or you would need to write code to parse the comma-separated string into a collection and then use the TABLE operator to use that collection in the query.
Assuming you modify the signature of the procedure, the call will also have to change so that you are passing in a collection.
get_patient
(status_tbl('COMPLETE','SUSPENDED_PRIOR_TO_COMPARE'),
v_cur_result,
errcode,
errmesg);
And just to point it out, writing procedures that have error code and error message OUT parameters rather than throwing exceptions is generally highly frowned upon. It makes far more sense to eliminate those parameters and to just throw exceptions when you encounter an error. Otherwise, you are relying on every caller to every procedure to correctly check the returned status code and message (which your sample code does not do). And you are losing a ton of valuable information about things like exactly what line an error occurred on, what the error stack was, etc.
Since you don't post your table definitions or your sample data, it is impossible for us to test this code. Here is a quick demonstration, though, of how it would work
SQL> create table patient (
2 patient_id number primary key,
3 status varchar2(10),
4 name varchar2(100)
5 );
Table created.
SQL> insert into patient values( 1, 'COMPLETE', 'Justin' );
1 row created.
SQL> insert into patient values( 2, 'SUSPENDED', 'Bob' );
1 row created.
SQL> insert into patient values( 3, 'NEW', 'Kerry' );
1 row created.
SQL> commit;
Commit complete.
SQL> CREATE TYPE status_tbl IS TABLE OF VARCHAR2(100);
2 /
Type created.
SQL> ed
Wrote file afiedt.buf
1 create or replace procedure get_patients( p_statuses in status_tbl,
2 p_cursor out sys_refcursor )
3 as
4 begin
5 open p_cursor
6 for select *
7 from patient
8 where status in (select *
9 from table( p_statuses ));
10* end;
SQL> /
Procedure created.
SQL> variable rc refcursor;
SQL> exec get_patients( status_tbl('COMPLETE', 'SUSPENDED'), :rc );
PL/SQL procedure successfully completed.
SQL> print rc;
PATIENT_ID STATUS
---------- ----------
NAME
--------------------------------------------------------------------------------
1 COMPLETE
Justin
2 SUSPENDED
Bob

Resources