What to pass as a SYS_REFCURSOR argument - oracle

Here I have a stored procedure in Oracle:
CREATE OR REPLACE PROCEDURE StP_COMPS
IS
CV_1 SYS_REFCURSOR;
BEGIN
OPEN CV_1 FOR SELECT * FROM COMPUTERS;
END;
When I execute the procedure like EXEC SP_COMPS I get no error, the SQL Developer just shows "ananymous block completed". Then I change the procedure to a
CREATE OR REPLACE PROCEDURE SP_COMPS
(cv_1 OUT SYS_REFCURSOR)
IS
BEGIN
OPEN CV_1 FOR SELECT * FROM COMPUTERS;
END;
and when I execute I get error stating that the number of type of the arguments are wrong. I'm very curious what I could send as an argument to the procedure if it's just an output parameter. I want to get the result set of the query run inside the procedure. What am I doing wrong here?
P.S. When I try to run the procedure by right clicking the procedure and selecting Run I get:
DECLARE
CV_2 sys_refcursor;
BEGIN
SP_COMPS(
CV_2 => CV_2
);
:CV_2 := CV_2; -- <--Can't understand this part
END;

You have a variable, you should execute the procedure like:
DECLARE
CV_1 SYS_REFCURSOR;
BEGIN
SP_COMPS(CV_1);
--use cv_1
END;
UPDATE(after OP update): That's a simple template for testing. As explained here: Easiest method to test an Oracle Stored Procedure, just run that code, and select ref_cursor as type of cv2 variable.

Related

How to call a stored procedure in pl/sql developer

I am new at this and have a simple question.
I have created a procedure like so in pl/sql developer
CREATE OR REPLACE PROCEDURE myproc2 AS
BEGIN
SELECT cd_desc des, cd_value cd FROM v_codes WHERE cd_type='CVS02'
END;
Now I want to call the procedure and see the output however when I run this
BEGIN
myproc2;
END;
in Pl/sql I am getting an error saying object myproc2 is invalid
How do I call a stored procedure in PL/SQL?
You're calling it right, but the procedure is wrong. If you check its status, it is invalid.
In PL/SQL, a SELECT requires INTO:
CREATE OR REPLACE PROCEDURE myproc2 AS
l_cd_desc v_codes.cd_desc%type;
l_cd_value v_codes.cd_value%type;
BEGIN
SELECT v.cd_desc, v.cd_value
INTO l_cd_desc, l_cd_value
FROM v_codes v
WHERE v.cd_type = 'CVS02';
END;
Beware of possible NO_DATA_FOUND or TOO_MANY_ROWS exception.
Also, although it'll now run OK (I guess), you won't see anything because it is unknown what you'll do next. You could, for example, choose to display values you fetched. In that case, add
<snip>
WHERE v.cd_type = 'CVS02';
dbms_output.put_line(l_cd_desc ||', '|| l_cd_value);
END;
Don't forget to enable serveroutput.
As you commented, you got too_many_rows. How to handle it? It depends on what you want to do. One option is to switch to a cursor FOR loop; now you don't need local variables and - as there's no SELECT statement itself - no INTO clause either:
CREATE OR REPLACE PROCEDURE myproc2
AS
BEGIN
FOR cur_r IN (SELECT v.cd_desc, v.cd_value
FROM v_codes v
WHERE v.cd_type = 'CVS02')
LOOP
DBMS_OUTPUT.put_line (cur_r.cd_desc || ', ' || cur_r.cd_value);
END LOOP;
END;
One great thing about Oracle SQL Developer is the GUI and that it does things for you.
You can open a sheet and run it the traditional way:
BEGIN
PROCEDURENAME(PARAM);
END;
or you can use the GUI, find the object with the (View->) Find DB object, find it, click on it and use the green arrow in the toolbar. It will open a UI for any parameters you used within the procedure.
In SQL Developer, if you want to see the output then you can return a cursor:
CREATE OR REPLACE PROCEDURE myproc2(
o_cursor OUT SYS_REFCURSOR
)
AS
BEGIN
OPEN o_cursor FOR
SELECT cd_desc AS des,
cd_value AS cd
FROM v_codes
WHERE cd_type='CVS02'; -- You need a ; statement terminator here.
END;
/
Then you can use:
-- Declare a cursor bind variable
VARIABLE cur SYS_REFCURSOR;
BEGIN
-- Call the cursor outputting into the bind variable.
myproc2(:cur);
END;
/
-- Print the cursor
PRINT :cur;
And run it as a script (using F5).

How to write an Oracle procedure with a select statement (Specifically on SQL Developer)?

I want to create a simple Oracle Stored procedure on SQL Developer that will return some records on a simple select query. I do not want to pass in any parameter, but I just want the Records to be returned back from the procedure into a result set -> a suitable variable.
I have been trying to use the following syntax :
create or replace PROCEDURE Getmarketdetails2(data OUT varchar2)
IS
BEGIN
SELECT *
into data
from dual;
END Getmarketdetails2;
But it gives me an error while I try to execute with the following exec statement -->
Declare a Varchar2;
exec Getmarketdetails2(a);
Error: PLS-00103: Encountered the symbol "end-of-file" when expecting "something else".
Cause: Usually a PL/SQL compilation error.
Appreciate if anyone can help me out of this long pending situation! I have tried enough to find a basic guide to create a simple Oracle stored procedure and execute it in SQL Developer, but none of them answer to the point!!
You want:
DECLARE
a VARCHAR2(4000); -- Give it a size
BEGIN -- Begin the anonymous PL/SQL block
Getmarketdetails2(a); -- Call the procedure
DBMS_OUTPUT.PUT_LINE( a ); -- Output the value
END; -- End the anonymous PL/SQL block
/ -- End the PL/SQL statement
or:
VARIABLE a VARCHAR2(4000); -- Create a bind variable
EXEC Getmarketdetails2(:a); -- Execute the procedure using the bind variable
PRINT a -- Print the bind variable
Assuming an up-to-date Oracle version, you can use dbms_sql.return_result()
create or replace PROCEDURE Getmarketdetails2
IS
c1 SYS_REFCURSOR;
BEGIN
OPEN c1 FOR
SELECT *
from dual;
DBMS_SQL.RETURN_RESULT(c1);
END Getmarketdetails2;
/
Then simply run
exec Getmarketdetails2
The only drawback is that SQL Developer only displays the result as text, not as a proper result grid.
This is how I return a cursor in Oracle
PROCEDURE GetAllData (P_CURSOR OUT SYS_REFCURSOR)
IS
BEGIN
OPEN P_CURSOR FOR
SELECT *
FROM TABLE ;
END GetAllData ;
Declare a Varchar2;
exec Getmarketdetails2(a);
Your procedure is ok;
Instead of above query, use below query to run sp:
Declare
a Varchar2(10);
Begin
Getmarketdetails2(a);
End;

How can a stored procedure be executed in Oracle with in and out parameters?

Here's my stored procedure:
CREATE OR REPLACE PROCEDURE STATS_SD
(
P_ID IN NUMBER,
PRC OUT SYS_REFCURSOR
)
IS
BEGIN
OPEN PRC FOR
SELECT
ID,
SESID
FROM RESPONSES
WHERE ID IN (P_ID)
END;
When I try to execute it using
EXEC EXAM_STATS_STUDENTS_SD('6901');
I get the following error:
PLS-00306: wrong number or types of arguments in call to 'STATS_SD'
Do you have any ideas why?
Here is an example using an OUT parameter that is a sys_refcursor. Note that I close the cursor in the pl/sql block that uses it (which is important!):
create or replace procedure get_data(o_cur OUT SYS_REFCURSOR) as
begin
OPEN o_cur FOR
select * from emp;
end;
And using the get_data procedure:
declare
l_cur sys_refcursor;
l_row emp%rowtype;
begin
get_data(l_cur);
LOOP
fetch l_cur
into l_row;
exit when l_cur%notfound;
-- do something with l_row here
END LOOP;
close l_cur;
end;
You are passing a wrong datatype to your procedure.
According to your declaration a NUMBER is expected:
P_ID IN NUMBER
However, you pass a VARCHAR2 in your exec command:
EXEC EXAM_STATS_STUDENTS_SD('6901');
Note the '' around the value.
Try calling this instead:
EXEC EXAM_STATS_STUDENTS_SD(6901);
Apart from that you are missing the second parameter completely.

Unable to execute oracle procedure in PLSQL Developer

I am having sample Procedure as Below
CREATE OR REPLACE PROCEDURE proc_Table1
BEGIN
SELECT 'Sample UserName' AS UserName
FROM Dual;
END;
Now I want to run this Proc in PLSQL developer.I tried the below but its generating error
begin
proc_Table1;
end;
Its Displaying
Thanks for the Help.
Any Idea why this Happens.
When you created the procedure, you should have been alerted to the fact that you had syntax errors. If you're going to run a SELECT statement, you need to do something with the results-- either populate a local variable or open a cursor or something else. The code you've posted is also missing the IS/AS keyword
CREATE OR REPLACE PROCEDURE proc_Table1
AS
l_username VARCHAR2(30);
BEGIN
SELECT 'Sample UserName' AS UserName
INTO l_username
FROM Dual;
END;
will be syntactically valid. It doesn't appear, however, to be particularly useful-- you procedure isn't modifying the database and has no way to communicate with the caller so it isn't doing anything meaningful. As a general principal, you would also generally want to use a simple PL/SQL assignment operator to populate a local variable rather than selecting from dual, i.e.
l_username := 'Sample UserName';
Try this, it should work:
CREATE OR REPLACE PROCEDURE proc_Table1(UserName OUT VARCHAR2)
AS
BEGIN
SELECT 'Sample UserName' INTO UserName
FROM Dual;
dbms_output.put_line(UserName);
END PROC_TABLE1;
-------------------------------
How to Execute
-------------------------------
declare
name varchar2(50);
result varchar2(100);
begin
proc_table1(name);
end;

Calling a stored PROCEDURE in Toad

I have a defined a new stored procedure but get a error while calling it,
CREATE OR REPLACE PROCEDURE SCOTT.getempsal(
p_emp_id IN NUMBER,
p_emp_month IN CHAR,
p_emp_sal OUT INTEGER)
AS
BEGIN
SELECT EMP_SAL
INTO p_emp_sal
FROM EMPLOYEE_SAL
WHERE EMP_ID = p_emp_id
AND EMP_MONTH = p_emp_month;
END getempsal;
And trying to call it:
getempsal(1,'JAN',OUT) --Invalid sql statement.
Your procedure contains an out parameter, so you need to call it in block like:
declare
a number;
begin
getempsal(1,'JAN',a);
dbms_output.put_line(a);
end;
A simple procedure (let's say with a number parameter) can be called with
exec proc(1);
or
begin
proc(1);
end;
Just write EXECUTE procedure_name('provide_the_valueof_IN parameter','value of in parameter', :k) ;
Run this statement a popup will come set the parameters as in out and the datatype too. U will see the output in another popup window.

Resources