Oracle PL SQL, Simplifying my procedure - sql

I have a following procedure.
PROCEDURE PROC_SELECT_ORDERTBL(
my_cursor OUT SYS_REFCURSOR,
p_ORDER_ID IN VARCHAR2
...
)
BEGIN
IF p_ORDER_ID IS NULL THEN
OPEN my_cursor FOR
[VERY LONG SELECT STATEMENT1]
ELSE
OPEN my_cursor FOR
[VERY LONG SELECT STATEMENT2]
END IF;
END PROC_SELECT_ORDERTBL
select statement 1 and 2 are almost same.
statement2 = statement1 + where clase(checking p_ORDER_ID)
I want to simplifying my procedure like next.
PROCEDURE PROC_SELECT_ORDERTBL(
my_cursor OUT SYS_REFCURSOR,
p_ORDER_ID IN VARCHAR2
...
)
BEGIN
WITH viewData AS
[VERY LONG SELECT STATEMENT1]
IF p_ORDER_ID IS NULL THEN
OPEN my_cursor FOR
viewData
ELSE
OPEN my_cursor FOR
viewData + where clause
END IF;
END PROC_SELECT_ORDERTBL
But this doesn't compile.
----------------------This in my whole procedure code-------------------
-- ORDERTBL 종이식권 주문단위로 조회
PROCEDURE PROC_SELECT_ORDERTBL (
my_cursor OUT SYS_REFCURSOR, -- CURSOR
p_AREA_ID IN VARCHAR2, -- AREA_ID
p_EQP_ID IN VARCHAR2, -- EQP_ID
p_ORDER_ID IN VARCHAR2, -- ORDER_ID
p_date_from IN VARCHAR2, -- yymmdd 조회시작일
p_date_to IN VARCHAR2, -- yymmdd 조회종료일
p_errorcode OUT NUMBER -- error code
) AS
BEGIN
p_errorcode := 0;
IF p_ORDER_ID IS NULL THEN
OPEN my_cursor FOR
SELECT ORD.ORDER_DATE AS 판매일자, ORD.ORDER_TIME AS 판매시간, ORD_ID.ORDER_ID AS 주문번호, TOTAL_SALES AS 판매금액
FROM
(
--판매일자, 판매시간, 판매금액
SELECT ORDER_DATE, ORDER_TIME, SUM(ORDER_FEE) AS TOTAL_SALES
FROM
(
SELECT DISTINCT ORDER_DATE, ORDER_TIME, ORDER_FEE FROM ORDERTBL
WHERE AREA_ID = p_AREA_ID AND EQP_ID = p_EQP_ID AND
ORDER_DATE >= p_date_from AND ORDER_DATE <= p_date_to
)
GROUP BY ORDER_DATE, ORDER_TIME
) ORD
JOIN
(
--판매일자, 판매시간, 주문번호
SELECT ORDER_DATE, ORDER_TIME, MIN(ORDER_ID) AS ORDER_ID
FROM ORDERTBL
WHERE AREA_ID = p_AREA_ID AND EQP_ID = p_EQP_ID AND
ORDER_DATE >= p_date_from AND ORDER_DATE <= p_date_to
GROUP BY ORDER_DATE, ORDER_TIME
) ORD_ID
ON ORD.ORDER_DATE = ORD_ID.ORDER_DATE AND ORD.ORDER_TIME = ORD_ID.ORDER_TIME
ORDER BY ORD.ORDER_DATE, ORD.ORDER_TIME;
ELSE
OPEN my_cursor FOR
SELECT ORD.ORDER_DATE AS 판매일자, ORD.ORDER_TIME AS 판매시간, ORD_ID.ORDER_ID AS 주문번호, TOTAL_SALES AS 판매금액
FROM
(
--판매일자, 판매시간, 판매금액
SELECT ORDER_DATE, ORDER_TIME, SUM(ORDER_FEE) AS TOTAL_SALES
FROM
(
SELECT DISTINCT ORDER_DATE, ORDER_TIME, ORDER_FEE FROM ORDERTBL
WHERE AREA_ID = p_AREA_ID AND EQP_ID = p_EQP_ID AND
ORDER_DATE >= p_date_from AND ORDER_DATE <= p_date_to
)
GROUP BY ORDER_DATE, ORDER_TIME
) ORD
JOIN
(
--판매일자, 판매시간, 주문번호
SELECT ORDER_DATE, ORDER_TIME, MIN(ORDER_ID) AS ORDER_ID
FROM ORDERTBL
WHERE AREA_ID = p_AREA_ID AND EQP_ID = p_EQP_ID AND
ORDER_DATE >= p_date_from AND ORDER_DATE <= p_date_to
GROUP BY ORDER_DATE, ORDER_TIME
) ORD_ID
ON ORD.ORDER_DATE = ORD_ID.ORDER_DATE AND ORD.ORDER_TIME = ORD_ID.ORDER_TIME
WHERE ORD_ID.ORDER_ID = p_ORDER_ID;
END IF;
EXCEPTION
WHEN OTHERS THEN
p_errorcode := SQLCODE;
END PROC_SELECT_ORDERTBL;

You can use CASE construct in the where clause. The logic would be similar to your IF-ELSE condition. But, it is not a good coding practice.
I would go with NVL and DECODE.
Update : The DECODE and NVL parameter values depends on the column data type.
If P_ORDER_ID is NUMBER then use :
WHERE
DECODE(p_order_id, NULL, 0, ORD_ID.ORDER_ID) = NVL(p_ORDER_ID, 0)
else if P_ORDER_ID is VARCHAR2 then use :
WHERE
DECODE(p_order_id, NULL, '0', ORD_ID.ORDER_ID) = NVL(p_ORDER_ID, '0')

Related

I can't call procedures several times

I have 2 procedures: the first one is to fill a table "dm.dm_account_turnover_f" with data on sertain day and the second one is to log this procces in a table dm.lg_messages. The first one calls the second one and when I call my procedure several times (I need that to fill my table with all days in a month) it causes the error that the transaction wasn't finished correctly.
When I call my procdure only once there's no errors. How can I do it in a loop without error like that? Is there's something wrong in procedures?
PROCEDURE ds.fill_account_turnover_f()
declare
v_RowCount int;
begin
call dm.writelog( '[BEGIN] fill(i_OnDate => date '''
|| to_char(i_OnDate, 'yyyy-mm-dd')
|| ''');', 1
);
call dm.writelog( 'delete on_date = '
|| to_char(i_OnDate, 'yyyy-mm-dd'), 1
);
delete
from dm.dm_account_turnover_f f
where f.on_date = i_OnDate;
call dm.writelog('insert', 1);
insert
into dm.dm_account_turnover_f
( on_date
, account_rk
, credit_amount
, credit_amount_rub
, debet_amount
, debet_amount_rub
)
with wt_turn as
( select p.credit_account_rk as account_rk
, p.credit_amount as credit_amount
, p.credit_amount * nullif(er.reduced_cource, 1) as credit_amount_rub
, cast(null as numeric) as debet_amount
, cast(null as numeric) as debet_amount_rub
from ds.ft_posting_f p
join ds.md_account_d a
on a.account_rk = p.credit_account_rk
left
join ds.md_exchange_rate_d er
on er.currency_rk = a.currency_rk
and i_OnDate between er.data_actual_date and er.data_actual_end_date
where p.oper_date = i_OnDate
and i_OnDate between a.data_actual_date and a.data_actual_end_date
and a.data_actual_date between date_trunc('month', i_OnDate) and (date_trunc('MONTH', to_date(i_OnDate::TEXT,'yyyy-mm-dd')) + INTERVAL '1 MONTH - 1 day')
union all
select p.debet_account_rk as account_rk
, cast(null as numeric) as credit_amount
, cast(null as numeric) as credit_amount_rub
, p.debet_amount as debet_amount
, p.debet_amount * nullif(er.reduced_cource, 1) as debet_amount_rub
from ds.ft_posting_f p
join ds.md_account_d a
on a.account_rk = p.debet_account_rk
left
join ds.md_exchange_rate_d er
on er.currency_rk = a.currency_rk
and i_OnDate between er.data_actual_date and er.data_actual_end_date
where p.oper_date = i_OnDate
and i_OnDate between a.data_actual_date and a.data_actual_end_date
and a.data_actual_date between date_trunc('month', i_OnDate) and (date_trunc('MONTH', to_date(i_OnDate::TEXT,'yyyy-mm-dd')) + INTERVAL '1 MONTH - 1 day')
)
select i_OnDate as on_date
, t.account_rk
, sum(t.credit_amount) as credit_amount
, sum(t.credit_amount_rub) as credit_amount_rub
, sum(t.debet_amount) as debet_amount
, sum(t.debet_amount_rub) as debet_amount_rub
from wt_turn t
group by t.account_rk;
GET DIAGNOSTICS v_RowCount = ROW_COUNT;
call dm.writelog('[END] inserted ' || to_char(v_RowCount,'FM99999999') || ' rows.', 1);
commit;
end
PROCEDURE dm.writelog(, )
declare
log_NOTICE constant int := 1;
log_WARNING constant int := 2;
log_ERROR constant int := 3;
log_DEBUG constant int := 4;
c_splitToTable constant int := 4000;
c_splitToDbmsOutput constant int := 900;
v_logDate timestamp;
v_callerType varchar;
v_callerOwner varchar;
v_caller varchar;
v_line numeric;
v_message varchar;
begin
v_logDate := now();
-- split to log table
v_message := i_message;
i_messageType := log_NOTICE;
while length(v_message) > 0 loop
insert into dm.lg_messages (
record_id,
date_time,
pid,
message,
message_type,
usename,
datname,
client_addr,
application_name,
backend_start
)
select
nextval('dm.seq_lg_messages'),
now(),
pid,
substr(v_message, 1, c_splitToTable),
i_messageType,
usename,
datname,
client_addr,
application_name,
backend_start
from pg_stat_activity
where pid = pg_backend_pid();
v_message := substr(v_message, c_splitToTable + 1);
end loop;
commit;
end
I need fill my table with data for a month so I need to call my procedure 31 times. I tried this with python
my loop:
date_dt = datetime.strptime(input('Please input the last day of month in format "yyyy-mm-dd" '), "%Y-%m-%d")
while (date_dt - timedelta(days=1)).strftime("%m") == date_dt.strftime("%m"):
date_str = str(date_dt)
new_table.fill_account_turnover_f(date_str)
date_dt -= timedelta(days=1)
function that calls the procedure:
def fill_account_turnover_f(self, date_str):
cur = self.con.cursor()
cur.execute(f"CALL ds.fill_account_turnover_f('{date_str}');")
self.con.commit()
cur.close()
but it causes the error about invalid transaction termitation! it says something about COMMIT, string 51 and string 6 operator CALL

PL/SQL procedure to output line the given date if not existing, latest date should be given

I have this table informationvalues with the contents:
Now I create a procedure where I need to input a date parameter which should output line the correct attr with given price. If the date doesn't exist the latest date should be selected.
The solution table for to_date('01-jan-19') would look like this:
This would be then output line in the procedure.
Should I select to correct tuple and output line it or would it be best to just bulk collect everything and then check in a for loop with an if statement what tuple I need to display.
What I have so far:
A select statement with the tuples I am looking for:
create or replace procedure print_inf_value(closingDate Date) is
cursor d1 (closingDate Date) is
select t.attr, t.dateOfValue, t.price
from (
select i.*,
row_number() over (
partition by attr
order by case when dateOfValue = closingdate then 1 else 2 end, dateOfValue desc
) rn
from InformationValues i
) t
where t.rn = 1;
BEGIN
dbms_output.put_line('Information Value ');
dbms_output.put_line('--------------------------------');
FOR d1_rec IN d1 LOOP
dbms_output.put_line(d1_rec.attr || ' ' || d1_rec.price );
END LOOP;
END;
Or a procedure where I bulk collect everything and then I need to sort out what tuple I need:
create or replace procedure print_inf_value(closingDate Date) is
TYPE d1 IS TABLE OF informationvalues%rowtype;
emps d1;
begin select * bulk collect into emps
from informationvalues;
FOR i IN 1 .. emps.COUNT LOOP
if emps(i).dateofvalue = closingDate then
dbms_output.put_line(emps(i).attr || ' ' || emps(i).price );
/*else*/
end if;
END LOOP;
END;
Both are not working right, so what am I missing to display tuple with the correct date.
Please try:
CREATE OR REPLACE PROCEDURE print_inf_value (closingDate DATE)
IS
BEGIN
DBMS_OUTPUT.put_line (RPAD ('ATTR', 20) || RPAD ('PRICE', 20));
FOR o
IN (select attr, trim(case when price < 1 then to_char(price,90.9) else to_char(price) end) price from (
select attr, price, dateofvalue,
row_number() over (partition by attr order by dateofvalue desc) rn from informationvalues
) i where dateofvalue = closingdate
or (rn = 1 and not exists (select 1 from informationvalues iv where iv.attr = i.attr and dateofvalue = closingdate) )
)
LOOP
DBMS_OUTPUT.put_line (RPAD (o.attr, 20) || RPAD ( o.price, 20));
END LOOP;
END;
Sample execution:
set serveroutput on;
begin
print_inf_value(date'2019-01-01');
end;
Output:
ATTR PRICE
age 2
electronics 0.5
gender 3
hobbies 0.5
homeAddress 7
maritalStatus 1
mobilePhone 5
musicTaste 0.1
socialContacts 1

using dynamic sql to create column for select statement

I'm writing a stored procedure for paginated results and this result can be ordered by certain values. I did have a switch case in a select statement but because it was trying to do an orderby on rownum it was very slow.
Now I am trying to use dyanmic sql to build the query outside the select but I don't know if what I am doing is possible.
Here is my SQL in Oracle SQL Developer:
create or replace PROCEDURE Sp_tsa_trainees_pagination (
schemeid IN INT,
searchval IN VARCHAR2,
pagesize IN INT DEFAULT 20,
currentpage IN INT DEFAULT 1,
--orderby IN VARCHAR2,
cursor_ OUT SYS_REFCURSOR)
AS
-- LOCAL VARIABLES
totalcount INT;
numberofpages INT;
startposition NUMBER;
endposition NUMBER;
orderby VARCHAR2(100) := 'surname asc' ;
dynamic_query VARCHAR(255) := 'row_number() over (order by t.SURNAME DESC, t.FORENAMES DESC) AS rnum';
BEGIN
-- Get total number of trainees in scheme
select COUNT(t.ORG_REGISTRATION_ID)
into totalcount FROM v_trainee t
where t.ORG_REGISTRATION_ID = schemeid
AND t.status = 'A' and LOWER(t.trainee_name) like '%' || LOWER(searchval) || '%';
-- calculate number of pages in the pagination by dividing total number of records by how many to display for each page
numberofpages := totalcount / pagesize;
-- get start position by multiplying number of records to display for each page by current page
startposition := pagesize *( currentpage-1);
-- add calculated start position by number of records to display to get end position
endposition := startposition + pagesize;
CASE orderby
WHEN 'surname desc' THEN dynamic_query := 'row_number() over (order by t.SURNAME DESC, t.FORENAMES DESC) AS rnum';
WHEN 'surname asc' THEN dynamic_query := 'row_number() over (order by t.SURNAME ASC, t.FORENAMES ASC) AS rnum';
END CASE;
OPEN cursor_ FOR
Select * from
(
SELECT
-- order by based on selection
dynamic_query rnum,
t.ORG_REGISTRATION_ID SearchId,
t.FORENAMES Forenames,
t.FORENAME Forename,
t.SURNAME Surname,
t.person_id PersonId,
t.trainee_name TraineeName,
t.STATUS Status,
t.IPD_ANNUAL_REVIEW_DATE AnnualReviewDate,
t.ANNUAL_REVIEW_STATUS AnnualReviewStatus,
t.payment_received PaymentRecieved,
t.TRAINEE_ID TraineeId,
t.IPD_SIGNUP_DATE IpdSignupDate,
t.START_DATE StartDate,
t.END_DATE EndDate,
t.LENGTH_ON_SCHEME LengthOnScheme,
t.EMPLOYEE_NUMBER EmploymentNumber,
t.SELECTED_LEVEL SelectedLevel,
t.SELECTED_LEVEL_DESCRIPTION SelectedLevelDescription,
t.ELIGIBLE_LEVEL EligibleLevel,
t.ELIGIBLE_LEVEL_DESCRIPTION EligibleLevelDescription,
sce.FORENAMES SceForenames,
sce.FORENAME SceForename,
sce.SURNAME SceSurname,
sce.mentor_name SceName,
sce.EMPLOYEE_NUMBER SceEmployeeNumber,
de.FORENAMES DeForenames,
de.FORENAME DeForename,
de.SURNAME DeSurname,
de.mentor_name DeName,
de.EMPLOYEE_NUMBER DeEmployeeNumber,
t.COMPLETED_ATTRIBUTE_LEVELS CompletedAttributeLevels,
t.ATTRIBUTE_LEVEL_COUNT AttributeLevelCount,
-- get percentage
CASE t.ATTRIBUTE_LEVEL_COUNT
WHEN 0 THEN 0
ELSE
COMPLETED_ATTRIBUTE_LEVELS / t.ATTRIBUTE_LEVEL_COUNT * 100
END percentage,
DECODE(F_ISTRAINEEGROUPMEMBER(t.ORG_REGISTRATION_ID, 'S', t.person_id),'Y','N','Y') WithoutTsaGroup,
orr.status SchemeStatus,
(select count(*) from TRAINING_GROUP_TRAINEE tgt where tgt.trainee_id = t.TRAINEE_ID) NUMBER_OF_GROUPS,
TotalCount
FROM v_trainee t
INNER JOIN org_registration orr ON t.ORG_REGISTRATION_ID = orr.id
LEFT OUTER JOIN v_mentor sce ON t.sce_id = sce.MENTOR_ID
LEFT OUTER JOIN v_mentor de ON t.de_id = de.MENTOR_ID
where t.ORG_REGISTRATION_ID = schemeid AND t.status = 'A'
and LOWER(t.trainee_name) like '%' || LOWER(searchval) || '%'
)
where rnum >= startposition and rnum <= endposition;
END;
I want to use this variable with the assigned sql:
dynamic_query rnum,
But when I execute the stored procedure I get this error:
ORA-01722: invalid number ORA-06512: at
"db.SP_TSA_TRAINEES_PAGINATION", line 46 ORA-06512: at line 13
So basically my question is can I assign a SQL to VARCHAR2 and then use it in a select statement dynamically.
You may need dynamic SQL for this. For example:
create or replace procedure testDyn(n in number, C OUT SYS_REFCURSOR) is
vDynamicPart varchar2(1000);
vSQl varchar2(1000);
begin
--
if (n = 1) then
vDynamicPart := 'count(1)';
else
vDynamicPart := 'count(null)';
end if;
--
vSQl := 'select ' || vDynamicPart || ' from dual';
open C for vSQl;
end;
If you call it
declare
n1 number;
n2 number;
C1 SYS_REFCURSOR;
C2 SYS_REFCURSOR;
begin
testDyn(1, C1);
testDyn(2, C2);
fetch C1 into n1;
fetch C2 into n2;
dbms_output.put_line('n1: ' || n1);
dbms_output.put_line('n2: ' || n2);
end;
you get:
n1: 1
n2: 0

How to generate SQL query from arithmetic relation

How would you parse (that's a simple case) something like that: ${table_1} + ${table_2} + ${table_3}
and generate a sql query such as:
WITH
TMP_1 AS (SELECT date, quantity FROM table_1),
TMP_2 AS (SELECT date, quantity FROM table_2),
TMP_3 AS (SELECT date, quantity FROM table_3)
SELECT time_bucket('1 day', date) AS date,
sum(quantity) AS sum FROM
(
SELECT date, quantity FROM TMP_1
UNION ALL
SELECT date, quantity FROM TMP_2
UNION ALL
SELECT date, quantity FROM TMP_3
) AS res_1
GROUP BY 1
ORDER BY 1;
Do you know of any kind of pseudo language that can be transformed to SQL queries
Update 1
The relation can change depending on user input: ${table_1} + ${table_2} * ( ${table_3} * 60 )
You can do it with sql itself:
do
$$
declare
_i text;
_r text;
begin
_i := '${table_1} + ${table_2} + ${table_3}';
_r := (
with u as (select * from unnest(string_to_array(_i,'+')) with ordinality t(e,o))
, c as (select format('TMP_%s AS (SELECT date, quantity FROM %I)'
, o
, substring(unnest(string_to_array(e,'+')) from '\{(.+)\}')
) from u
)
select string_agg(format,','||chr(10)) from c);
_r := 'WITH '||chr(10)||_r||chr(10)||$s$SELECT time_bucket('1 day', date) AS date,
sum(quantity) AS sum FROM
(
SELECT date, quantity FROM TMP_1
UNION ALL
SELECT date, quantity FROM TMP_2
UNION ALL
SELECT date, quantity FROM TMP_3
) AS res_1
GROUP BY 1
ORDER BY 1;$s$;
raise info '%',_r;
execute _r;
end;
$$
;

How to avoid using same function multiple times in Query and speed up the data retrieval

I have the following function:
CREATE OR REPLACE FUNCTION IR.SRG(
IR_item IN VARCHAR2,
IR_comp VARCHAR2,
IR_locn VARCHAR2,
IR_Type VARCHAR2,
IR_fromdate DATE,
IR_tilldate DATE,
)
RETURN NUMBER DETERMINISTIC
IS
IR_qty NUMBER;
myLocations sys.odcivarchar2list; --collection
BEGIN
IF IR_locn = 'ALL' THEN
myLocations := SYS.ODCIVARCHAR2LIST('D2','D4','D5','D11');
ELSE
myLocations := SYS.ODCIVARCHAR2LIST('D2');
END IF;
IF IR_TYPE = 'O' then
SELECT SUM(QTY)
INTO IR_qty
FROM STOCK_LEDGER
WHERE ITEM_CODE = IR_item
AND LOCATION_CODE IN
(SELECT column_value FROM TABLE(myLocations)
)
AND DOCUMENTDATE <= IR_TILLDATE
AND DOCUMENTDATE >= IR_FROMDATE;
END IF;
IF IR_TYPE = 'C' then
SELECT SUM(QTY)
INTO IR_qty
FROM STOCK_LEDGER
WHERE ITEM_CODE = IR_item
AND LOCATION_CODE IN
(SELECT column_value FROM TABLE(myLocations)
)
AND DOCUMENTDATE <= IR_TILLDATE
AND DOCUMENTDATE >= IR_FROMDATE
AND Some other conditions;;
END IF;
--Some Other Conditions
RETURN (NVL (IR_QTY, 0));
EXCEPTION
WHEN ZERO_DIVIDE THEN
RETURN 0;
END;
This function is called from a query multiple times. For example:
SELECT ITEM_CODE,
ITEM_NAME,
IR.SRG (IM.ITEM_CODE,
'Company1',
'ALL',
'O',
'01/01/2009',
'12/31/2010'),
IR.SRG (IM.ITEM_CODE,
'Company1',
'ALL',
'C',
'01/01/2009',
'12/31/2010')
, -- Function Called with other Conditions
FROM ITEM_MASTER IM
Example, I have around 1500 items, so for each item in the above query, the function is called 2 times, one for 'O' IR_Type and another for 'C' IR_Type. So the function is called a 3000 times. I have 8 different types of IR_Type and around 15000 items. It is called 120000 times which slows the data retrieval for about 2 hours, which is very troublesome.
I need help in retrieving the data by any other proper way which can speed up the report.
Thanks in advance.
See how far you get without using the function.
select item_code
,item_name
,(select sum(qty)
from stock_ledger
where item_code = im.item_code,
and location_code in ('D2', 'D4', 'D5', 'D11')
and documentdate <= to_date(:TO_DATE, 'MM/DD/YYYY')
and documentdate >= to_date(:FROM_DATE, 'MM/DD/YYYY')) as something1
,ir.srg(im.item_code, 'Company1', 'ALL', 'C', '01/01/2009', '12/31/2010')
, -- Function Called with other Conditions
from item_master im
Because of different parameter values you should call it twice but you could use result cache for better performance.
https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:6978972926020
CREATE OR REPLACE FUNCTION IR.SRG(
IR_item IN VARCHAR2,
IR_comp VARCHAR2,
IR_locn VARCHAR2,
IR_Type VARCHAR2,
IR_fromdate DATE,
IR_tilldate DATE,
)
RETURN NUMBER DETERMINISTIC RESULT_CACHE IS
BEGIN
IF IR_locn = 'ALL' THEN
myLocations := SYS.ODCIVARCHAR2LIST('D2','D4','D5','D11');
ELSE
myLocations := SYS.ODCIVARCHAR2LIST('D2');
END IF;
IF IR_TYPE = 'O' then
SELECT SUM(QTY)
INTO IR_qty
FROM STOCK_LEDGER
WHERE ITEM_CODE = IR_item
AND LOCATION_CODE IN
(SELECT column_value FROM TABLE(myLocations)
)
AND DOCUMENTDATE <= IR_TILLDATE
AND DOCUMENTDATE >= IR_FROMDATE;
END IF;
IF IR_TYPE = 'C' then
SELECT SUM(QTY)
INTO IR_qty
FROM STOCK_LEDGER
WHERE ITEM_CODE = IR_item
AND LOCATION_CODE IN
(SELECT column_value FROM TABLE(myLocations)
)
AND DOCUMENTDATE <= IR_TILLDATE
AND DOCUMENTDATE >= IR_FROMDATE
AND Some other conditions;;
END IF;
--Some Other Conditions
RETURN (NVL (IR_QTY, 0));
EXCEPTION
WHEN ZERO_DIVIDE THEN
RETURN 0;
END;