Return Count in Procedure - Oracle - oracle

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;

Related

Oracle PL/SQL - procedure with array parameter

I need to write an oracle procedure which will have an array of ID's as parameter.
Then I will return a cursor which contains result of select(1).
(1) - select * from table where id in(ID's)
As an option we can pass a string param and then convert string to array.
DECLARE
info sys_refcursor ;
error varchar(255);
BEGIN
package.test_function('1,2,3',info ,error);// info will contain a result cursor for select(1)
END;
Do you have other ideas?
You can create a user-defined collection type:
CREATE TYPE int8_list IS TABLE OF NUMBER(8,0);
Then your package:
CREATE PACKAGE pkg_name AS
PROCEDURE proc_name (
i_ids IN int8_list,
o_cursor OUT SYS_REFCURSOR
);
END;
/
CREATE PACKAGE BODY pkg_name AS
PROCEDURE proc_name (
i_ids IN int8_list,
o_cursor OUT SYS_REFCURSOR
)
IS
BEGIN
OPEN o_cursor FOR
SELECT * FROM table_name WHERE id MEMBER OF i_ids;
END;
END;
/
Then you can call the procedure:
DECLARE
v_info sys_refcursor ;
v_id TABLE_NAME.ID%TYPE;
v_value TABLE_NAME.VALUE%TYPE;
BEGIN
pkg_name.proc_name(int8_list(1,2,3), v_info);
LOOP
FETCH v_info INTO v_id, v_value;
EXIT WHEN v_info%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(v_id || ' ' || v_value);
END LOOP;
END;
/
Which, for the sample data:
CREATE TABLE table_name (id, value) AS
SELECT LEVEL, CHR(64+LEVEL) FROM DUAL CONNECT BY LEVEL <= 5;
Outputs:
1 A
2 B
3 C
db<>fiddle here

Using count(*) to fetch more than one row in a SQL Procedure

I'm trying to return the number of rows per invoice_id using a function and procedure. Some invoice_id's have more than one row and I'm not sure how to fetch the count when I execute my procedure. As an example invoice_id(7) has just one row, but invoice_id(100) has four rows of information.
Create or replace function return_num_rows_function(invoice_id_text in varchar2)
Return varchar2
Is inv_id varchar2(20);
Begin
Select count(*)invoice_id into inv_id from invoice_line_items where invoice_id=invoice_id_text;
Return inv_id;
End;
Create or replace procedure return_num_rows (invoice_id_text in varchar2)
Is inv_id varchar(20);
line_item_desc invoice_line_items.line_item_description%type;
Begin
inv_id := return_num_rows_function(invoice_id_text);
If inv_id is not null then
Select count(*)invoice_id, line_item_description into inv_id,line_item_desc
From invoice_line_items where invoice_id = inv_id;
dbms_output.put_line('The number of rows returned:'|| inv_id);
dbms_output.put_line('Item description(s):'|| line_item_desc);
End if;
End;
set serveroutput on;
execute return_num_rows(7);
First of all do not use a string type variable for a numeric one
(invoice_id_text).
For your case it's better to use a procedure instead of called
function ( return_num_rows_function ), since you need two out
arguments returned.
A SQL Select statement cannot be used without Group By with aggegated and non-aggregated columns together ( i.e. don't use this one :
Select count(*) invoice_id, line_item_description
into inv_id,line_item_desc
From invoice_line_items
Where invoice_id = inv_id;
)
So, Try to create below procedures :
SQL> CREATE OR REPLACE Procedure
return_num_rows_proc(
i_invoice_id invoice_line_items.invoice_id%type,
inv_id out pls_integer,
line_item_desc out invoice_line_items.line_item_description%type
) Is
Begin
for c in
(
Select line_item_description
into line_item_desc
From invoice_line_items
Where invoice_id = i_invoice_id
)
loop
line_item_desc := line_item_desc||' '||c.line_item_description;
inv_id := nvl(inv_id,0) + 1;
end loop;
End;
/
SQL> CREATE OR REPLACE Procedure
return_num_rows(
i_invoice_id pls_integer
) Is
inv_id pls_integer;
line_item_desc invoice_line_items.line_item_description%type;
Begin
return_num_rows_proc(i_invoice_id,inv_id,line_item_desc);
If inv_id is not null then
dbms_output.put_line('The number of rows returned:' || inv_id);
dbms_output.put_line('Item description(s):' || line_item_desc);
End if;
End;
/
and call as in your case :
SQL> set serveroutput on;
SQL> execute return_num_rows(7);
Replace inv_id varchar2(20) with inv_id number;
and also if you want to get two outputs from procedure better to use refcursor.

Print report with error REP-8: A run time error in the PL/SQL development environment (DE)

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

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;
/

Can't retrieve data using dynamic SQL from the function that returns the table

My types:
TYPE T_rowBalanceListForClient IS RECORD
(
RowCode Asset.RowCode%TYPE,
RowName Asset.RowName%TYPE
);
TYPE T_tableBalanceListForClient IS TABLE OF T_rowBalanceListForClient;
My function:
FUNCTION F_BalanceListForClient
(
p_ClientId Client.ClientId%TYPE
)
RETURN T_tableBalanceListForClient PIPELINED
AS
CURSOR CUR_TABLE IS
SELECT
RowCode,
RowName
FROM Asset;
BEGIN
FOR CUR_REC IN CUR_TABLE LOOP
PIPE ROW(CUR_REC);
END LOOP;
END;
Part of my stored procedure:
sql_statement := ' SELECT * FROM TABLE(:1)';
OPEN c_Result FOR sql_statement USING F_BalanceListForClient(11);
While building the package I reseive the Oracle error:
PLS-00457: expressions have to be of SQL types
In the common stored procedures calls like this are built and operate well (not dynamics):
PROCEDURE GET_BALANCE_STANDARD_LIST
(
c_Result OUT SYS_REFCURSOR,
p_ClientId Client.ClientId%TYPE DEFAULT NULL
)
AS
BEGIN
OPEN c_Result FOR
SELECT RowName FROM TABLE(F_BalanceListForClient(p_ClientId));
END;
Appreciate any help.
Thanks.
CREATE OR REPLACE TYPE T_rowBalanceListForClient IS OBJECT
(
RowCode NUMBER,
RowName VARCHAR2(200)
);
CREATE OR REPLACE TYPE T_tableBalanceListForClient AS TABLE OF T_rowBalanceListForClient;
/
CREATE OR REPLACE FUNCTION F_BalanceListForClient
(
p_ClientId NUMBER
)
RETURN T_tableBalanceListForClient PIPELINED
AS
CURSOR CUR_TABLE IS
SELECT
RowCode,
RowName
FROM Assets
; --put a filter of the p_clientId
BEGIN
FOR CUR_REC IN CUR_TABLE
LOOP
pipe row (T_rowBalanceListForClient (CUR_REC.RowCode, CUR_REC.RowName));
END LOOP;
RETURN;
END;
/
CREATE OR REPLACE PROCEDURE GET_BALANCE_STANDARD_LIST
(
c_Result OUT SYS_REFCURSOR,
p_ClientId NUMBER DEFAULT NULL
)
AS
sql_statement varchar2(200);
BEGIN
sql_statement := ' SELECT * FROM TABLE(F_BalanceListForClient(:1))';
OPEN c_Result FOR sql_statement USING p_ClientId;
END;
/
BEGIN
GET_BALANCE_STANDARD_LIST(:cur ,11);
END;
/

Resources