Exception handling PL SQL - sql

My Application has following two procedure which handles the entire transaction.
But when my nested procedure throws an exception the CRUD operation performed in outer procedure could not get roll back. Please help me to re arrange it or how could I write in better way so that I can roll back my transaction.
PROCEDURE SP_SEND_CASE_NEXT_LEVEL
(
p_wfId IN NUMBER,
p_assessmentId IN NUMBER,
p_prevLevelId IN NUMBER,
p_appType IN NUMBER,
p_sequenceNumber IN NUMBER,
p_subSequenceNumber IN NUMBER,
p_userCode IN VARCHAR2,
p_companyCode IN VARCHAR2,
p_camNumber IN VARCHAR2,
p_reviewType IN NUMBER,
p_unitType IN NUMBER,
p_regionCode IN NUMBER,
p_caseType IN VARCHAR2,
p_isApproved IN VARCHAR2,
p_fromUserCode IN VARCHAR2,
P_ERRORDETAIL OUT VARCHAR2
) IS
V_Newlevelid NUMBER(8);
V_NewWfId NUMBER(8);
v_StepCompleted NUMBER(2);
v_caseComplete VARCHAR2(1);
v_isStepComplete VARCHAR2(1);
v_isCompanyPicked VARCHAR2(1);
v_subUserInWorkflow NUMBER(1);
v_isPresent NUMBER(1);
v_inConsistentWorkFlow VARCHAR2(2);
v_subUserCode VARCHAR2(8);
v_errmsg VARCHAR2(50);
v_userDP NUMBER(10, 2);
v_sql VARCHAR2(2000);
v_sub_seq_no NUMBER(8);
v_reversalSequenceNo NUMBER(4);
v_reversalAppType NUMBER(2);
v_NewCourierId NUmber(8);
v_courierCount NUMBER(1);
v_revSequenceNo NUMBER(4);
v_courierComments VARCHAR2(4000);
v_required_count NUMBER(2);
v_sessionPriority NUMBER(1);
v_customRequiredCount NUMBER(1);
BEGIN
p_errorDetail := 'Failure';
v_inConsistentWorkFlow := 'N';
v_reversalAppType := 0;
v_revSequenceNo :=0;
v_courierComments := '';
v_customRequiredCount := 0;
SAVEPOINT Start_Tran;
BEGIN
-- update aph_comp_leveldetails for initiator of case
UPDATE Aph_Comp_Leveldetails
SET Case_Complete = 'Y',
End_Date = Sysdate,
Is_Step_Complete = 'Y',
is_approved = p_isApproved
WHERE User_Code = p_userCode
AND Assessmentid = p_assessmentId
and levelid = p_prevlevelid;
-- update Aph_Comp_Header for case status
UPDATE Aph_Comp_Header
SET CASE_STATUS_DESC = 'Pending',
COMP_REVERSE = 'N'
WHERE Assessmentid = p_assessmentId;
-- update MST_TAT_CALC set case end time for previous level user
UPDATE MST_TAT_CALC
SET CASE_END_TIME = sysdate,
RULE_END_TIME = sysdate,
days = fn_get_days(RULE_START_TIME, sysdate, REASON)
WHERE User_Code = p_userCode -- TODO : to be removed
and LEVELID = p_prevLevelId
AND ASSESSMENTID = p_assessmentId
and reason <> 'C' and CASE_END_TIME is null;
-------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------
SELECT COUNT(CASE_COMPLETE) into v_required_count
FROM APH_COMP_LEVELDETAILS
WHERE ASSESSMENTID = p_assessmentid
AND SEQ_NO = p_sequenceNumber
AND APP_TYPE = p_appType
and COMP_REVERSE = 'N'
and COMP_WITHDRAWN = 'N'
and COMP_REJECTED = 'N';
SELECT COUNT(CASE_COMPLETE) into v_StepCompleted
FROM APH_COMP_LEVELDETAILS
WHERE ASSESSMENTID = p_assessmentid
AND SEQ_NO = p_sequenceNumber
AND APP_TYPE = p_appType
AND CASE_COMPLETE = 'Y'
and COMP_REVERSE = 'N'
and COMP_WITHDRAWN = 'N'
and COMP_REJECTED = 'N';
BEGIN
-- aph_comp_leveldetails
INSERT INTO aph_comp_leveldetails
(WF_ID,
ASSESSMENTID,
LEVELID,
User_Code,
Case_Complete,
COMP_FROMUSER,
SEQ_NO,
SUB_SEQ_NO,
COMP_TOUSER,
Start_Date,
IS_STEP_COMPLETE,
Is_Company_Picked,
App_Type,
WORK_FLOW_USER)
VALUES
(Send.Wf_Id,
p_assessmentId,
V_Newlevelid,
USER_ON_HOLIDAY.User_code,
'N',
--send.user_id,
P_USERCODE,
Send.Sequence_No,
v_sub_seq_no,
USER_ON_HOLIDAY.User_code,
Sysdate,
'N',
'N',
Send.App_Type,
Send.user_id);
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
v_errmsg := 'Unable to insert into aph_comp_leveldetails as previous level step not completed';
RETURN;
END;
-------------------------------------------------------------------------------------------------
BEGIN
-- check if user is alreadily part of workflow.
SELECT COUNT(*)
INTO v_isPresent
FROM aph_wf_user
WHERE ASSESSMENTID = P_ASSESSMENTID
and USER_ID = USER_ON_HOLIDAY.USER_CODE
and is_wf_user = 'Y';
END;
-------------------------------------------------------------------------------------------------
IF v_isPresent = 0 THEN
-- if user is not alreadily part of workflow then insert into aph_wf_user.
BEGIN
-- insert in aph_wf_user
INSERT INTO aph_wf_user
(WF_ID,
ASSESSMENTID,
USER_ID,
SEQUENCE_NO,
APP_TYPE,
IS_EDITABLE,
USER_DP,
UNIT_TYPE,
CREATED_BY,
CREATION_DATE)
VALUES
(V_NewWfId,
P_ASSESSMENTID,
USER_ON_HOLIDAY.user_code,
Send.Sequence_No,
send.app_type,
'N',
v_userDP,
send.unit_type,
P_USERCODE,
sysdate);
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
v_errmsg := 'Unable to insert into aph_comp_leveldetails as previous level step not completed';
RETURN;
END;
END IF; -- end of if v_isPresent = 0
-------------------------------------------------------------------------------------------------
BEGIN
--mst_tat_calc
INSERT INTO mst_tat_calc
(ASSESSMENTID,
LEVELID,
COMPANY_CODE,
USER_CODE,
REASON,
CASE_START_TIME,
CASE_END_TIME,
RULE_START_TIME,
RULE_END_TIME,
CAM_NUMBER,
REVIEW_TYPE,
UNIT_TYPE,
REGION_CODE,
LEVELID_COURIER_TO)
VALUES
(P_ASSESSMENTID,
/*p_prevLevelId,*/
V_NEWLEVELID,
P_COMPANYCODE,
/*p_userCode,*/
USER_ON_HOLIDAY.user_code,
'C',--This should be value of enum CommonActionEnum.COURIER
sysdate,
null,
sysdate,
null,
p_camNumber,
p_reviewType,
p_unitType,
P_REGIONCODE,
/*V_Newlevelid*/
p_prevLevelId
);
-------------------------------------------------------------------------------------------------
INSERT INTO mst_tat_calc
(ASSESSMENTID,
LEVELID,
COMPANY_CODE,
USER_CODE,
REASON,
CASE_START_TIME,
RULE_START_TIME,
CAM_NUMBER,
REVIEW_TYPE,
UNIT_TYPE,
REGION_CODE,
DAYS)
VALUES
(P_ASSESSMENTID,
V_NEWLEVELID,
p_companyCode,
USER_ON_HOLIDAY.user_code,
'N',--This should be value of enum CommonActionEnum.NORMAL_APPROVAL
sysdate,
fn_get_rule_date(sysdate),
p_camNumber,
p_reviewType,
p_unitType,
p_regionCode,
0);
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
v_errmsg := 'Unable to insert into mst_tat_calc as normal approver';
RETURN;
END;
-------------------------------------------------------------------------------------------------
-- Check for if user has any courier
BEGIN
-- update in aph_user_Courier as courier status sent and sent date
SELECT COUNT(1)
INTO v_courierCount
FROM aph_user_courier
WHERE assessmentid = p_assessmentid
AND touser = USER_ON_HOLIDAY.User_code
AND levelid = p_prevlevelid;
if v_courierCount = 0 then
begin
Pack_Aph_Getid.Proc_Aph_Getid('APH_USER_COURIER','COURIER_ID', v_NewCourierId); -- generate courier id.
end;
INSERT
INTO APH_USER_COURIER
(
COURIER_ID,
ASSESSMENTID,
LEVELID,
FROMUSER,
TOUSER,
FROMUSER_COMMENTS,
TOUSER_COMMENTS,
FROMCOURIER_STATUS,
TOCOURIER_STATUS,
FROM_DATETIME,
TO_DATETIME,
DOCUMENTRECEIVED,
RECEIVEDDATE
)
--values (v_NewCourierId, p_assessmentid, V_Newlevelid, p_usercode, Send.User_Id, null, null, 'SENT' , null , sysdate , null, null, null);
VALUES
(
v_NewCourierId,
p_assessmentid,
V_Newlevelid,
p_usercode,
USER_ON_HOLIDAY.User_code,
v_courierComments,
NULL,
'SENT' ,
NULL ,
sysdate ,
NULL,
NULL,
NULL
);
else
UPDATE aph_user_Courier
SET fromcourier_status = 'SENT',
tocourier_status = null,
FROM_DATETIME = SYSDATE
WHERE assessmentid = p_assessmentid
AND levelid = p_prevlevelid
--AND touser = Send.User_Id;
AND touser = USER_ON_HOLIDAY.User_code
end if;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
v_errmsg := 'Unable to update aph_user_Courier';
RETURN;
END;
BEGIN
SP_COMMON_INSERTS(p_assessmentId, p_prevLevelId, V_Newlevelid, 'N', 'N',0,'0','N', p_errorDetail)
EXCEPTION
WHEN OTHERS THEN
p_Errordetail := 'Error in common';
ROLLBACK;
END;
BEGIN
UPDATE APH_WF_USER set IS_EDITABLE = 'N' where USER_ID = Send.User_Id and ASSESSMENTID = p_assessmentId;
END;
END;
END SP_SEND_CASE_NEXT_LEVEL;
Procedure Sp_Common_Inserts
(
--p_wfId In Number,
p_assessmentId In Number,
p_prevLevelId In Number,
p_Newlevelid in number,
p_withdraw in varchar2,
p_rejected in varchar2,
p_prevAssessmentId in Number,
p_borrowerCode in varchar2,
p_srm_lcr in varchar2,
p_errorDetail Out Varchar2
) Is
v_wfId Number(8);
V_Errmsg Varchar2(50);
v_initiatorUserCode varchar2(50);
V_SrNo Number(8);
Begin
-- Savepoint Start_Tran1;
if p_withdraw = 'N' and p_rejected = 'N' then
begin
-- APH_ASSESSMENT_PARAMETER
INSERT INTO APH_ASSESSMENT_PARAMETER
(
SR_NO,
ASSESSMENTID,
LEVELID,
CAM_DATE,
REVISION_DATE,
SRM_EXPIRY_DATE,
PART_PROGRAM,
PRODUCT_PROGRAM,
PRODUCT_PROGRM_EXPOSURE,
PROGRM_PARAMETERS_ADHERED,
IS_SEPARETE_APPROVER,
CASH_BACKED_EXPOSURE,
EXPOSURE_GURANTED,
CLIMS_ID,
CAM_LOGIN_DATE,
BORROWER_RATING,
RATING_TYPE,
RATING_FINALISATION_DATE,
INITIAL_LABELLING_DATE,
CURRENT_REVIEW_DATE,
LABEL_REVIEW_TYPE,
LABEL,
LAST_CLIENT_CALL_DATE,
CALLED_ON_DATE,
INTERFACE_DATE,
COMP_CODE
) SELECT
SR_NO,
p_assessmentId,
p_Newlevelid,
CAM_DATE,
REVISION_DATE,
SRM_EXPIRY_DATE,
PART_PROGRAM,
PRODUCT_PROGRAM,
PRODUCT_PROGRM_EXPOSURE,
PROGRM_PARAMETERS_ADHERED,
IS_SEPARETE_APPROVER,
CASH_BACKED_EXPOSURE,
EXPOSURE_GURANTED,
CLIMS_ID,
CAM_LOGIN_DATE,
BORROWER_RATING,
RATING_TYPE,
RATING_FINALISATION_DATE,
INITIAL_LABELLING_DATE,
CURRENT_REVIEW_DATE,
LABEL_REVIEW_TYPE,
LABEL,
LAST_CLIENT_CALL_DATE,
CALLED_ON_DATE,
INTERFACE_DATE,
COMP_CODE
From APH_ASSESSMENT_PARAMETER
Where Levelid = p_prevlevelid;
Exception
When No_Data_Found Then
rollback;
v_errmsg := 'Unable to insert into APH_ADDENDUM_DETAILS as no data found at previous level';
return;
end;
end if;
IF P_WITHDRAW = 'Y' or P_REJECTED = 'Y' THEN
--APH_APPRAISAL_DETAILS
begin
INSERT INTO APH_APPRAISAL_DETAILS
(
ASSESSMENTID,
COMPANY_CODE,
CAM_FORMAT_ID,
FILE_NAME,
ORDER_ID,
REPORTS_HTML_CONTENTS,
SR_NO
)SELECT
p_assessmentId,
COMPANY_CODE,
CAM_FORMAT_ID,
FILE_NAME,
ORDER_ID,
REPORTS_HTML_CONTENTS,
SR_NO
FROM APH_APPRAISAL_DETAILS
WHERE ASSESSMENTID = P_prevAssessmentId
AND FILE_NAME NOT IN (SELECT FILE_NAME FROM APH_FTL_DETAILS WHERE FTL_ID IN(29,30,31));
Exception
When No_Data_Found Then
rollback;
v_errmsg := 'Unable to insert into APH_BORROWER_DETAILS as no data found at previous level';
Return;
End;
END IF;
p_Errordetail:='SUCCESS';
Exception
When Others Then
Rollback;
p_Errordetail :=v_errmsg;
End Sp_Common_Inserts;
Please let me know how to handle exception in above two procedures if nested procedure sp_common_insert throws an exception.

Instead of using RETURN, use RAISE instead. That way, the error encountered in your sub blocks will also trigger the exception that sets the value of p_Errordetail in your main block. Another thing is that you don't have an EXCEPTION block in SP_SEND_CASE_NEXT_LEVEL procedure's main block. Here's a revision of your code:
PROCEDURE SP_SEND_CASE_NEXT_LEVEL
(
p_wfId IN NUMBER,
p_assessmentId IN NUMBER,
p_prevLevelId IN NUMBER,
p_appType IN NUMBER,
p_sequenceNumber IN NUMBER,
p_subSequenceNumber IN NUMBER,
p_userCode IN VARCHAR2,
p_companyCode IN VARCHAR2,
p_camNumber IN VARCHAR2,
p_reviewType IN NUMBER,
p_unitType IN NUMBER,
p_regionCode IN NUMBER,
p_caseType IN VARCHAR2,
p_isApproved IN VARCHAR2,
p_fromUserCode IN VARCHAR2,
P_ERRORDETAIL OUT VARCHAR2
) IS
V_Newlevelid NUMBER(8);
V_NewWfId NUMBER(8);
v_StepCompleted NUMBER(2);
v_caseComplete VARCHAR2(1);
v_isStepComplete VARCHAR2(1);
v_isCompanyPicked VARCHAR2(1);
v_subUserInWorkflow NUMBER(1);
v_isPresent NUMBER(1);
v_inConsistentWorkFlow VARCHAR2(2);
v_subUserCode VARCHAR2(8);
v_errmsg VARCHAR2(50);
v_userDP NUMBER(10, 2);
v_sql VARCHAR2(2000);
v_sub_seq_no NUMBER(8);
v_reversalSequenceNo NUMBER(4);
v_reversalAppType NUMBER(2);
v_NewCourierId NUmber(8);
v_courierCount NUMBER(1);
v_revSequenceNo NUMBER(4);
v_courierComments VARCHAR2(4000);
v_required_count NUMBER(2);
v_sessionPriority NUMBER(1);
v_customRequiredCount NUMBER(1);
BEGIN
p_errorDetail := 'Failure';
v_inConsistentWorkFlow := 'N';
v_reversalAppType := 0;
v_revSequenceNo :=0;
v_courierComments := '';
v_customRequiredCount := 0;
SAVEPOINT Start_Tran;
BEGIN
-- update aph_comp_leveldetails for initiator of case
UPDATE Aph_Comp_Leveldetails
SET Case_Complete = 'Y',
End_Date = Sysdate,
Is_Step_Complete = 'Y',
is_approved = p_isApproved
WHERE User_Code = p_userCode
AND Assessmentid = p_assessmentId
and levelid = p_prevlevelid;
-- update Aph_Comp_Header for case status
UPDATE Aph_Comp_Header
SET CASE_STATUS_DESC = 'Pending',
COMP_REVERSE = 'N'
WHERE Assessmentid = p_assessmentId;
-- update MST_TAT_CALC set case end time for previous level user
UPDATE MST_TAT_CALC
SET CASE_END_TIME = sysdate,
RULE_END_TIME = sysdate,
days = fn_get_days(RULE_START_TIME, sysdate, REASON)
WHERE User_Code = p_userCode -- TODO : to be removed
and LEVELID = p_prevLevelId
AND ASSESSMENTID = p_assessmentId
and reason <> 'C' and CASE_END_TIME is null;
-------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------
SELECT COUNT(CASE_COMPLETE) into v_required_count
FROM APH_COMP_LEVELDETAILS
WHERE ASSESSMENTID = p_assessmentid
AND SEQ_NO = p_sequenceNumber
AND APP_TYPE = p_appType
and COMP_REVERSE = 'N'
and COMP_WITHDRAWN = 'N'
and COMP_REJECTED = 'N';
SELECT COUNT(CASE_COMPLETE) into v_StepCompleted
FROM APH_COMP_LEVELDETAILS
WHERE ASSESSMENTID = p_assessmentid
AND SEQ_NO = p_sequenceNumber
AND APP_TYPE = p_appType
AND CASE_COMPLETE = 'Y'
and COMP_REVERSE = 'N'
and COMP_WITHDRAWN = 'N'
and COMP_REJECTED = 'N';
BEGIN
-- aph_comp_leveldetails
INSERT INTO aph_comp_leveldetails
(WF_ID,
ASSESSMENTID,
LEVELID,
User_Code,
Case_Complete,
COMP_FROMUSER,
SEQ_NO,
SUB_SEQ_NO,
COMP_TOUSER,
Start_Date,
IS_STEP_COMPLETE,
Is_Company_Picked,
App_Type,
WORK_FLOW_USER)
VALUES
(Send.Wf_Id,
p_assessmentId,
V_Newlevelid,
USER_ON_HOLIDAY.User_code,
'N',
--send.user_id,
P_USERCODE,
Send.Sequence_No,
v_sub_seq_no,
USER_ON_HOLIDAY.User_code,
Sysdate,
'N',
'N',
Send.App_Type,
Send.user_id);
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
v_errmsg := 'Unable to insert into aph_comp_leveldetails as previous level step not completed';
RAISE;
END;
-------------------------------------------------------------------------------------------------
BEGIN
-- check if user is alreadily part of workflow.
SELECT COUNT(*)
INTO v_isPresent
FROM aph_wf_user
WHERE ASSESSMENTID = P_ASSESSMENTID
and USER_ID = USER_ON_HOLIDAY.USER_CODE
and is_wf_user = 'Y';
END;
-------------------------------------------------------------------------------------------------
IF v_isPresent = 0 THEN
-- if user is not alreadily part of workflow then insert into aph_wf_user.
BEGIN
-- insert in aph_wf_user
INSERT INTO aph_wf_user
(WF_ID,
ASSESSMENTID,
USER_ID,
SEQUENCE_NO,
APP_TYPE,
IS_EDITABLE,
USER_DP,
UNIT_TYPE,
CREATED_BY,
CREATION_DATE)
VALUES
(V_NewWfId,
P_ASSESSMENTID,
USER_ON_HOLIDAY.user_code,
Send.Sequence_No,
send.app_type,
'N',
v_userDP,
send.unit_type,
P_USERCODE,
sysdate);
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
v_errmsg := 'Unable to insert into aph_comp_leveldetails as previous level step not completed';
RAISE;
END;
END IF; -- end of if v_isPresent = 0
-------------------------------------------------------------------------------------------------
BEGIN
--mst_tat_calc
INSERT INTO mst_tat_calc
(ASSESSMENTID,
LEVELID,
COMPANY_CODE,
USER_CODE,
REASON,
CASE_START_TIME,
CASE_END_TIME,
RULE_START_TIME,
RULE_END_TIME,
CAM_NUMBER,
REVIEW_TYPE,
UNIT_TYPE,
REGION_CODE,
LEVELID_COURIER_TO)
VALUES
(P_ASSESSMENTID,
/*p_prevLevelId,*/
V_NEWLEVELID,
P_COMPANYCODE,
/*p_userCode,*/
USER_ON_HOLIDAY.user_code,
'C',--This should be value of enum CommonActionEnum.COURIER
sysdate,
null,
sysdate,
null,
p_camNumber,
p_reviewType,
p_unitType,
P_REGIONCODE,
/*V_Newlevelid*/
p_prevLevelId
);
-------------------------------------------------------------------------------------------------
INSERT INTO mst_tat_calc
(ASSESSMENTID,
LEVELID,
COMPANY_CODE,
USER_CODE,
REASON,
CASE_START_TIME,
RULE_START_TIME,
CAM_NUMBER,
REVIEW_TYPE,
UNIT_TYPE,
REGION_CODE,
DAYS)
VALUES
(P_ASSESSMENTID,
V_NEWLEVELID,
p_companyCode,
USER_ON_HOLIDAY.user_code,
'N',--This should be value of enum CommonActionEnum.NORMAL_APPROVAL
sysdate,
fn_get_rule_date(sysdate),
p_camNumber,
p_reviewType,
p_unitType,
p_regionCode,
0);
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
v_errmsg := 'Unable to insert into mst_tat_calc as normal approver';
RAISE;
END;
-------------------------------------------------------------------------------------------------
-- Check for if user has any courier
BEGIN
-- update in aph_user_Courier as courier status sent and sent date
SELECT COUNT(1)
INTO v_courierCount
FROM aph_user_courier
WHERE assessmentid = p_assessmentid
AND touser = USER_ON_HOLIDAY.User_code
AND levelid = p_prevlevelid;
if v_courierCount = 0 then
begin
Pack_Aph_Getid.Proc_Aph_Getid('APH_USER_COURIER','COURIER_ID', v_NewCourierId); -- generate courier id.
end;
INSERT
INTO APH_USER_COURIER
(
COURIER_ID,
ASSESSMENTID,
LEVELID,
FROMUSER,
TOUSER,
FROMUSER_COMMENTS,
TOUSER_COMMENTS,
FROMCOURIER_STATUS,
TOCOURIER_STATUS,
FROM_DATETIME,
TO_DATETIME,
DOCUMENTRECEIVED,
RECEIVEDDATE
)
--values (v_NewCourierId, p_assessmentid, V_Newlevelid, p_usercode, Send.User_Id, null, null, 'SENT' , null , sysdate , null, null, null);
VALUES
(
v_NewCourierId,
p_assessmentid,
V_Newlevelid,
p_usercode,
USER_ON_HOLIDAY.User_code,
v_courierComments,
NULL,
'SENT' ,
NULL ,
sysdate ,
NULL,
NULL,
NULL
);
else
UPDATE aph_user_Courier
SET fromcourier_status = 'SENT',
tocourier_status = null,
FROM_DATETIME = SYSDATE
WHERE assessmentid = p_assessmentid
AND levelid = p_prevlevelid
--AND touser = Send.User_Id;
AND touser = USER_ON_HOLIDAY.User_code
end if;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
v_errmsg := 'Unable to update aph_user_Courier';
RAISE;
END;
BEGIN
SP_COMMON_INSERTS(p_assessmentId, p_prevLevelId, V_Newlevelid, 'N', 'N',0,'0','N', p_errorDetail)
EXCEPTION
WHEN OTHERS THEN
p_Errordetail := 'Error in common';
ROLLBACK;
END;
BEGIN
UPDATE APH_WF_USER set IS_EDITABLE = 'N' where USER_ID = Send.User_Id and ASSESSMENTID = p_assessmentId;
END;
END;
Exception
When Others Then
Rollback;
p_Errordetail :=v_errmsg;
END SP_SEND_CASE_NEXT_LEVEL;
Procedure Sp_Common_Inserts
(
--p_wfId In Number,
p_assessmentId In Number,
p_prevLevelId In Number,
p_Newlevelid in number,
p_withdraw in varchar2,
p_rejected in varchar2,
p_prevAssessmentId in Number,
p_borrowerCode in varchar2,
p_srm_lcr in varchar2,
p_errorDetail Out Varchar2
) Is
v_wfId Number(8);
V_Errmsg Varchar2(50);
v_initiatorUserCode varchar2(50);
V_SrNo Number(8);
Begin
-- Savepoint Start_Tran1;
if p_withdraw = 'N' and p_rejected = 'N' then
begin
-- APH_ASSESSMENT_PARAMETER
INSERT INTO APH_ASSESSMENT_PARAMETER
(
SR_NO,
ASSESSMENTID,
LEVELID,
CAM_DATE,
REVISION_DATE,
SRM_EXPIRY_DATE,
PART_PROGRAM,
PRODUCT_PROGRAM,
PRODUCT_PROGRM_EXPOSURE,
PROGRM_PARAMETERS_ADHERED,
IS_SEPARETE_APPROVER,
CASH_BACKED_EXPOSURE,
EXPOSURE_GURANTED,
CLIMS_ID,
CAM_LOGIN_DATE,
BORROWER_RATING,
RATING_TYPE,
RATING_FINALISATION_DATE,
INITIAL_LABELLING_DATE,
CURRENT_REVIEW_DATE,
LABEL_REVIEW_TYPE,
LABEL,
LAST_CLIENT_CALL_DATE,
CALLED_ON_DATE,
INTERFACE_DATE,
COMP_CODE
) SELECT
SR_NO,
p_assessmentId,
p_Newlevelid,
CAM_DATE,
REVISION_DATE,
SRM_EXPIRY_DATE,
PART_PROGRAM,
PRODUCT_PROGRAM,
PRODUCT_PROGRM_EXPOSURE,
PROGRM_PARAMETERS_ADHERED,
IS_SEPARETE_APPROVER,
CASH_BACKED_EXPOSURE,
EXPOSURE_GURANTED,
CLIMS_ID,
CAM_LOGIN_DATE,
BORROWER_RATING,
RATING_TYPE,
RATING_FINALISATION_DATE,
INITIAL_LABELLING_DATE,
CURRENT_REVIEW_DATE,
LABEL_REVIEW_TYPE,
LABEL,
LAST_CLIENT_CALL_DATE,
CALLED_ON_DATE,
INTERFACE_DATE,
COMP_CODE
From APH_ASSESSMENT_PARAMETER
Where Levelid = p_prevlevelid;
Exception
When No_Data_Found Then
rollback;
v_errmsg := 'Unable to insert into APH_ADDENDUM_DETAILS as no data found at previous level';
RAISE;
end;
end if;
IF P_WITHDRAW = 'Y' or P_REJECTED = 'Y' THEN
--APH_APPRAISAL_DETAILS
begin
INSERT INTO APH_APPRAISAL_DETAILS
(
ASSESSMENTID,
COMPANY_CODE,
CAM_FORMAT_ID,
FILE_NAME,
ORDER_ID,
REPORTS_HTML_CONTENTS,
SR_NO
)SELECT
p_assessmentId,
COMPANY_CODE,
CAM_FORMAT_ID,
FILE_NAME,
ORDER_ID,
REPORTS_HTML_CONTENTS,
SR_NO
FROM APH_APPRAISAL_DETAILS
WHERE ASSESSMENTID = P_prevAssessmentId
AND FILE_NAME NOT IN (SELECT FILE_NAME FROM APH_FTL_DETAILS WHERE FTL_ID IN(29,30,31));
Exception
When No_Data_Found Then
rollback;
v_errmsg := 'Unable to insert into APH_BORROWER_DETAILS as no data found at previous level';
RAISE;
End;
END IF;
p_Errordetail:='SUCCESS';
Exception
When Others Then
Rollback;
p_Errordetail :=v_errmsg;
End Sp_Common_Inserts;

Related

Stored Procedure (rookie programmer), What's wrong with my code?

I'm trying to create a stored procedure that will update a related row in the BugIt table given an expense report number ErepNo and expense category number EXNo.
The procedure must contain 3 input parameters EXNo ,ErepNo and the 'rUpAm' and with one boolean output parameter aRes.
If the ErepStatus is equal to 'Approved' then the stored value rUpAm is added to BIAct,the output parameter is set to TRUE and the row is updated.
Else the ErepStatus is equal to 'Denied' or 'Pending' an application error is raised and the output parameter is set to FALSE.
Here is what I have tried so far
CREATE OR REPLACE PROCEDURE StoredProcedure1
(tEXNo IN BugIt.EXNo%TYPE,
tErepNo IN ER.ErepNo%TYPE,
rUpAm IN INTEGER,
aRes OUT BOOLEAN ) IS
FOUND BOOLEAN := False;
tErepStatus ER.ErepStatus%TYPE;
tBIAct BugIt.BIAct%TYPE;
CURSOR ERCur(TmpErepNo ExpI.ErepNo%TYPE)is
SELECT ExpI.EXNo, ER.ErepStatus
FROM ER, BugIt, ExpI
WHERE ER.ErepNo = tErepNo
AND BugIt.EXNo = ExpI.EXNo
AND ER.ErepNo = ExpI.ErepNo
ORDER BY ErepStatus DESC;
BEGIN
OPEN ERCur(tErepNo);
LOOP
FETCH ERCur INTO tErepStatus, tBIAct;
EXIT WHEN ERCur%NOTFOUND;
IF tErepStatus = 'APPROVED' THEN
FOUND := TRUE;
END IF;
IF tErepStatus = 'PENDING' OR tErepStatus = 'DENIED' THEN
FOUND := False;
EXIT;
END IF;
END LOOP;
CLOSE ERCur;
IF FOUND THEN
tBIAct := tBIAct + rUpAm;
aRes := TRUE;
UPDATE BugIt
Set BIAct = tBIAct
WHere EXNo = tEXNo;
ElSE
tBIAct := tBIAct;
aRes := False;
END IF;
EXCEPTION
WHEN OTHERS THEN aRes := False;
raise_application_error(-20001, 'Database error');
END;
/
Here is my test case to implement the code that I have, which keeps coming up with errors(below)
---test--
SET Serveroutput on;
SELECT ExpI.EXNo, ER.ErepStatus
FROM ER, BugIt, ExpI
WHERE ER.ErepNo = 21
AND BugIt.EXNo = ExpI.EXNo
AND BugIt.ErepNo = ExpI.ErepNo
ORDER BY ErepStatus DESC;
-- Test script
DECLARE
Result BOOLEAN;
aBIAct BugIt.BIAct%TYPE;
BEGIN
StoredProcedure1(2, 2, 3, Result);
IF Result then
dbms_output.put_line('updated element to the BugIt table');
ELSE
dbms_output.put_line('Row not updated to the BugIt table');
END IF;
END;
/
ERROR at line 1:
ORA-20001: Database error
ORA-06512: at "SYSTEM.SPROLLUPEXPITEM", line 51
ORA-06512: at line 6
I think you want:
CREATE OR REPLACE PROCEDURE StoredProcedure1 (
tEXNo IN BugIt.EXNo%TYPE,
tErepNo IN ER.ErepNo%TYPE,
rUpAm IN INTEGER,
aRes OUT BOOLEAN
)
IS
tErepStatus ER.ErepStatus%TYPE;
BEGIN
SELECT ER.ErepStatus
INTO tErepStatus
FROM ER
INNER JOIN ExpI
ON ( ER.ErepNo = ExpI.ErepNo )
INNER JOIN BugIt
ON ( BugIt.EXNo = ExpI.EXNo )
WHERE ER.ErepNo = tErepNo
AND ER.ErepStatus IN ( 'APPROVED', 'PENDING', 'DENIED' )
ORDER BY ErepStatus DESC
FETCH FIRST ROW ONLY;
aRes := tErepStatus = 'APPROVED';
IF aRes THEN
UPDATE BugIt
SET BIAct = BIAct + rUpAm
WHERE EXNo = tEXNo;
END IF;
EXCEPTION
WHEN NO_DATA_FOUND THEN
aRes := FALSE;
END;
/
Which, for the sample data:
CREATE TABLE ER ( ErepNo, Erepstatus ) AS
SELECT 1, 'APPROVED' FROM DUAL UNION ALL
SELECT 2, 'PENDING' FROM DUAL UNION ALL
SELECT 3, 'DENIED' FROM DUAL UNION ALL
SELECT 3, 'APPROVED' FROM DUAL;
CREATE TABLE ExpI ( ErepNo, EXNo ) AS
SELECT 1, 1 FROM DUAL UNION ALL
SELECT 2, 2 FROM DUAL UNION ALL
SELECT 3, 3 FROM DUAL;
CREATE TABLE BugIt ( EXNo, BIAct ) AS
SELECT 1, 1 FROM DUAL UNION ALL
SELECT 2, 2 FROM DUAL UNION ALL
SELECT 3, 3 FROM DUAL;
Then:
DECLARE
aRes BOOLEAN;
BEGIN
StoredProcedure1( 1, 1, 1, aRes );
IF ares THEN
DBMS_OUTPUT.PUT_LINE( 'Changed' );
ELSE
DBMS_OUTPUT.PUT_LINE( 'Not Changed' );
END IF;
END;
/
Outputs Changed and:
SELECT * FROM BugIt;
Gives:
EXNO | BIACT
---: | ----:
1 | 2
2 | 2
3 | 3
And:
DECLARE
aRes BOOLEAN;
BEGIN
StoredProcedure1( 3, 3, 1, aRes );
IF ares THEN
DBMS_OUTPUT.PUT_LINE( 'Changed' );
ELSE
DBMS_OUTPUT.PUT_LINE( 'Not Changed' );
END IF;
END;
/
Outputs Not Changed and the BugIt table has not changed.
db<>fiddle here

How to write "in" claus in select query when ever in_put param has some values..?

whenever users pass a list of values then we need to pause "in" condition.
the jin_son_doc will be like this "India,American Samoa"
create or replace PROCEDURE test_attendee (
out_chr_err_code OUT VARCHAR2,
out_chr_err_msg OUT VARCHAR2,
out_attendee_tab OUT return_attendee_arr_result,
in_json_doc IN VARCHAR2
) IS
l_chr_srcstage VARCHAR2(200);
l_chr_biqtab VARCHAR2(200);
l_chr_srctab VARCHAR2(200);
l_chr_bistagtab VARCHAR2(200);
l_chr_err_code VARCHAR2(255);
l_chr_err_msg VARCHAR2(255);
l_out_chr_errbuf VARCHAR2(2000);
lrec return_attendee_report;
l_num_counter NUMBER := 0;
json_doc CHAR_ARRAY(1000) := in_json_doc;
CURSOR cur_attendee_data IS
SELECT
*
FROM
(
SELECT
a.*,
ROWNUM rn
FROM
(SELECT * FROM (
SELECT
r.id request_id,
c.designation ext_att_title,
DECODE(c.attendee_type, 'externalattendees', 'External', 'Internal') attendee_type
FROM
bi_request r
LEFT JOIN bi_request_activity_day a ON a.request_id = r.id
LEFT JOIN bi_request_catering_activity b ON b.request_activity_day_id = a.id
LEFT JOIN bi_request_attendees c ON c.request_id = r.id
LEFT JOIN bi_request_act_day_room d ON d.request_activity_day_id = a.id
AND d.room = b.room
WHERE
r.state = 'CONFIRMED'
AND a.event_date BETWEEN l_start_date AND l_end_date
AND r.location_id = (
SELECT UNIQUE
( id )
FROM
bi_location
WHERE
unique_id = l_location_id
)
AND d.room_type = 'MAIN_ROOM'
AND country IN (
SELECT
column_value
FROM
TABLE ( json_doc )
)
)
WHERE
1=1
) a
WHERE
ROWNUM <= l_end_row
)
WHERE
rn >= l_start_row;
TYPE rec_attendee_data IS
TABLE OF cur_attendee_data%rowtype INDEX BY PLS_INTEGER;
l_cur_attendee_data rec_attendee_data;
BEGIN
dbms_output.put_line(l_country_array.count);
out_attendee_tab := return_attendee_arr_result();
OPEN cur_attendee_data;
LOOP
FETCH cur_attendee_data BULK COLLECT INTO l_cur_attendee_data;
EXIT WHEN l_cur_attendee_data.count = 0;
dbms_output.put_line('here in first insert');
lrec := return_attendee_report();
out_attendee_tab := return_attendee_arr_result(return_attendee_report());
out_attendee_tab.DELETE;
FOR i IN 1..l_cur_attendee_data.count LOOP
-- dbms_output.put_line('Inside cursor ' );
BEGIN
l_num_counter := l_num_counter + 1;
lrec := return_attendee_report();
lrec.requestid := l_cur_attendee_data(i).request_id;
lrec.attendeetype := l_cur_attendee_data(i).attendee_type;
lrec.attendeetype := json_doc;
IF l_num_counter > 1 THEN
out_attendee_tab.extend();
out_attendee_tab(l_num_counter) := return_attendee_report();
ELSE
out_attendee_tab := return_attendee_arr_result(return_attendee_report());
END IF;
out_attendee_tab(l_num_counter) := lrec;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('Error occurred : ' || sqlerrm);
END;
END LOOP;
END LOOP;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('HERE INSIIDE OTHERS' || sqlerrm);
END;
Whenever j"son_doc" is null we need to skip the in clause. Is this possible, let me know if we have any solution.
user will pass jin_son_doc will be like this "India, America".
by using the following function i'm converting string to array,
create or replace FUNCTION fn_varchar_to_array(p_list IN VARCHAR2)
RETURN CHAR_ARRAY
AS
l_string VARCHAR2(32767) := p_list || ',';
l_comma_index PLS_INTEGER;
l_index PLS_INTEGER := 1;
l_tab CHAR_ARRAY := CHAR_ARRAY();
BEGIN
LOOP
l_comma_index := INSTR(l_string, ',', l_index);
EXIT WHEN l_comma_index = 0;
l_tab.EXTEND;
l_tab(l_tab.COUNT) := SUBSTR(l_string, l_index, l_comma_index - l_index);
l_index := l_comma_index + 1;
END LOOP;
RETURN l_tab;
END fn_varchar_to_array;
You can use OR condition as following:
....
AND (json_doc is null
OR country IN (
SELECT
column_value
FROM
TABLE ( json_doc )
)
)
...
Cheers!!

PLSQL DML statements inside procedure

I am trying to execute below procedure but it says me to use BULKCOLLECT and FORALL to refactor my code. Is it just a warning or should i not use like below for my procedure. If so, how should i modify the code as i am iterating through an array and i need each value to update into table.
CREATE OR REPLACE PROCEDURE SCHEMA.PR_VALIDATE
(
FILEARRAY IN STRARRAY,
DUPARRAY OUT STRARRAY,
PASSARRAY OUT STRARRAY,
FAILARRAY OUT STRARRAY,
MISSARRAY OUT STRARRAY
)
IS
dupCount NUMBER;
staCode VARCHAR2 (10);
fileName VARCHAR2 (50);
dupfileName VARCHAR2(50);
fileId NUMBER;
ID VARCHAR2(20);
BEGIN
for i in 1 .. FILEARRAY.count
loop
fileName := FILEARRAY(i);
SELECT COUNT (T.FILEID), T.FILEID,T.STATUS,T.ID INTO dupCount,fileId,staCode,ID FROM TB_TABLE_NAME T, TB_TABLE_NAME S
WHERE T.FILEID=S.FILEID
AND T.STATUS=S.STATUS
AND T.FILENAME = fileName AND T.STATUS IN ('PASS', 'FAIL)
GROUP BY T.FILEID,T.STATUS,T.ID;
IF dupCount>1
THEN
SELECT FILENAME INTO dupfileName FROM TB_TABLE_1
WHERE STATUS IN ('PASS','FAIL') AND FILEID=fileId
AND FILENAME != fileName;
DBMS_OUTPUT.PUT_LINE(dupfileName);
UPDATE TB_TABLE_1 SET STATUS='DUP' WHERE FILENAME=dupfileName;
DUPARRAY(DUPARRAY.LAST +1 ) :=dupfileName;
DBMS_OUTPUT.PUT_LINE(dupfileName);
END IF;
IF staCode = 'FAIL'
THEN
FAILARRAY(FAILARRAY.LAST+1) :=fileName;
ELSIF staCode = 'PASS'
THEN
PASSARRAY(PASSARRAY.LAST+1) :=fileName;
END IF;
end loop;
EXCEPTION
WHEN NO_DATA_FOUND THEN
staCode :=NULL;
MISSARRAY(MISSARRAY.LAST +1 ) :=fileName;
WHEN OTHERS THEN
PR_ERRORS('PR_VALIDATE', SQLERRM);
ROLLBACK;
END;
/
As I mentioned in the comment FORALL here is out of context as business logic is incorporated here but again you can try BULK COLLECT with FOR loop to iterate. But data volume is not that large you can still go with the row-by-row approach. Hope below snippet helps. Also there were some single quotes missing which would have given compile time error.
CREATE OR REPLACE PROCEDURE SCHEMA.PR_VALIDATE(
FILEARRAY IN STRARRAY,
DUPARRAY OUT STRARRAY,
PASSARRAY OUT STRARRAY,
FAILARRAY OUT STRARRAY,
MISSARRAY OUT STRARRAY )
IS
dupCount NUMBER;
staCode VARCHAR2 (10);
fileName VARCHAR2 (50);
dupfileName VARCHAR2(50);
fileId NUMBER;
ID VARCHAR2(20);
BEGIN
FOR i IN 1 .. FILEARRAY.count
LOOP
fileName := FILEARRAY(i);
SELECT COUNT (T.FILEID),
T.FILEID,
T.STATUS,
T.ID
INTO dupCount,
fileId,
staCode,
ID
FROM TB_TABLE_NAME T,
TB_TABLE_NAME S
WHERE T.FILEID =S.FILEID
AND T.STATUS =S.STATUS
AND T.FILENAME = fileName
AND T.STATUS IN ('PASS', 'FAIL')
GROUP BY T.FILEID,
T.STATUS,
T.ID;
IF dupCount>1 THEN
SELECT FILENAME
INTO dupfileName
FROM TB_TABLE_1
WHERE STATUS IN ('PASS','FAIL')
AND FILEID =fileId
AND FILENAME != fileName;
DBMS_OUTPUT.PUT_LINE(dupfileName);
UPDATE TB_TABLE_1
SET STATUS='DUP'
WHERE FILENAME=dupfileName;
DUPARRAY(DUPARRAY.LAST +1 ) :=dupfileName;
DBMS_OUTPUT.PUT_LINE(dupfileName);
END IF;
IF staCode = 'FAIL' THEN
FAILARRAY(FAILARRAY.LAST+1) :=fileName;
ELSIF staCode = 'PASS' THEN
PASSARRAY(PASSARRAY.LAST+1) :=fileName;
END IF;
END LOOP;
EXCEPTION
WHEN NO_DATA_FOUND THEN
staCode :=NULL;
MISSARRAY(MISSARRAY.LAST +1 ) :=fileName;
WHEN OTHERS THEN
PR_ERRORS('PR_VALIDATE', SQLERRM);
ROLLBACK;
END;

ORA-06550: line 1, column 7 (PL/SQL: Statement ignored) Error

I am getting following error for the stored procedure and not able to understand the issue (must be from db side) While googling, I found similar issues but couldn't get the solution. Can any one help me please find the error in PROCEDURE ??
Error :-
18:58:50,281 ERROR [STDERR] java.sql.SQLException: ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 'SP_DIST_RETAILER_REMAP'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
Stored Prodedure(SP_DIST_RETAILER_REMAP) :-
CREATE OR REPLACE PROCEDURE SMAPRD02.SP_DIST_RETAILER_REMAP (
i_old_dist_code IN VARCHAR2,
i_new_dist_code IN VARCHAR2,
i_territory_remapping IN NUMBER,
i_remapping_reason IN VARCHAR2,
i_trans_doneby_rolename IN VARCHAR2,
i_trans_doneby_id IN NUMBER,
i_trans_dist_rolename IN VARCHAR2,
i_trans_ret_rolename IN VARCHAR2,
i_activity_type IN VARCHAR2,
i_ret_list IN V_ARRAY,
result OUT VARCHAR2,
i_o_query OUT VARCHAR2
)
AS
--i_ret_codes OUT VARCHAR2;
v_dist_count NUMBER;
v_ret_count NUMBER;
v_ret_codes VARCHAR2(10000) := '';
v_flag VARCHAR2(10) := 'true';
v_trans_id NUMBER;
v_query VARCHAR2(10000);
BEGIN
IF i_territory_remapping = 1 then
SELECT count(*) into v_dist_count FROM tblemployee where EMPCODE = i_new_dist_code and circle_code = (select emp.circle_code
from tblemployee emp where emp.empcode = i_old_dist_code) and upper(user_type) like upper('%dist%') and upper(ACCESS_TO) in ('SALES','BOTH') and upper(stage) not in (upper('InActive'));
ELSE
SELECT count(*) into v_dist_count FROM tblemployee where EMPCODE = i_new_dist_code and circle_code = (select emp.circle_code from tblemployee emp
where emp.empcode = i_old_dist_code) and cluster_code = (select emp.cluster_code from tblemployee emp where emp.empcode = i_old_dist_code)
and upper(user_type) like upper('%dist%') and upper(ACCESS_TO) in ('SALES','BOTH') and upper(stage) not in (upper('InActive'));
END IF;
IF v_dist_count =0 THEN
result := 'invalid_new_dist_code';
v_flag := 'false';
ELSIF v_dist_count = 1 THEN
SELECT count(*) into v_ret_count FROM tblretailer t where t.DIST_CODE = i_old_dist_code and (upper(t.ACCESS_TO) = 'SALES' or upper(t.ACCESS_TO) = 'BOTH');
--SELECT count(*) into v_ret_count FROM tblretailer t where t.DIST_CODE = i_old_dist_code and upper(t.ACCESS_TO) = 'SALES' and upper(t.stage) in ('APPROVED','INACTIVE');
IF v_ret_count=i_ret_list.count THEN
IF i_territory_remapping = 1 THEN
result := 'no_ret_left';
v_flag := 'false';
END IF;
ELSE
IF i_territory_remapping != 1 THEN
result := 'ret_left';
v_flag := 'false';
END IF;
END IF;
END IF;
IF i_ret_list is null or i_ret_list.count = 0 THEN
result := 'empty retailers list';
v_flag := 'false';
END IF;
/*FOR i IN i_ret_list.FIRST .. i_ret_list.LAST
LOOP
IF v_ret_codes is null
THEN
v_ret_codes := ''''||i_ret_list(i)||'''';
ELSE
v_ret_codes := v_ret_codes||','''||i_ret_list(i)||'''';
END IF;
IF v_ret_codes is null
THEN
v_ret_codes := i_ret_list(i);
ELSE
v_ret_codes := v_ret_codes||','||i_ret_list(i);
END IF;
END LOOP;
i_ret_codes := v_ret_codes;
v_flag := 'false';
result := 'success';*/
IF v_flag = 'true' THEN
FOR i IN i_ret_list.FIRST .. i_ret_list.LAST
LOOP
IF v_ret_codes is null
THEN
v_ret_codes := ''''||i_ret_list(i)||'''';
ELSE
v_ret_codes := v_ret_codes||','''||i_ret_list(i)||'''';
END IF;
END LOOP;
--i_ret_codes := v_ret_codes;
--update tblretailer set dist_code=i_new_dist_code,DIST_ID=to_number(i_new_dist_code),cluster_code=(select cluster_code from tblemployee where empcode = i_new_dist_code),FOSID='',FOS_CODE='',DSR_ID='',DSR_CODE='',LAST_UPDATED_DATE=sysdate where retcode in (v_ret_codes);
v_query := 'update tblretailer set dist_code='||i_new_dist_code||',DIST_ID=to_number('||i_new_dist_code||'),cluster_code=(select cluster_code from tblemployee where empcode = '||i_new_dist_code||'),FOSID='''',FOS_CODE='''',DSR_ID='''',DSR_CODE='''',LAST_UPDATED_DATE=sysdate where retcode in ('||v_ret_codes||')';
execute immediate (v_query);
--i_query :='update tblretailer set dist_code='||i_new_dist_code||',DIST_ID=to_number('||i_new_dist_code||'),cluster_code=(select cluster_code from tblemployee where empcode = '||i_new_dist_code||'),FOSID='',FOS_CODE='',DSR_ID='',DSR_CODE='',LAST_UPDATED_DATE=sysdate where retcode in ('||v_ret_codes||');';
insert into TBL_TRANSFER_SUP_MASTER(MASTER_ID,TRANS_ID,TRANS_DONEBY_ROLENAME,TRANS_DONEBY_ID,TRANS_FROM_ROLENAME,TRANS_FROM,TRANS_TO_ROLENAME,TRANS_TO,ACTIVITY_CODE,TRANS_DATE,TRANSFER_REASON,LAST_UPDATED_DATE)
values(SUP_MASTER_TRANS_ID_SEQ.nextval,SUP_MASTER_TRANS_ID_SEQ.nextval,i_trans_doneby_rolename,i_trans_doneby_id,i_trans_dist_rolename,i_old_dist_code,i_trans_dist_rolename,i_new_dist_code,'101',sysdate,i_remapping_reason,sysdate) return TRANS_ID into v_trans_id;
FOR i IN i_ret_list.FIRST .. i_ret_list.LAST
LOOP
insert into TBL_TRANSFER_SUP_DTLS(DTLS_ID,TRANS_ID,TRANS_ON_ROLENAME,TRANS_ON_ID,LAST_UPDATED_DATE)
values(SUP_DTLS_ID_SEQ.nextval,v_trans_id,i_trans_ret_rolename,i_ret_list(i),sysdate);
END LOOP;
IF SQL%ROWCOUNT>0 THEN
result := 'success';
ELSE
result := 'failure';
END IF;
--update tblstock set NEW_DIST_CODE_REMAP=i_new_dist_code,REMAP_DATE=sysdate,LAST_UPDATED_DATE=sysdate where (DIST_CODE=i_old_dist_code or NEW_DIST_CODE_REMAP=i_old_dist_code) and RET_CODE in (v_ret_codes);
v_query := 'update tblstock set NEW_DIST_CODE_REMAP='||i_new_dist_code||',REMAP_DATE=sysdate,LAST_UPDATED_DATE=sysdate where (DIST_CODE='||i_old_dist_code||' or NEW_DIST_CODE_REMAP='||i_old_dist_code||') and RET_CODE in ('||v_ret_codes||')';
execute immediate (v_query);
i_o_query := v_query;
insert all into TBL_ACTIVITY_LOG (LOG_ID,TRANS_ID,ACTIVITY_DONEBY_ROLENAME,ACTIVITY_DONEBY_ID,ACTIVITY_REFERENCE_ID,ACTIVITY_CODE,ACTIVITY_DATE)
values(ACTIVITY_LOG_TRANS_ID_SEQ.NEXTVAL,ACTIVITY_LOG_TRANS_ID_SEQ.NEXTVAL,i_trans_doneby_rolename,i_trans_doneby_id,v_trans_id,
act_code,sysdate) select log_config.ACTIVITY_CODE act_code from TBL_ACTIVITY_LOG_CONFIG log_config
where upper(log_config.ACTIVITY_TYPE)= upper(i_activity_type);
END IF;
END;
/
Java Code :-
try{
if(ret_list.size()>0)
ret_code = ret_list.toArray();
con = ConnectionManager.getDirectConnection();
ArrayDescriptor descriptor = ArrayDescriptor.createDescriptor(PropertyLoader.RET_SECONDARY_V_ARRAY,con);
ARRAY array_to_pass = new ARRAY( descriptor,con, ret_code );
cstmt = con.prepareCall("{ call SP_DIST_RETAILER_REMAP(?,?,?,?,?,?,?,?,?,?,?,?)}");
cstmt.setString(1,old_dist_code.trim());
cstmt.setString(2,new_dist_code.trim());
if(territory_remapping)
cstmt.setInt(3,1);
else
cstmt.setInt(3,2);
cstmt.setString(4,remapping_reason);
cstmt.setString(5,userVO.getRolename().trim());
cstmt.setInt(6,userVO.getEmpid());
cstmt.setString(7,PropertyLoader.DISTRIBUOTR_ROLENAME);
cstmt.setString(8,PropertyLoader.RETAILER_ROLENAME);
cstmt.setString(9,PropertyLoader.ACTIVITY_TYPES_RETAILER_REMAPPING);
cstmt.setArray(10,array_to_pass);
cstmt.registerOutParameter(11,Types.VARCHAR);
cstmt.registerOutParameter(12,Types.VARCHAR);
/*cstmt.registerOutParameter(13,Types.VARCHAR);*/
cstmt.execute();
status = cstmt.getString(11);
System.out.println("Remap Update Query "+cstmt.getString(12));
//System.out.println(cstmt.getString(13));
}
If the value stored in PropertyLoader.RET_SECONDARY_V_ARRAY is not "V_ARRAY", then you are using different types; even if they are declared identically (e.g. both are table of number) this will not work.
You're hitting this data type compatibility restriction:
You can assign a collection to a collection variable only if they have
the same data type. Having the same element type is not enough.
You're trying to call the procedure with a parameter that is a different type to the one it's expecting, which is what the error message is telling you.
The procedure which you are using is should be properly declared in the place which you are using it. For an example if it is under a user and in a package then it should be in that order. The username, package and procedurename.

SQL Plus procedure error

I am trying to create the procedure which blurs some of the info if the condition is satisfied. I am able to create the procedure, but the execution doesn't work!
This is the table:
drop table orders;
create table Orders(
OrderID number,
Firstname varchar2(10),
State varchar2(2),
ProductDescription varchar2(20),
Qty number,
ItemPrice number);
insert into Orders values(1, 'Inaae', 'Kim','IL','hard drive', 2,200);
insert into Orders values(3, 'Lisa','Simpson','CA','Books',5,25);
insert into Orders values(4, 'Bart','Simpson','MD','Video',20,3);
insert into Orders values(5, 'Inaae','Kim','WA','ear ring',3,10);
insert into Orders values(6, 'Hommer','Simpson','IN','Beer',50,2);
insert into Orders values(7, 'Marge','Simpson','FL','coffee machine',1,150);
insert into Orders values(8, 'Gerret','W','NY','Chair',1,180);
This is the code for procedure:
create or replace function fn_extended_price(itemprice IN NUMBER, Qty IN NUMBER) RETURN NUMBER
as
begin
RETURN itemprice * Qty;
end;
/
create or replace procedure sp_order
as
cursor c_order is select OrderId, Firstname, Lastname, ProductDescription, Qty, itemprice, State from Orders;
order_val c_order %ROWTYPE;
vOrder char(20); --will handle extention price blur
vQty number;
vItemPrice number;
vState varchar2(2);
begin
FOR order_val in c_order LOOP
vOrder := fn_extended_price(order_val.itemprice, order_val.Qty);
vQty := order_val.Qty;
vItemPrice := order_val.itemprice;
vState := order_val.State;
if vState = 'CA' OR vState = 'MD' OR vState = 'IL' THEN
vOrder :='*********';
vQty :='********';
vItemPrice :='******';
end if;
DBMS_OUTPUT.PUT_LINE('---------------------------------');
DBMS_OUTPUT.PUT_LINE('Order ID: ' || order_val.orderid);
DBMS_OUTPUT.PUT_LINE('First Name: ' || order_val.firstname);
DBMS_OUTPUT.PUT_LINE('Last Name: ' || order_val.lastname);
DBMS_OUTPUT.PUT_LINE('Product Description: ' || order_val.ProductDescription);
DBMS_OUTPUT.PUT_LINE('Qty: ' || order_val.Qty);
DBMS_OUTPUT.PUT_LINE('Item Price::' || order_val.itemprice);
DBMS_OUTPUT.PUT_LINE('Extended Price: $' || vOrder);
END LOOP;
end;
/
THE ERROR IS:
SQL> exec sp_orders
BEGIN sp_orders; END;
*
ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00201: identifier 'SP_ORDERS' must be declared
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
Can anyone tell me what is the mistake??
Thank you
You have named your procedure as sp_order, yet you are trying to run a procedure named sp_orders.
What is more, you are trying to store ****** value in a NUMBER variable in your code which will yield a "PL/SQL: numeric or value error%s" exception, change your procedure as follows:
create or replace procedure sp_order
as
cursor c_order is select OrderId, Firstname, Lastname, ProductDescription, Qty, itemprice, State from Orders;
order_val c_order %ROWTYPE;
vOrder char(20); --will handle extention price blur
vQty number;
vItemPrice number;
vState varchar2(2);
begin
FOR order_val in c_order LOOP
vOrder := fn_extended_price(order_val.itemprice, order_val.Qty);
vQty := order_val.Qty;
vItemPrice := order_val.itemprice;
vState := order_val.State;
if vState = 'CA' OR vState = 'MD' OR vState = 'IL' THEN
vOrder :='*********';
vQty :=NULL;
vItemPrice :=NULL;
end if;
DBMS_OUTPUT.PUT_LINE('---------------------------------');
DBMS_OUTPUT.PUT_LINE('Order ID: ' || order_val.orderid);
DBMS_OUTPUT.PUT_LINE('First Name: ' || order_val.firstname);
DBMS_OUTPUT.PUT_LINE('Last Name: ' || order_val.lastname);
DBMS_OUTPUT.PUT_LINE('Product Description: ' || order_val.ProductDescription);
DBMS_OUTPUT.PUT_LINE('Qty: ' || order_val.Qty);
DBMS_OUTPUT.PUT_LINE('Item Price::' || order_val.itemprice);
DBMS_OUTPUT.PUT_LINE('Extended Price: $' || vOrder);
END LOOP;
end;
/