Stored procedure stopped working - sql

I have a problem concerning a stored procedure. The stored procedure i programmed permits a third party provider to insert data into my database. It always worked fin up to 5 days ago when no data gets anymore inserted. I am really a complete rooky with respect to SQL so i do not know where to start investigating what could be the error. Any help, insights and advices are highly appreciated. Thanks in advance. Attached is the code.
create or replace PROCEDURE "GET_DROP_COPY"
(
P_BEGINSTRING IN VARCHAR2
, P_BODYLENGTH IN VARCHAR2
, P_MSGTYPE IN VARCHAR2
, P_MSGSEQNUM IN VARCHAR2
, P_SENDERCOMPID IN VARCHAR2
, P_SENDINGTIME IN VARCHAR2
, P_TARGETCOMPID IN VARCHAR2
, P_TARGETSUBID IN VARCHAR2
, P_AVGPX IN VARCHAR2
, P_CLORDID IN VARCHAR2
, P_CUMQTY IN VARCHAR2
, P_CURRENCY IN CHAR
, P_EXECID IN VARCHAR2
, P_SECURITYIDSOURCE IN NUMBER
, P_LASTPX IN NUMBER
, P_LASTQTY IN NUMBER
, P_ORDERID IN VARCHAR2
, P_ORDERQTY IN NUMBER
, P_ORDSTATUS IN VARCHAR2
, P_PRICE IN NUMBER
, P_ORDTYPE IN VARCHAR2
, P_SECURITYID IN VARCHAR2
, P_SIDE IN VARCHAR2
, P_FIELD55 IN VARCHAR2
, P_TIMEINFORCE IN VARCHAR2
, P_TRANSACTTIME IN VARCHAR2
, P_SETTLTYPE IN VARCHAR2
, P_TRADEDATE IN VARCHAR2
, P_EXDESTINATION IN VARCHAR2
, P_EXECTYPE IN VARCHAR2
, P_LEAVESQTY IN VARCHAR2
, P_SECURITYTYPE IN VARCHAR2
, P_SECONDARYORDERID IN VARCHAR2
, P_SECURITYEXCHANGE IN VARCHAR2
, P_ROUNDLOTBOOK IN NUMBER
, P_COPYMSGINDICATOR IN VARCHAR2
, P_REPEATING_GROUP IN NUMBER
, P_PARTY_ID IN VARCHAR2
, P_PARTYIDSOURCE IN VARCHAR2
, P_PARTYROLE IN NUMBER
, P_PARTYID2 IN VARCHAR2
, P_PARTYIDSOURCE2 IN VARCHAR2
, P_PARTYROLE2 IN NUMBER
, P_PARTYID3 IN VARCHAR2
, P_PARTYIDSOURCE3 IN VARCHAR2
, P_PARTYROLE3 IN NUMBER
, P_CHECKSUM IN NUMBER
) AS
l_count NUMBER;
l_modpor NUMBER(1,0);
l_logid NUMBER;
err_num NUMBER;
err_msg VARCHAR2(100);
BEGIN
SELECT NVL(MAX(ID),0) INTO l_logid
FROM LOG_PROCEDURE;
IF l_logid = 0 THEN
l_logid := 1;
ELSE
l_logid := l_logid + 1;
END IF;
INSERT INTO LOG_PROCEDURE (ID, ETL, INICIO, TRAZA, TABLA)
VALUES(l_logid, 'GET_DROP_COPY', SYSDATE, 'INSERT RECORD. ',
'DROP_COPY');
COMMIT;
INSERT INTO DROP_COPY (BEGINSTRING, BODYLENGTH, MSGTYPE, MSGSEQNUM,
SENDERCOMPID, SENDINGTIME, TARGETCOMPID, TARGETSUBID, AVGPX, CLORDID,
CUMQTY, CURRENCY, EXECID, SECURITYIDSOURCE, LASTPX, LASTQTY, ORDERID,
ORDERQTY, ORDSTATUS, PRICE, ORDTYPE, SECURITYID, SIDE, FIELD55,
TIMEINFORCE, TRANSACTTIME, SETTLTYPE, TRADEDATE, EXDESTINATION,
EXECTYPE, LEAVESQTY, SECURITYTYPE, SECONDARYORDERID, SECURITYEXCHANGE,
ROUNDLOTBOOK, COPYMSGINDICATOR, REPEATING_GROUP, PARTY_ID,
PARTYIDSOURCE, PARTYROLE, PARTYID2, PARTYIDSOURCE2, PARTYROLE2,
PARTYID3, PARTYIDSOURCE3, PARTYROLE3, CHECKSUM)
VALUES(P_BEGINSTRING, P_BODYLENGTH, P_MSGTYPE, P_MSGSEQNUM,
P_SENDERCOMPID, P_SENDINGTIME, P_TARGETCOMPID, P_TARGETSUBID, P_AVGPX,
P_CLORDID, P_CUMQTY, P_CURRENCY, P_EXECID, P_SECURITYIDSOURCE, P_LASTPX,
P_LASTQTY, P_ORDERID, P_ORDERQTY, P_ORDSTATUS, P_PRICE, P_ORDTYPE,
P_SECURITYID, P_SIDE, P_FIELD55, P_TIMEINFORCE, P_TRANSACTTIME,
P_SETTLTYPE, P_TRADEDATE, P_EXDESTINATION, P_EXECTYPE, P_LEAVESQTY,
P_SECURITYTYPE, P_SECONDARYORDERID, P_SECURITYEXCHANGE, P_ROUNDLOTBOOK,
P_COPYMSGINDICATOR, P_REPEATING_GROUP, P_PARTY_ID, P_PARTYIDSOURCE,
P_PARTYROLE, P_PARTYID2, P_PARTYIDSOURCE2, P_PARTYROLE2, P_PARTYID3,
P_PARTYIDSOURCE3, P_PARTYROLE3, P_CHECKSUM);
l_count := TO_CHAR(SQL%ROWCOUNT);
UPDATE LOG_PROCEDURE
SET FIN = SYSDATE,
ESTADO = 'OK',
TRAZA = TRAZA || l_count || ' REGISTRO(s) INSERTADO(s).'
WHERE ID = l_logid;
COMMIT;
IF (P_PARTY_ID IN ('009', '036', '016', '003') OR P_PARTYID2 IN ('009', '036', '016', '003') OR P_PARTYID3 IN ('009', '036', '016', '003')) AND (P_ORDERID NOT LIKE'%SER%') THEN
IF ( P_EXECTYPE NOT IN ('0', '4') AND ((P_PARTYROLE = 7 AND P_PARTY_ID = '058') OR (P_PARTYROLE2 = 7 AND P_PARTYID2 = '058') OR (P_PARTYROLE3 = 7 AND P_PARTYID3 = '058'))) THEN
l_modpor := 1;
ELSE
l_modpor := 0;
END IF;
INSERT INTO EQUITY_PORTFOLIO_DCMOV
( BEGINSTRING, BODYLENGTH, MSGTYPE, MSGSEQNUM, SENDERCOMPID, SENDINGTIME, TARGETCOMPID, TARGETSUBID, AVGPX, CLORDID,
CUMQTY, CURRENCY, EXECID, SECURITYIDSOURCE, LASTPX, LASTQTY, ORDERID, ORDERQTY, ORDSTATUS, PRICE, ORDTYPE, SECURITYID, SIDE, FIELD55,
TIMEINFORCE, TRANSACTTIME, SETTLTYPE, TRADEDATE, EXDESTINATION, EXECTYPE, LEAVESQTY, SECURITYTYPE, SECONDARYORDERID, SECURITYEXCHANGE,
ROUNDLOTBOOK, COPYMSGINDICATOR, REPEATING_GROUP, PARTY_ID, PARTYIDSOURCE, PARTYROLE, PARTYID2, PARTYIDSOURCE2, PARTYROLE2,
PARTYID3, PARTYIDSOURCE3, PARTYROLE3, CHECKSUM, ORIGEN, MODPOR
)
VALUES( P_BEGINSTRING, P_BODYLENGTH, P_MSGTYPE, P_MSGSEQNUM, P_SENDERCOMPID, TO_TIMESTAMP(P_SENDINGTIME, 'YYYYMMDD-HH24:MI:SS.FF3'), P_TARGETCOMPID, P_TARGETSUBID, P_AVGPX,
P_CLORDID, P_CUMQTY, TRIM(P_CURRENCY), P_EXECID, P_SECURITYIDSOURCE, P_LASTPX, P_LASTQTY, P_ORDERID, P_ORDERQTY, P_ORDSTATUS, P_PRICE, P_ORDTYPE,
P_SECURITYID, P_SIDE, P_FIELD55, P_TIMEINFORCE, TO_TIMESTAMP(P_TRANSACTTIME, 'YYYYMMDD-HH24:MI:SS.FF3'), P_SETTLTYPE, P_TRADEDATE, P_EXDESTINATION, P_EXECTYPE, P_LEAVESQTY,
P_SECURITYTYPE, P_SECONDARYORDERID, TRIM(P_SECURITYEXCHANGE), P_ROUNDLOTBOOK, TRIM(P_COPYMSGINDICATOR), P_REPEATING_GROUP, P_PARTY_ID, P_PARTYIDSOURCE,
P_PARTYROLE, P_PARTYID2, P_PARTYIDSOURCE2, P_PARTYROLE2, P_PARTYID3, P_PARTYIDSOURCE3, P_PARTYROLE3, P_CHECKSUM, 'LOCAL', l_modpor
);
SELECT COUNT(*) INTO l_count
FROM EQUITY_PORTFOLIO
WHERE SECURITYID = P_SECURITYID;
IF l_count >= 1 AND l_modpor = 1 THEN
ACTUALIZA_EQUITY_PORTFOLIO (P_ORDERID, P_SECURITYID, P_PRICE, P_ORDERQTY, P_EXECTYPE, P_ORDSTATUS, P_SIDE, TO_TIMESTAMP(P_SENDINGTIME, 'YYYYMMDD-HH24:MI:SS.FF3'), TO_TIMESTAMP(P_TRANSACTTIME, 'YYYYMMDD-HH24:MI:SS.FF3'), P_TRADEDATE, P_LASTPX, P_LASTQTY, l_modpor);
ELSE
IF l_count = 0 THEN
INSERT INTO EQUITY_PORTFOLIO(SECURITYID, SECURITY_ID, ID_ISIN, POSITION, POSITION_INI, AAAAMMDD, CURRENCY)
SELECT P_SECURITYID, EQDES.BLOOMBERG_TICKER, EQDES.ID_ISIN, 0, 0, P_TRADEDATE, CURRENCY
FROM EQUITY_DESCRIPTOR EQDES
WHERE ID_EXCH_SYMBOL = P_SECURITYID;
COMMIT;
ACTUALIZA_EQUITY_PORTFOLIO (P_ORDERID, P_SECURITYID, P_PRICE, P_ORDERQTY, P_EXECTYPE, P_ORDSTATUS, P_SIDE, TO_TIMESTAMP(P_SENDINGTIME, 'YYYYMMDD-HH24:MI:SS.FF3'), TO_TIMESTAMP(P_TRANSACTTIME, 'YYYYMMDD-HH24:MI:SS.FF3'), P_TRADEDATE, P_LASTPX, P_LASTQTY, l_modpor);
END IF;
END IF;
END IF;
EXCEPTION
WHEN OTHERS THEN
err_num := SQLCODE;
err_msg := SUBSTR(SQLERRM, 1, 100);
INSERT INTO DROP_COPY_ERROR (BEGINSTRING, BODYLENGTH, MSGTYPE, MSGSEQNUM,
SENDERCOMPID, SENDINGTIME, TARGETCOMPID, TARGETSUBID, AVGPX, CLORDID,
CUMQTY, CURRENCY, EXECID, SECURITYIDSOURCE, LASTPX, LASTQTY, ORDERID,
ORDERQTY, ORDSTATUS, PRICE, ORDTYPE, SECURITYID, SIDE, FIELD55,
TIMEINFORCE, TRANSACTTIME, SETTLTYPE, TRADEDATE, EXDESTINATION,
EXECTYPE, LEAVESQTY, SECURITYTYPE, SECONDARYORDERID, SECURITYEXCHANGE,
ROUNDLOTBOOK, COPYMSGINDICATOR, REPEATING_GROUP, PARTY_ID,
PARTYIDSOURCE, PARTYROLE, PARTYID2, PARTYIDSOURCE2, PARTYROLE2,
PARTYID3, PARTYIDSOURCE3, PARTYROLE3, CHECKSUM, LOGID)
VALUES(P_BEGINSTRING, P_BODYLENGTH, P_MSGTYPE, P_MSGSEQNUM,
P_SENDERCOMPID, P_SENDINGTIME, P_TARGETCOMPID, P_TARGETSUBID, P_AVGPX,
P_CLORDID, P_CUMQTY, P_CURRENCY, P_EXECID, P_SECURITYIDSOURCE, P_LASTPX,
P_LASTQTY, P_ORDERID, P_ORDERQTY, P_ORDSTATUS, P_PRICE, P_ORDTYPE,
P_SECURITYID, P_SIDE, P_FIELD55, P_TIMEINFORCE, P_TRANSACTTIME,
P_SETTLTYPE, P_TRADEDATE, P_EXDESTINATION, P_EXECTYPE, P_LEAVESQTY,
P_SECURITYTYPE, P_SECONDARYORDERID, P_SECURITYEXCHANGE, P_ROUNDLOTBOOK,
P_COPYMSGINDICATOR, P_REPEATING_GROUP, P_PARTY_ID, P_PARTYIDSOURCE,
P_PARTYROLE, P_PARTYID2, P_PARTYIDSOURCE2, P_PARTYROLE2, P_PARTYID3,
P_PARTYIDSOURCE3, P_PARTYROLE3, P_CHECKSUM, l_logid);
UPDATE LOG_PROCEDURE
SET FIN = SYSDATE,
ESTADO = 'ERROR',
CODERR = err_num,
MSGERR = err_msg
WHERE ID = l_logid;
COMMIT;
END GET_DROP_COPY;
This is the output when i run the procedure:
Connecting to the database CLBCB_TRADER.
ORA-01400: cannot insert NULL into ("CLBCBTRADER"."DROP_COPY_ERROR"."SENDINGTIME")
ORA-06512: at "CLBCBTRADER.GET_DROP_COPY", line 155
ORA-01400: cannot insert NULL into ("CLBCBTRADER"."DROP_COPY"."SENDINGTIME")
ORA-06512: at line 98
Process exited.
Disconnecting from the database CLBCB_TRADER.
Additionally, I should mention that the "SENDINGTIME" variable always looks like this so i dont see a problem: "20141110-13:30:03.394"

Looking at the error message, it seems that parameter P_SENDINGTIME is passed as a NULL value, and this is not a value allowed in your schema definition.
It seems that your third party provider changed something in the last days.
If that parameter was just a timestamp, you could set a default value to it running your script to alter the procedure by setting a default value:
create or replace PROCEDURE "GET_DROP_COPY" (
//...first part definition of script here
, P_SENDINGTIME IN VARCHAR2 := ''
//...rest definition of script here
)
//... body of script here
END GET_DROP_COPY;
Please note that:
you should first of all ask the provider whether they changed
anything
it may be a risky approach if you aren't sure of what that value should be
you may use sysdate to get a proper timestamp value - eg:
...
, P_SENDINGTIME IN VARCHAR2 := TO_CHAR(SYSDATE, 'MM.DD.YYYY HH24:MI:SS')
...

The error is telling you that you are trying to insert a NULL value into the SENDINGTIME field of GET_DROP_COPY. The field does not allow NULL values.
Either:
Insert an actual value
Allow nulls in your column.
You should probably look to the first option as there is probably a reason for the column not allowing nulls.

Related

Select values from table and update them using function in Oracle

I need to set branch_code as IN parameter and then select cms_rungno, cms_finayear from table and assign cms_rungno to a variable and update its value by 1. Then, return the journ_no by below format.
Here's my code I have tried so far. I have no clear idea about this.
FUNCTION GEN_JOURNO
( branch_code IN varchar2 )
RETURN varchar2 IS
journ_no varchar2;
rungno number;
BEGIN
--LAST_NO + 1
SELECT cms_finayear
FROM corpinfo.tblcommonserial a
where cms_brncode=branch_code and cms_code='JOUN'
SELECT cms_rungno INTO rungno
FROM corpinfo.tblcommonserial a
where cms_brncode:=branch_code and cms_code:='JOUN';
UPDATE corpinfo.tblcommonserial a
set cms_rungno:=rungno+1
where cms_brncode:=branch_code and cms_code:='JOUN'
journ_no:=cms_brncode || SUBSTR(TO_CHAR(cms_finayear),3,2)|| LPAD(TO_CHAR(cms_rungno),6,'0');
RETURN journ_no ;
--EXCEPTION
--WHEN exception_name THEN
-- statements ;
END;
This worked for me. Had syntax mistakes in my previous code
FUNCTION GEN_JOURNO
( branch_code IN varchar2 )
RETURN varchar2(5) IS
journ_no varchar2(5);
rungno number;
BEGIN
--LAST_NO + 1
SELECT cms_finayear
FROM corpinfo.tblcommonserial a
where cms_brncode=branch_code and cms_code='JOUN';
SELECT cms_rungno INTO rungno
FROM corpinfo.tblcommonserial a
where cms_brncode=branch_code and cms_code='JOUN';
UPDATE corpinfo.tblcommonserial a
set cms_rungno=rungno+1
where cms_brncode=branch_code and cms_code='JOUN';
journ_no=branch_code || SUBSTR(TO_CHAR(cms_finayear),3,2)|| LPAD(TO_CHAR(cms_rungno),6,'0');
RETURN journ_no ;
--EXCEPTION
--WHEN exception_name THEN
-- statements ;
END;

PL/SQL: ORA-00917 Compilation failed, line 49 (11:56:09) The line numbers associated with

create or replace TRIGGER R_TRACKER_TRI
before insert on R_TRACKER
for each row
declare
v_number varchar2(15);
begin
if inserting then
:NEW.PROJECT_ID := PROJECT_ID(1);
:NEW.PRO_CREATED := LOCALTIMESTAMP;
:NEW.PRO_CREATED_BY := nvl(v('APP_USER'),USER);
IF :NEW.RECRUITMENT_TYPE= 'New' THEN
SELECT ('NEW/'||TO_CHAR(SYSDATE,'YY') || '/' || (NVL(MAX(SUBSTRB(PROJECT_ID,8)),10000)+1)) into v_number
FROM R_TRACKER
WHERE SUBSTRB(PROJECT_ID,1,3) = 'NEW';
:NEW.PROJECT_ID := v_number;
elsif :NEW.RECRUITMENT_TYPE= 'Replacement' THEN
SELECT ('REP/'||TO_CHAR(SYSDATE,'YY') || '/' || (NVL(MAX(SUBSTRB(PROJECT_ID,8)),10000)+1)) into v_number
FROM R_TRACKER
WHERE SUBSTRB(PROJECT_ID,1,3) = 'REP';
:NEW.PROJECT_ID := v_number;
end if;
INSERT INTO R_TRACKER
(
PROJECT_ID,
PRO_LOC,
DESIGNATION,
NO_OF_POSITION,
VACANCY_SINCE,
STATUS,
REMARKS,
UPLOAD,
RECRUITMENT_TYPE,
APPROVAL,
ACTION
)
VALUES
(
:NEW.PROJECT_ID,
:NEW.PRO_LOC,
:NEW.DESIGNATION,
:NEW.NO_OF_POSITION,
:NEW.VACANCY_SINCE,
:NEW.STATUS,
:NEW.REMARKS
:NEW.UPLOAD,
:NEW.RECRUITMENT_TYPE,
:NEW.APPROVAL,
:NEW.ACTION
);
end if;
end;
Looking at your code one can make out that you need to understand the use of Trigger. Please read it. In brief I wanted to tell that trigger is an event on a table. It is created to automate insertion/updation/deletion of column value of that table. In your case you are creating trigger on table R_TRACKER and then again at below inserting into it. This is wrong. See how you can do it.
--Table
CREATE TABLE R_TRACKER
(
PROJECT_ID VARCHAR2 (50),
PRO_LOC VARCHAR2 (50),
DESIGNATION VARCHAR2 (50),
NO_OF_POSITION VARCHAR2 (50),
VACANCY_SINCE VARCHAR2 (50),
STATUS VARCHAR2 (50),
REMARKS VARCHAR2 (50),
UPLOAD VARCHAR2 (50),
RECRUITMENT_TYPE VARCHAR2 (50),
APPROVAL VARCHAR2 (50),
ACTION VARCHAR2 (50)
);
--Trigger on table
CREATE OR REPLACE TRIGGER R_TRACKER_TRI
BEFORE INSERT ON R_TRACKER
FOR EACH ROW
DECLARE
v_number VARCHAR2 (15);
BEGIN
IF INSERTING
THEN
:NEW.PROJECT_ID := '1';--PROJECT_ID(1) -- This seems to be a function in your case;
--:NEW.PRO_CREATED := LOCALTIMESTAMP;
-- :NEW.PRO_CREATED_BY := NVL('APP_USER', USER);
IF :NEW.RECRUITMENT_TYPE = 'New'
THEN
SELECT ( 'NEW/'
|| TO_CHAR (SYSDATE, 'YY')
|| '/'
|| (NVL (MAX (SUBSTRB (PROJECT_ID, 8)), 10000) + 1))
INTO v_number
FROM R_TRACKER
WHERE SUBSTRB (PROJECT_ID, 1, 3) = 'NEW';
:NEW.PROJECT_ID := v_number;
ELSIF :NEW.RECRUITMENT_TYPE = 'Replacement'
THEN
SELECT ( 'REP/'
|| TO_CHAR (SYSDATE, 'YY')
|| '/'
|| (NVL (MAX (SUBSTRB (PROJECT_ID, 8)), 10000) + 1))
INTO v_number
FROM R_TRACKER
WHERE SUBSTRB (PROJECT_ID, 1, 3) = 'REP';
:NEW.PROJECT_ID := v_number;
END IF;
END IF;
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;

oracle date conversion error

I get an error when the input for iv_from_date is given in this format 04/01/2013,it works perfectly when the input is in this format 04/Jan/2013.the nls date format is DD-MON_RR.My input should be in this format 04/01/2013.How do i do this
CREATE OR REPLACE procedure Sp_SaveNewTaxPercentage(iv_category_id number,
iv_tax_percentage number,
iv_from_date varchar2,
iv_to_date varchar2 default '12/31/9998',
iv_created_date date,
ov_err_code out nocopy varchar2,
ov_err_msg out nocopy varchar2) is
lv_category_id varchar2(25);
LV_TO_DATE varchar2(25);
lv_cat_id varchar2(12);
IV_TAX_ID VARCHAR2(12);
lv_tax_percentage varchar(20);
begin
ov_err_code := 0;
SELECT MAX(TAX_ID)
INTO IV_TAX_ID
FROM TAX_P
WHERE CATEGORY_ID IN (iv_category_id);
for J in (SELECT CATEGORY_ID, FROM_DATE, tax_percentage
FROM TAX_P
WHERE TAX_ID = IV_TAX_ID) loop
SELECT to_date(iv_from_date, 'dd/mm/yyyy') - 1
INTO LV_TO_DATE
FROM DUAL;
lv_cat_id := J.CATEGORY_ID;
lv_tax_percentage := j.tax_percentage;
begin
UPDATE TAX_P
SET TO_dATE = LV_TO_DATE
WHERE TAX_PERCENTAGE = lv_tax_percentage
and to_date = iv_to_date;
commit;
insert into tax_p
(TAX_ID,
CATEGORY_ID,
TAX_PERCENTAGE,
FROM_DATE,
TO_DATE,
CREATE_DATE)
values
(tax_seq.nextval,
iv_category_id,
to_char(iv_tax_percentage, '99D99'),
iv_from_date,
iv_to_Date,
sysdate);
commit;
end;
end loop;
IF LV_CAT_ID IS NULL THEN
insert into tax_p
(TAX_ID,
CATEGORY_ID,
TAX_PERCENTAGE,
FROM_DATE,
TO_DATE,
CREATE_DATE)
values
(tax_seq.nextval,
iv_category_id,
to_char(iv_tax_percentage, '99D99'),
iv_from_date,
IV_TO_DATE,
sysdate);
END IF;
commit;
select 'Successfully Saved' into ov_err_msg from dual;
commit;
Exception
when others then
rollback;
ov_err_code := 1;
ov_err_msg := 'Error while saving' || SQLERRM;
end Sp_SaveNewTaxPercentage;
Please avoid using VARCHAR2 type for variables and parameters thar are actually of type DATE. Oracle tries to convert your varchar parameter to date implicitly. When format is the same as set in NLS_DATE_FORMAT it succeeds else it fails. Make both iv_from_date and iv_to_date typed as DATE. If respective columns in table TAX_P are typed as varchar2 then make explicit format conversion in insert statement.

Writing Dynamic Insert or Update in Oracle

I am working on an application that will be used to populate the address details of for employees. The address structure will be different for every country.
For the address style mapping I have a table in which I have mapped all the styles.
I have the following requirement:
As shown in the image, I have an address mapping table in which
col1 is for style (wrt country),
col2 for Field_name (The field to be displayed in front end) and
col3 for column_field_name (The name of the column in which the field in col2 will be stored in transaction table.)
![Mapping table Desc][1]
**ADDRESS_STYLE FIELD_NAME COLUMN_FIELD_NAME**
1 US_GLB Address Line1 ADDRESS_LINE1
2 US_GLB Address Line2 ADDRESS_LINE2
3 US_GLB Zip Code POSTAL_CODE
4 US_GLB Tax Zip Code ADD_INFORMATION17
5 US_GLB City TOWN_OR_CITY
6 US_GLB State REGION_2
7 US_GLB Country COUNTRY
8 US_GLB Tax Jurisdiction ADD_INFORMATION15
9 US_GLB Tax Jurisdiction Other ADD_INFORMATION16
10 US_GLB Telephone TELEPHONE_NUMBER_1
11 US_GLB Telephone2 TELEPHONE_NUMBER_2
Now I have to write a procedure or function which will take the all the in parameters
and insert those in my transaction table as they are mapped in mapping table.
For Ex-(As shown above)
Field Address Line1 will be stored in ADDRESS_LINE1 of transaction table.
Field State will be stored in REGION_2 of transaction table.
So in this Proof of Concept I have made two assumptions (maybe three, depends how you count them).
The target ADDRESSES table has an ID column, populated by a sequence.
The column mappings are always in the same order as the columns in the table's projection
and that order is guaranteed by a sort column on the mapping table.
The first is just a guess and easy enough to fit to whatever your actual process is.
The second assumption has major ramifications, because if you haven't been disciplined about how the data is entered into the mapping table this implementation won't work reliably. You'll need to replace the loop with eleven separate lookups for each value of FIELD_NAME. Obviously that would be far too tedious for me to code.
create or replace procedure pop_addr_details
(i_addr_style mapping_table.address_style%type
, i_Address_Line1 in varchar2
, i_Address_Line2 in varchar2
, i_Zip_Code in varchar2
, i_Tax_Zip Code in varchar2
, i_City in varchar2
, i_State in varchar2
, i_Country in varchar2
, i_Tax_Jurisdiction in varchar2
, i_Tax_Jurisdiction Other in varchar2
, i_Telephone in varchar2
, i_Telephone2 in varchar2 )
is
stmt varchar2(32767);
begin
stmt := 'insert into adddresses values (address_id';
for map_rec in ( select column_field_name
from mapping_table
where address_style = i_addr_style
order by col_order )
loop
stmt := stmt || ',' || map_rec.column_field_name;
end loop;
stmt := stmt || ') values ( address_seq.next_val, :1, :2, :3, :4, :5, :6, :7, :8, :9, :10, :11)';
execute immedate stmt using i_Address_Line1
, i_Address_Line2
, i_Zip_Code
, i_Tax_Zip Code
, i_City
, i_State
, i_Country
, i_Tax_Jurisdiction
, i_Tax_Jurisdiction Other
, i_Telephone
, i_Telephone2;
end pop_addr_details;
/
There's a whole chapter on dynamic SQL in the PL/SQL documentation. Find out more.
------------------------------INSERT PROCEDURE-----------------------------
PROCEDURE GHCM_ADDRESS_INSERT_DTLS_PROC(IN_PERSON_ID PLS_INTEGER,
I_ADDR_STYLE VARCHAR2,
IN_ATRRIBUTE1 VARCHAR2,
IN_ATRRIBUTE2 VARCHAR2,
IN_ATRRIBUTE3 VARCHAR2,
IN_ATRRIBUTE4 VARCHAR2,
IN_ATRRIBUTE5 VARCHAR2,
IN_ATRRIBUTE6 VARCHAR2,
IN_ATRRIBUTE7 VARCHAR2,
IN_ATRRIBUTE8 VARCHAR2,
IN_ATRRIBUTE9 VARCHAR2,
IN_ATRRIBUTE10 VARCHAR2,
IN_ATRRIBUTE11 VARCHAR2,
IN_ATRRIBUTE12 VARCHAR2,
IN_ATRRIBUTE13 VARCHAR2,
IN_ATRRIBUTE14 VARCHAR2,
IN_ATRRIBUTE15 VARCHAR2,
IN_ATRRIBUTE16 VARCHAR2,
IN_ATRRIBUTE17 VARCHAR2,
OUT_SUCCESS OUT VARCHAR2)
IS
V_STATEMENT VARCHAR2(1000);
V_SEQ_ID PLS_INTEGER;
BEGIN
V_STATEMENT := 'INSERT INTO PER_ADDRESS_TEST (ADDRESS_ID,STYLE,IN_PERSON_ID';
FOR MAP_REC IN (SELECT COLUMN_FIELD_NAME
FROM GHCM_ADDRESS_STYLE_MAPING_TBL
WHERE STYLE = I_ADDR_STYLE
AND DISPLAY_FLAG = 'Y'
AND ENABLED_FLAG = 'Y'
AND MAPPING_DESC = 'Address Structure'
ORDER BY DISPLAY_ORDER_NO) LOOP
V_STATEMENT := V_STATEMENT || ',' || MAP_REC.COLUMN_FIELD_NAME;
END LOOP;
FOR MAP_REC IN (SELECT DISTINCT (COLUMN_FIELD_NAME)
FROM GHCM_ADDRESS_STYLE_MAPING_TBL
WHERE COLUMN_FIELD_NAME NOT IN
(SELECT COLUMN_FIELD_NAME
FROM GHCM_ADDRESS_STYLE_MAPING_TBL
WHERE STYLE = I_ADDR_STYLE
AND DISPLAY_FLAG = 'Y'
AND ENABLED_FLAG = 'Y'
AND MAPPING_DESC = 'Address Structure')) LOOP
V_STATEMENT := V_STATEMENT || ',' || MAP_REC.COLUMN_FIELD_NAME;
END LOOP;
V_STATEMENT := V_STATEMENT ||
') values ( :1, :2, :3, :4, :5, :6, :7, :8, :9,:10,:11,:12,:13,:14,:15,:16,:17,:18,:19,:20)';
V_SEQ_ID := ADDRESS_SEQ_TEST.NEXTVAL;
EXECUTE IMMEDIATE V_STATEMENT
USING V_SEQ_ID, I_ADDR_STYLE, IN_PERSON_ID, IN_ATRRIBUTE1, IN_ATRRIBUTE2, IN_ATRRIBUTE3, IN_ATRRIBUTE4, IN_ATRRIBUTE5, IN_ATRRIBUTE6, IN_ATRRIBUTE7, IN_ATRRIBUTE8, IN_ATRRIBUTE9, IN_ATRRIBUTE10, IN_ATRRIBUTE11, IN_ATRRIBUTE12, IN_ATRRIBUTE13, IN_ATRRIBUTE14, IN_ATRRIBUTE15, IN_ATRRIBUTE16, IN_ATRRIBUTE17;
COMMIT;
OUT_SUCCESS := 'Y';
END;