SYS_REFCURSOR as OUT parameter - oracle

I have a table contains (username-primarykey,password,age,gender);
have to create procedure like procedure(username in varchar,s_cursor out sys_refcursor);
procedure has to accept username and returns row (where username=in parameter )as cursor.
Rule:Cursor must and should be having unique sequence no along with the record it gives.
example:(unique no(sequence),username ,password,age,gender)
Every time procedure should return single record along with uniqueno(sequence)

You can try something like this, if you need more information you have to provide more details.
Create a sequence for unique no.
CREATE SEQUENCE emp_seq
MINVALUE 1
MAXVALUE 999999999999999999999999999
START WITH 1
INCREMENT BY 1
CACHE 20;
Create a procedure which returns sys_refcursor as OUT parameter and emp_id as IN parameter
CREATE OR REPLACE PROCEDURE get_employee_details (user_id
YOURTABLE.USERNAME%TYPE,
emp_cursor OUT SYS_REFCURSOR)
AS
BEGIN
OPEN emp_cursor FOR
SELECT emp_seq.NEXTVAL,
USERNAME,
PASSWORD,
AGE,
GENDER
FROM YOURTABLE
WHERE USERNAME = user_id;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
DBMS_OUTPUT.put_line ('<your message>' || SQLERRM);
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line ('<your message>' || SQLERRM);
END get_employee_details;
/
And to execute the procedure from sqlplus
variable usercur refcursor;
DECLARE
user_id YOURTABLE.USERNAME%TYPE;
BEGIN
user_id := 'JON';
get_employees(user_id,:usercur);
END;
/
print usercur
Update 1
I assume that you are calling your procedure from sqlplus or from Toad, then you could execute your procedure as
variable dcursor refcursor;
DECLARE
p_arrival DEFAULT_DETAILS.ARRIVALCOUNTRY%TYPE;
BEGIN
p_arrival := '123';
PROCEDURE_SAMPLE(p_arrival,:dcursor);
END;
/
print dcursor
Update 2
To execute procedure from SQL Developer, do as
var usercur refcursor
exec procedure_sample('AU',:usercur)
print usercur

Related

provide Select statement in procedure parameter

Hi i'm working on this query in oracle and i need to provide many id to a procedure from a table. how can i provide each id from a table to my procedure. sory i'm kinda new at this im completely lost i dont know what to search.
here's
Procedure
PROCEDURE procedname(in_id in VARCHAR2)
select id from mytable
Here's what i tryed
execute procedname(select id from mytable);
but did no work
Is there a way to achive this?
Hope somone help me out with this
You can pass a collection of numbers. Here is an example on how to pass.
--sys.odcinumberlist is a collection which can hold numbers..
create procedure sp_test(i_id in sys.odcinumberlist)
as
l_cnt int;
begin
select count(*)
into l_cnt
from TABLE(i_id); /* the TABLE keyword is used to unfold the collection of numbers as rows..*/
dbms_output.put_line(l_cnt);
end;
/
--calling the stored procedure
begin
dbms_output.enable;
sp_test(sys.odcinumberlist(1,2,3,4,5,6)); /* here i am passing a list of numbers from 1 to 6*/
--the procedure will count the number of elements in the input collection which is 6
end;
/
You cannot directly use a SQL statement as an argument for a procedure or function. Since that needs an INTO clause in order to return the content of the SELECT statement. Your case suggests a CURSOR as needs to return all the records at a time. For this, a possible sample solution using SYS_REFCURSOR as an IN/OUT(or just OUT) type of parameter would be ;
SQL> CREATE TABLE mytable( id VARCHAR2(1) );
SQL> INSERT INTO mytable VALUES('A');
SQL> INSERT INTO mytable VALUES('B');
SQL> CREATE OR REPLACE PROCEDURE Convert_ID(p_myrecordset IN OUT SYS_REFCURSOR) AS
BEGIN
OPEN p_myrecordset FOR
SELECT id, ASCII( id )
FROM mytable
ORDER BY id;
END;
/
SQL> SET SERVEROUTPUT ON;
SQL> DECLARE
l_cursor SYS_REFCURSOR;
l_value1 mytable.id%TYPE;
l_value2 INT;
BEGIN
Convert_ID(p_myrecordset => l_cursor);
LOOP
FETCH l_cursor
INTO l_value1, l_value2;
EXIT WHEN l_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(l_value1 || ' - ' || l_value2 );
END LOOP;
CLOSE l_cursor;
END;
/
A - 65
B - 66
Demo
To take each id from some table and call sometable(id), a PL/SQL loop would be something like this:
begin
for r in (
select id from sometable
)
loop
procedname(r.id);
end loop;
end;

Not able to execute a proc in oracle 10 g

I am trying to execute a simple proc Like this in oracle 10g but not able to do getting error PLS-00905: object dbnew.sp_TDCCountry is invalid any idea would be appreciated
Table
CREATE TABLE TDCCountry
( CountryID number(10) NOT NULL,
CountryName varchar2(50) NOT NULL
);
Procedure
CREATE OR REPLACE PROCEDURE SP_TDCCountry
IS
BEGIN
select * from tdcCountry;
COMMIT;
END SP_TDCCountry;
Execution
1.
begin
SP_TDCCountry;
end;
2.exec SP_TDCCountry;
Because you do not have an into clause by which you return values to some variables. It may be proper to return your variable as a rowtype [ By the way a commit is not needed for a non-DDL( in this case, there's a SELECT) statement ].
So, You may use in the following way :
SQL> set serveroutput on;
SQL> CREATE OR REPLACE PROCEDURE SP_TDCCountry IS
v_row tdcCountry%rowtype;
BEGIN
select * into v_row from tdcCountry;
dbms_output.put(v_row.countryid||' - ');
dbms_output.put_line(v_row.countryname);
END;
/
SQL> exec SP_TDCCountry;
If your SELECT statement brings more than one row, then it's proper to return data by means of cursor :
SQL> CREATE OR REPLACE PROCEDURE SP_TDCCountry IS
v_row tdcCountry%rowtype;
BEGIN
for c in ( select * from tdcCountry )
loop
dbms_output.put(c.countryid||' - ');
dbms_output.put_line(c.countryname);
end loop;
END;
/
SQL> exec SP_TDCCountry;

I want to write two plsql procedures. Get data in one procedure and print it from the second procedure

I need a list of values to be fetched from a table in one procedure and then the values to be passed to a second procedure.
For ex. In A.prc I need to fetch data from a table and in B.prc I need to print the data that I fetched in A.prc.
Thanks in Advance
P.S. : Using Oracle 11g as DB with sys priv and Toad to write the prc's
CREATE OR REPLACE PROCEDURE P1(
EMPNO OUT EMP.EMPNO%type,
ENAME OUT EMP.ENAME%type,
DEPTNO OUT EMP.DEPTNO%type)
AS
C_EMP SYS_REFCURSOR;
C_EM VARCHAR2(200);
BEGIN
C_EM:='SELECT EMPNO,ENAME,DEPTNO FROM EMP';
OPEN C_EMP FOR C_EM;
LOOP
FETCH C_EMP into EMPNO,ENAME,DEPTNO;
EXIT WHEN C_EMP%notfound;
END LOOP;
P2(C_EMP);
CLOSE C_EMP;
END;
/
CREATE OR REPLACE PROCEDURE P2(e_EMP SYS_REFCURSOR) AS
BEGIN
LOOP
FETCH e_EMP INTO E_EMPNO,E_ENAME,E_DEPTNO;
EXIT WHEN e_EMP%NOTFOUND;
END LOOP;
CLOSE e_EMP;
END;
/
Error : [Error] PLS-00306 (17: 4): PLS-00306: wrong number or types of
arguments in call to 'P2'
Update 1: Also need to do this without a cursor, with an associative array.
This is a part of assignment/homework.
Tried this with array:
CREATE OR REPLACE PROCEDURE P1
AS
TYPE EmpTabTyp IS TABLE OF emp%ROWTYPE INDEX BY BINARY_INTEGER;
emp_tab EmpTabTyp;
BEGIN
SELECT * INTO emp_tab FROM emp;
END;
/
[Error] PLS-00597 (6: 15): PLS-00597: expression 'EMP_TAB' in the INTO list is >of wrong type
[Error] ORA-00904 (6: 23): PL/SQL: ORA-00904: : invalid identifier
You on the right track, however I think it could be done a little bit more simple.
I hope my example would give you an idea of how to solve it.
For example:
CREATE OR REPLACE PROCEDURE P2 (nId IN NUMBER, vName IN VARCHAR2)
AS
BEGIN
DBMS_OUTPUT.PUT_LINE('Output nId: ' || nId || ' vName: ' || vName);
END;
/
CREATE OR REPLACE PROCEDURE P1
AS
CURSOR c1 AS
SELECT Id, Name FROM TableA;
BEGIN
FOR r1 IN c1 LOOP
P2(nId => r1.Id, vName => r1.Name);
END LOOP;
END;
/
I also would suggest to have a another look on how IN and OUT parameters work, becasue you are using them in a wrong way. But that would would be a whole different topic. :-)
To pass a cursor line to a procedure you could send the record:
For example:
CREATE OR REPLACE PROCEDURE P2 (r1 IN TableA%ROWTYPE)
AS
BEGIN
DBMS_OUTPUT.PUT_LINE('Output nId: ' || r1.nId || ' vName: ' || r1.vName);
END;
/
CREATE OR REPLACE PROCEDURE P1
AS
CURSOR c1 AS
SELECT Id, Name FROM TableA;
BEGIN
FOR r1 IN c1 LOOP
P2(r1 => r1);
END LOOP;
END;
/

Stored proc that picks a stored procedure from a list in a table and executes it in an oracle db?

Is it possible, if yes, what would the syntax look like for a stored proc which would pick a stored procedure from a list in a table and then executes it in an oracle db?
The stored procedure should use EXECUTE IMMEDIATE to execute an anonymous PL/SQL block with the procedure name. This can be as simple as creating a string like begin proc_name; end;. Things get more difficult if there are parameters and return values.
create table proc_table(id number, procedure_name varchar2(100));
insert into proc_table values(1, 'proc1');
insert into proc_table values(2, 'proc2');
create or replace procedure proc1 is begin dbms_output.put_line('1'); end;
/
create or replace procedure proc2 is begin dbms_output.put_line('2'); end;
/
begin
for procedures in
(
select procedure_name
from proc_table
order by procedure_name
) loop
execute immediate 'begin '||procedures.procedure_name||'; end;';
end loop;
end;
/
Output:
1
2

Procedure to input number and output varchar2

I need to write a procedure to input let's say a rep_id and then output the rep_name that corresponds to the rep_id.
After that, I need to use another procedure to call the above procedure.
Here is what I have for the first procedure.
create or replace procedure p_inout
(v_rep_id in number)
As
v_first_name varchar2(20);
v_last_name varchar2(20);
begin
select first_name,last_name into v_first_name, v_last_name
from rep
where rep_id = v_rep_id;
dbms_output.put_line(v_first_name||' '||v_last_name);
end p_inout;
/
Execute p_inout(100);
And here is my procedure to call the above procedure
create or replace procedure p_call
is
v_first_name varchar2(20);
v_last_name varchar2(20);
begin
p_inout(100);
dbms_output.put_line(v_first_name||' '||v_last_name);
end p_call;
/
execute p_call
I was able to get the result but one guy told me that my call procedure should be like this
Create or replace procedure p_call
Is
V_name varchar2(20);
Begin
P_inout(100,v_name); --100 is a rep id
Dbms_output.Put_line(v_name);
End;
/
Execute p_call
Doesn't my procedure to call and his call procedure produce the same result?
CREATE TABLE minions (
rep_id DATE CONSTRAINT minions__rep_id__pk PRIMARY KEY,
rep_name NUMBER CONSTRAINT minions__rep_name__nn NOT NULL
CONSTRAINT minions__rep_name__u UNIQUE
)
/
CREATE OR REPLACE PROCEDURE myCatWasSick (
p_rep_id IN minions.rep_id%TYPE,
p_rep_name OUT minions.rep_name%TYPE
)
IS
BEGIN
SELECT rep_name
INTO p_rep_name
FROM minions
WHERE rep_id = p_rep_id;
EXCEPTION
WHEN NO_DATA_FOUND THEN
p_rep_name := NULL;
END myCatWasSick;
/
CREATE OR REPLACE PROCEDURE releaseTheBadgers
IS
the_badger NUMBER(10);
BEGIN
myCatWasSick( SYSDATE + 1, the_badger );
// Do something with the_badger.
END releaseTheBadgers;
/

Resources