Why this procedure doesn't work?
I tried to get by cursor the rows of the table: AF_EMPLOYEE, and this will order with ASC/DESC (according to the case).
Create or Replace Procedure return_rows_EMPLOYEE (in_order in number,
in_sorting in VARCHAR2, in_job in VARCHAR2, out_cursor OUT SYS_REFCURSOR) As
Begin
OPEN out_cursor for
select * from AF_EMPLOYEE
WHERE EMPL_JOB_TITLE = in_job
ORDER BY in_sorting
CASE in_order
WHEN 1 THEN ASC
ELSE DESC
END
End;
If the sort column is numeric, you can use case to negate it, but it's not good code!
CREATE OR REPLACE PROCEDURE return_rows_EMPLOYEE (in_order in number,
in_sorting in VARCHAR2, in_job in VARCHAR2, out_cursor OUT SYS_REFCURSOR) As
Begin
OPEN out_cursor for
select * from AF_EMPLOYEE
WHERE EMPL_JOB_TITLE = in_job
ORDER BY
CASE in_sorting WHEN 'ASC' THEN sort_column
WHEN 'DESC' THEN -sort_column
END;
END;
/
Create or Replace Procedure return_rows_EMPLOYEE (in_order in number,
in_sorting in VARCHAR2, in_job in VARCHAR2, out_cursor OUT SYS_REFCURSOR) As
Begin
if in_order = 1 THEN
OPEN out_cursor for
select * from AF_EMPLOYEE
WHERE EMPL_JOB_TITLE = in_job
ORDER BY in_sorting ASC
else
OPEN out_cursor for
select * from AF_EMPLOYEE
WHERE EMPL_JOB_TITLE = in_job
ORDER BY in_sorting DESC
end if;
End;
Update
try this:
Create or Replace Procedure return_rows_EMPLOYEE (in_order in number,
in_sorting in VARCHAR2, in_job in VARCHAR2, out_cursor OUT SYS_REFCURSOR) As
Begin
OPEN out_cursor for
select * from AF_EMPLOYEE
WHERE EMPL_JOB_TITLE = in_job
ORDER BY
case when in_order = 1 then
in_sorting
end,
case when in_order <> 1 then
in_sorting
end desc;
End;
Related
I have this procedure into a package, and I need to return the count of a table, but I don't know how do this. I have this and it doesn't work.
PROCEDURE OBTENER_TOTALCAMPAĆA(TOTAL OUT NUMBER)
IS
row_count number;
BEGIN
SELECT COUNT(*) AS TOTAL_CARTERA INTO row_count FROM CLIENTE
RETURNING row_count INTO TOTAL;
END;
Try this. You don't need to say returning in this case. Returning is typically used in inserts that you need to get the id from after the row is inserted. In your case, just fill the output param with the select ... INTO from ....
PROCEDURE OBTENER_TOTALCAMPAĆA(TOTAL OUT NUMBER)
IS
BEGIN
SELECT COUNT(*) AS TOTAL_CARTERA INTO TOTAL FROM CLIENTE;
END;
Buena suerte
try this. it works for me. create oracle package
create or replace PACKAGE LEVEL_CRUD AS
PROCEDURE INSERT_LEVEL_DATA (
P_LEVEL_ID IN APP_LEVEL_MASTER.LEVEL_ID%TYPE,
P_LEVEL_NAME IN APP_LEVEL_MASTER.LEVEL_NAME%TYPE,
P_CREATED_BY IN APP_LEVEL_MASTER.CREATED_BY%TYPE,
P_CREATE_DATE IN VARCHAR2,
P_UPDATE_DATE IN VARCHAR2
);
PROCEDURE FETCH_LEVEL_DATA (
LEVEL_C OUT SYS_REFCURSOR
);
PROCEDURE UPDATE_LEVEL_DATA (
P_LEVEL_ID IN APP_LEVEL_MASTER.LEVEL_ID%TYPE,
P_LEVEL_NAME IN APP_LEVEL_MASTER.LEVEL_NAME%TYPE,
P_CREATED_BY IN APP_LEVEL_MASTER.CREATED_BY%TYPE,
P_CREATE_DATE IN APP_LEVEL_MASTER.CREATE_DATE%TYPE,
P_UPDATE_DATE IN varchar2,
P_UPDATE_COUNT OUT NUMBER
);
PROCEDURE GET_LEVEL_RECORD_ID_WISE(
P_LEVEL_ID IN APP_LEVEL_MASTER.LEVEL_ID%TYPE,
LEVEL_C OUT SYS_REFCURSOR
);
PROCEDURE DELETE_LEVEL_DATA(
P_LEVEL_ID IN APP_LEVEL_MASTER.LEVEL_ID%TYPE,
DELETE_C OUT NUMBER
);
END LEVEL_CRUD;
create package body where actual procedure is available and sql query will return count and data
create or replace PACKAGE BODY LEVEL_CRUD AS
PROCEDURE INSERT_LEVEL_DATA (
P_LEVEL_ID IN APP_LEVEL_MASTER.LEVEL_ID%TYPE,
P_LEVEL_NAME IN APP_LEVEL_MASTER.LEVEL_NAME%TYPE,
P_CREATED_BY IN APP_LEVEL_MASTER.CREATED_BY%TYPE,
P_CREATE_DATE IN VARCHAR2,
P_UPDATE_DATE IN VARCHAR2
) AS
BEGIN
INSERT INTO APP_LEVEL_MASTER
( LEVEL_ID,LEVEL_NAME,CREATED_BY,CREATE_DATE,UPDATE_DATE,STATUS)
VALUES ( ESC_LEVEL_ID.NEXTVAL,P_LEVEL_NAME,P_CREATED_BY,SYSDATE,SYSDATE,1);
END INSERT_LEVEL_DATA;
PROCEDURE FETCH_LEVEL_DATA (
LEVEL_C OUT SYS_REFCURSOR
) AS
BEGIN
open LEVEL_C FOR
SELECT * FROM APP_LEVEL_MASTER where STATUS = 1;
END FETCH_LEVEL_DATA;
PROCEDURE UPDATE_LEVEL_DATA (
P_LEVEL_ID IN APP_LEVEL_MASTER.LEVEL_ID%TYPE,
P_LEVEL_NAME IN APP_LEVEL_MASTER.LEVEL_NAME%TYPE,
P_CREATED_BY IN APP_LEVEL_MASTER.CREATED_BY%TYPE,
P_CREATE_DATE IN APP_LEVEL_MASTER.CREATE_DATE%TYPE,
P_UPDATE_DATE IN varchar2,
P_UPDATE_COUNT OUT NUMBER
) AS
BEGIN
UPDATE APP_LEVEL_MASTER AUM
SET
AUM.LEVEL_NAME = P_LEVEL_NAME,
AUM.CREATED_BY = P_CREATED_BY,
AUM.CREATE_DATE= TO_DATE(P_CREATE_DATE,'DD/MM/YYYY'),
AUM.UPDATE_DATE=TO_DATE(sysdate)
WHERE AUM.LEVEL_ID = P_LEVEL_ID;
P_UPDATE_COUNT:=SQL%ROWCOUNT;
END UPDATE_LEVEL_DATA;
PROCEDURE GET_LEVEL_RECORD_ID_WISE(
P_LEVEL_ID IN APP_LEVEL_MASTER.LEVEL_ID%TYPE,
LEVEL_C OUT SYS_REFCURSOR
)AS
BEGIN
OPEN LEVEL_C FOR
SELECT * FROM APP_LEVEL_MASTER WHERE LEVEL_ID=P_LEVEL_ID;
END GET_LEVEL_RECORD_ID_WISE;
PROCEDURE DELETE_LEVEL_DATA(
P_LEVEL_ID IN APP_LEVEL_MASTER.LEVEL_ID%TYPE,
DELETE_C OUT NUMBER
)AS
BEGIN
UPDATE APP_LEVEL_MASTER SET STATUS='0' WHERE LEVEL_ID=P_LEVEL_ID;
DELETE_C:=SQL%ROWcOUNT;
END DELETE_LEVEL_DATA;
END LEVEL_CRUD;
I have a procedure like this:
CREATE OR REPLACE PROCEDURE RIC.TEST
(P_VAR1 IN VARCHAR2, P_VAR2 IN VARCHAR2, P_VAR3 IN VARCHAR2, P_VAR4 IN VARCHAR2)
IS
L_RC SYS_REFCURSOR;
BEGIN
INSERT INTO RIC.TEMP_TABLE
SELECT * FROM RIC.TABLE WHERE COL1=P_VAR1 AND COL2=P_VAR2 AND COL3=P_VAR3 AND COL4=P_VAR4 AND ...;
OPEN L_RC
FOR 'SELECT .... FROM RIC.TEMP_TABLE WHERE ...';
...
TEMP_TABLE is a temporary table. I need to return and show second select output (SELECT .... FROM RIC.TEMP_TABLE WHERE ...) when I run this procedure. How can I do that? Is cursor wrong way for this?
Thank you.
Modify the procedure to
CREATE OR REPLACE PROCEDURE ric.test (p_var1 IN VARCHAR2,
p_var2 IN VARCHAR2,
p_var3 IN VARCHAR2,
p_var4 IN VARCHAR2,
p_cursor OUT SYS_REFCURSOR)
IS
BEGIN
INSERT INTO ric.temp_table
SELECT *
FROM ric.table
WHERE col1 = p_var1 AND col2 = p_var2 AND col3 = p_var3;
OPEN p_cursor FOR SELECT * FROM ric.temp_table;
END;
/
and execute the procedure as
VARIABLE cur REFCURSOR;
EXEC test (:cur);
PRINT cur;
If you would like to execute the procedure using SQL, wrap the procedure in a function which should be followed by calling the function in a SQL statement.
Example
I have problem with generate report to PDF via Report Server.
When generating a report show an error:
REP-8: A run time error in the PL/SQL development environment (DE)
PDE-PSD001 Could not resolve reference to while loading
REP-0008: An unexpected memory error occurred while initializing preferences.
The error occurs randomly. Once the report prints without problems and at a second printing report does not print and an error shown above,
although the report contains the same data.
My report use 3 Ref cursors and 3 select query. Use Report builder version 11.1.2.2.0.
Please, knows anyone where the problem is and how to resolve it?
Here is example, how I call Ref cusrcor:
Package:
TYPE t_info_rec IS RECORD (
column_1 VARCHAR2(15)
,column_2 NUMBER
,column_3 DATE
,column_4 VARCHAR2(15)
,column_5 VARCHAR2(15)
);
TYPE t_info_cur IS REF CURSOR RETURN t_info_rec;
PROCEDURE info(p_cur IN OUT t_info_cur
,p_parameter_1 NUMBER
,p_parameter_2 NUMBER
,p_parameter_3 VARCHAR2
,p_parameter_4 VARCHAR2
,p_parameter_5 NUMBER
,p_parameter_6 VARCHAR2);
Package Body:
PROCEDURE info(p_cur IN OUT t_info_cur
,p_parameter_1 NUMBER
,p_parameter_1 NUMBER
,p_parameter_1 VARCHAR2
,p_parameter_1 VARCHAR2
,p_parameter_1 NUMBER
,p_parameter_1 VARCHAR2)
IS
--
BEGIN
--
OPEN p_cur FOR
SELECT column_1,column_2,column_3,column_4,column_5
FROM table
;
--
EXCEPTION
WHEN OTHERS THEN
RAISE;
open p_cur for SELECT null,null,null,null,null FROM dual WHERE 1=0;
END info;
Call Ref cusrsor from Report Builders in RDF file:
function QR_2RefCurDS return package.t_info_cur is
c1 package.t_info_cur;
begin
package.info(c1
,p_parameter_1 => :P_PARAM1
,p_parameter_2 => :P_PARAM2
,p_parameter_3 => :P_PARAM3
,p_parameter_4 => :P_PARAM4
,p_parameter_5 => :P_PARAM5
,p_parameter_6 => :P_PARAM6
);
return c1;
end;
I am sorry for my English.
Thank you
Standa
There are few issue with your code. I can see that you declared type of ref cursor. Not sure if that can work. However without digging further in your code i show my code as below. In my code I am creating a record and passing the record type to procedure.
Solution 1
CREATE OR REPLACE PACKAGE Pkg_test
AS
TYPE t_info_rec IS RECORD
(
column_1 NUMBER,
column_2 NUMBER,
column_3 VARCHAR2 (15),
column_4 VARCHAR2 (15),
column_5 NUMBER
);
TYPE t_info_cur IS TABLE OF t_info_rec;
PROCEDURE info (p_cur IN OUT t_info_cur,
p_parameter_1 NUMBER,
p_parameter_2 NUMBER,
p_parameter_3 VARCHAR2,
p_parameter_4 VARCHAR2,
p_parameter_5 NUMBER,
p_parameter_6 VARCHAR2);
FUNCTION QR_2RefCurDS
RETURN t_info_cur;
END Pkg_test;
/
CREATE OR REPLACE PACKAGE BODY Pkg_test
as
PROCEDURE info(p_cur IN OUT t_info_cur
,p_parameter_1 NUMBER
,p_parameter_2 NUMBER
,p_parameter_3 VARCHAR2
,p_parameter_4 VARCHAR2
,p_parameter_5 NUMBER
,p_parameter_6 VARCHAR2)
IS
BEGIN
--OPEN p_cur FOR
SELECT p_parameter_1,p_parameter_2,p_parameter_3,p_parameter_4,p_parameter_5
bulk collect into p_cur
FROM dual ;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('In exception');
-- open p_cur for
SELECT null,null,null,null,null
bulk collect into p_cur
FROM dual WHERE 1=0;
End;
--Function Starting
FUNCTION QR_2RefCurDS
return t_info_cur
is
c1 t_info_cur;
begin
info(c1
,p_parameter_1 => 1 --:P_PARAM1
,p_parameter_2 => 2 --:P_PARAM2
,p_parameter_3 => 'Hello' --:P_PARAM3
,p_parameter_4 => 'Howru' --:P_PARAM4
,p_parameter_5 => 4 --:P_PARAM5
,p_parameter_6 => 'BYE' --:P_PARAM6
);
return c1;
end;
END Pkg_test;
/
Execution:
SQL> declare
outpt PKG_TEST.t_info_cur;
begin
outpt:=PKG_TEST.QR_2RefCurDS;
for i in 1..outpt.count
loop
dbms_output.put_line(outpt(i).column_1 ||' ' || outpt(i).column_2||' ' || outpt(i).column_3||' ' || outpt(i).column_4||' ' || outpt(i).column_5); end loop;
end;
/
1 2 Hello Howru 4
PL/SQL procedure successfully completed.
Solution 2
I use sys_refcursor to match your requirement:
CREATE OR REPLACE PACKAGE Pkg_test
AS
PROCEDURE info (p_cur IN OUT sys_refcursor,
p_parameter_1 NUMBER,
p_parameter_2 NUMBER,
p_parameter_3 VARCHAR2,
p_parameter_4 VARCHAR2,
p_parameter_5 NUMBER,
p_parameter_6 VARCHAR2);
FUNCTION QR_2RefCurDS
return sys_refcursor;
END Pkg_test;
/
CREATE OR REPLACE PACKAGE BODY Pkg_test
as
PROCEDURE info(p_cur IN OUT sys_refcursor
,p_parameter_1 NUMBER
,p_parameter_2 NUMBER
,p_parameter_3 VARCHAR2
,p_parameter_4 VARCHAR2
,p_parameter_5 NUMBER
,p_parameter_6 VARCHAR2)
IS
BEGIN
OPEN p_cur FOR
SELECT p_parameter_1,p_parameter_2,p_parameter_3,p_parameter_4,p_parameter_5
FROM dual ;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('In exception');
open p_cur for
SELECT null,null,null,null,null
--bulk collect into p_cur
FROM dual WHERE 1=0;
End;
--Function Starting
FUNCTION QR_2RefCurDS
return sys_refcursor
is
c1 sys_refcursor;
begin
info(c1
,p_parameter_1 => 1 --:P_PARAM1
,p_parameter_2 => 2 --:P_PARAM2
,p_parameter_3 => 'Hello' --:P_PARAM3
,p_parameter_4 => 'Howru' --:P_PARAM4
,p_parameter_5 => 4 --:P_PARAM5
,p_parameter_6 => 'BYE' --:P_PARAM6
);
return c1;
end;
END Pkg_test;
Execution
SQL> select PKG_TEST.QR_2RefCurDS from dual;
QR_2REFCURDS
--------------------
CURSOR STATEMENT : 1
CURSOR STATEMENT : 1
:B5 :B4 :B3 :B2 :B1
---------- ---------- -------------------------------- -------------------------------- ----------
1 2 Hello Howru 4
I have ORACLE PROCEDURE, where I need to use dynamic table name in select query based on parameter "a_ID" passed.
But I am getting error in creating procedure.
Error(20,28): PL/SQL: ORA-00942: table or view does not exist
Can anybody help resolving this?
Below is the proc....
CREATE OR REPLACE
PROCEDURE IsTrue
(
AppID IN VARCHAR2,
a_ID IN VARCHAR2,
l_ID VARCHAR2,
return_value out CHAR
)
AS
v_sql VARCHAR(3000);
v_tablename VARCHAR(30);
BEGIN
SELECT decode(a_ID,'LS','LSAPP','MR','MRAPP','RV','RVAPP','APP') INTO v_tablename FROM dual;
SELECT CASE
WHEN EXISTS (SELECT 1
FROM v_tablename
WHERE APPID = AppID
AND LID <> l_ID)
THEN 'Y'
ELSE 'N'
END AS RECORD_EXISTS
FROM DUAL;
EXECUTE IMMEDIATE v_sql INTO return_value;
END;
CREATE OR REPLACE PROCEDURE IsTrue (argAppID IN VARCHAR2, a_ID IN VARCHAR2, l_ID VARCHAR2, return_value out CHAR )
AS
v_sql VARCHAR(3000);
v_tablename VARCHAR(30);
BEGIN
SELECT decode(a_ID,'LS','LSAPP','MR','MRAPP','RV','RVAPP','APP') INTO v_tablename FROM dual;
v_sql := 'SELECT CASE WHEN EXISTS (SELECT 1 FROM ' || v_tablename || ' WHERE APPID = '''|| argAppID ||''' AND LID <> '''|| l_ID || ''') THEN ''Y'' ELSE ''N'' END AS RECORD_EXISTS FROM DUAL';
EXECUTE IMMEDIATE v_sql INTO return_value;
END;
In your procedure the second line created as dynamic sql and stored in v_sql.
This may help your procedure to execute as you need.
EDITED :
I am trying to create a procedure where a Ref Cursor is defined as an OUT parameter, my question is how do I call out that Ref Cursor when I execute it for example here is how I want to call it in my EXEC sql command :
EXEC film_not_in_stock(2,2,vcur);
Here is the procedure :
CREATE OR REPLACE PROCEDURE film_not_in_stock( p_film_id IN NUMBER, p_store_id IN NUMBER, vcur OUT SYS_REFCURSOR)
IS
cur sys_refcursor;
v_cur inventory.inventory_id%TYPE --or the same type the inventory_id column is
v_cur sys_refcursor;
BEGIN
OPEN cur FOR SELECT inventory_id
FROM inventory
WHERE film_id = p_film_id
AND store_id = p_store_id
AND inventory_id NOT IN (SELECT inventory_in_stock(inventory_id) FROM dual);
fetch cur into v_cur;
EXIT WHEN cur%NOTFOUND;
END;
/
I know there are typos in procedure as well, will appreciate if you can help me put it right.
Thank you very very much !!
Tonya
Try as
variable p_cursor REFCURSOR;
DECLARE
BEGIN
film_not_in_stock(2,2,:p_cursor);
end;
/
print p_cursor;
And modify procedure as
CREATE OR REPLACE PROCEDURE film_not_in_stock (
p_film_id IN inventory.film_id%TYPE,
p_store_id IN inventory.store_id%TYPE,
vcur OUT SYS_REFCURSOR)
AS
BEGIN
OPEN vcur FOR
SELECT inventory_id
FROM inventory
WHERE film_id = p_film_id
AND store_id = p_store_id
AND inventory_id NOT IN
(SELECT inventory_in_stock (inventory_id) FROM DUAL);
END;
/
The following will do :
var results refcursor
exec film_not_in_stock(2,2,:results);
You need to declare a variable to fetch your cursor results into...
Something like this...
CREATE OR REPLACE PROCEDURE film_not_in_stock( p_film_id IN NUMBER, p_store_id IN NUMBER, p_film_count OUT NUMBER, cur OUT SYS_REFCURSOR)
IS
cur sys_refcursor;
v_cur inventory.inventory_id%TYPE --or the same type the inventory_id column is
BEGIN
OPEN cur FOR SELECT inventory_id
FROM inventory
WHERE film_id = p_film_id
AND store_id = p_store_id
AND inventory_id NOT IN (SELECT inventory_in_stock(inventory_id) FROM dual);
--SELECT FOUND_ROWS() INTO p_film_count FROM dual; <<----- **This is the line**
fetch cur into v_cur;
EXIT WHEN %NOTFOUND;
--do whatever you want
END;
/