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;