I have the below code which generates a pdf file for each record in the table with an email address to a specific folder, but what I have realized is that on each iteration the URL is appended to the next iteration, which makes the URL increases on each loop. So after the browser reaches its limit it throws an error and generates only 10 files when I am expecting about 1500 pdf files.
PROCEDURE RUN_REPORT2 IS
M_PARAM_ID PARAMLIST ;
M_REP_ID VARCHAR2(3000);
V_REP_CURRENCY VARCHAR2(5);
V_BASE_CURRENCY VARCHAR2(5);
v_show_document VARCHAR2(30000);
v_report_name VARCHAR2(30000);
v_format VARCHAR2(200) := 'PDF';
CURSOR C1 IS
SELECT EMP_EMPLOYEE_NO,
INITCAP(EMP_FIRSTNAME) EMP_FIRSTNAME,
EMP_EMAIL_ADDRESS,
TO_CHAR(PMA_PAY_PERIOD_TO, 'MONTH' || ' ' || 'YYYY') PAY_PERIOD,
EMP_TIN DOB,
TRIM(TO_CHAR(PMA_PAY_PERIOD_TO, 'MONTH')) PAY_MONTH,
TRIM(TO_CHAR(PMA_PAY_PERIOD_TO, 'YYYY')) PAY_YEAR
FROM HR_EMPLOYEES, PAY_PAYROLL_MASTER
WHERE EMP_EMPLOYEE_ID = PMA_EMPLOYEE_ID
AND EMP_COMPANY_CODE = PMA_COMPANY_CODE
AND EMP_EMAIL_ADDRESS IS NOT NULL
AND EMP_EMPLOYEE_NO BETWEEN :ONE.EMPNO_FM AND :ONE.EMPNO_TO
AND TO_CHAR(PMA_PAY_PERIOD_TO, 'Month YYYY') = :ONE.PAY_PERIOD
AND PMA_COMPANY_CODE = :GLOBAL.COMPNAME
BEGIN
SELECT PAR_REPORT_URL, PAR_FORMS_DIRECTORY
INTO v_show_document, v_report_name
FROM APPS_PARAMETERS
WHERE PAR_COMPANY_CODE = :GLOBAL.COMPNAME;
FOR C1_R IN C1 LOOP
v_show_document := v_show_document
|| '&report='||v_report_name||'PAYSLIP_EIC_EMAIL.jsp'
|| '&destype=file'
|| '&desformat='||v_format
|| '&P_EMPNO_FM='||C1_R.EMP_EMPLOYEE_NO
|| '&P_EMPNO_TO=' ||C1_R.EMP_EMPLOYEE_NO
|| '&P_DEPT_FM='||:ONE.DEPT_FM
|| '&P_DEPT_TO=' ||:ONE.DEPT_TO
|| '&P_REG_FM='||:ONE.REG_FM
|| '&P_REG_TO=' ||:ONE.REG_TO
|| '&P_REP_CURRENCY=' ||V_REP_CURRENCY
|| '&P_PERIOD='||:ONE.PAY_PERIOD
|| '&P_COMPCODE=' ||:GLOBAL.COMPNAME
|| '&desname='||v_report_name||'EMAIL_FOLDER\'||C1_R.EMP_EMAIL_ADDRESS||' '||C1_R.EMP_FIRSTNAME||'
'||C1_R.PAY_MONTH||C1_R.PAY_YEAR||'.PDF';
WEB.SHOW_DOCUMENT(v_show_document||'&cmdkey=userlogin','_blank');
SET_APPLICATION_PROPERTY(CURSOR_STYLE, 'DEFAULT');
DESTROY_PARAMETER_LIST(M_PARAM_ID) ;
CLEAR_MESSAGE;
END LOOP;
END;
The way I understood it, this:
v_show_document := v_show_document
|| '&report='||v_report_name||'PAYSLIP_EIC_EMAIL.jsp'
should be
v_show_document :=
'&report='||v_report_name||'PAYSLIP_EIC_EMAIL.jsp'
Otherwise, you're concatenating v_show_document with previous loop's iteration every time, making it HUGE (and more or less useless).
Related
OK so I have a cursor for loop that I want to print an error message when the select statement doesn't find a course that the user has inputted. But the problem is that cursor for loops automatically exits when the select statement fails, so my else statement never executes. How do I print a message saying that they course they are looking for doesn't exist. Note switching to a cursor fetch is not an option. For example id the user enters a course that exists it prints all relevant information. When the user inputs a course with no prerequisite it prints a proper message, but if the user inputs a course that doesn't exists, nothing gets printed.
DECLARE
course_name VARCHAR2(40) := '&course_input';
TYPE course_r IS RECORD(
course_description course.description%TYPE,
cost course.cost%TYPE,
prerequisite course.prerequisite%TYPE,
prerequisite_cost course.cost%TYPE
);
course_rec course_r;
CURSOR course_cursor IS
SELECT a.description, a.cost, a.prerequisite, b.cost AS preq_cost
FROM COURSE a
LEFT JOIN COURSE b ON a.prerequisite = b.course_no
WHERE UPPER(a.description) LIKE '%'||'&course_input'||'%';
BEGIN
FOR record IN course_cursor
LOOP
course_rec.course_description := record.description;
course_rec.cost := record.cost;
course_rec.prerequisite := record.prerequisite;
course_rec.prerequisite_cost := record.preq_cost;
IF course_rec.prerequisite IS NULL THEN
DBMS_OUTPUT.PUT_LINE('There is NO prerequisite course for any that starts on ' || course_name || '. Try again');
ELSIF course_rec.prerequisite IS NOT NULL THEN
DBMS_OUTPUT.PUT_LINE('Course: ' || course_rec.course_description);
DBMS_OUTPUT.PUT_LINE('Cost: ' || course_rec.cost);
DBMS_OUTPUT.PUT_LINE('Prerequisite: ' || course_rec.prerequisite);
DBMS_OUTPUT.PUT_LINE('Prerequisite Cost: ' || course_rec.prerequisite_cost);
DBMS_OUTPUT.PUT_LINE('=================================================');
ELSE
DBMS_OUTPUT.PUT_LINE('There is NO VALID course that starts on '||course_name||'. Try again.');
END IF;
END LOOP;
END;
/
You can do this by having a variable which only gets set inside the loop. Then you can check that variable after the loop has completed to see if it was set, and decide if you need to do additional work.
Something like:
DECLARE
course_name VARCHAR2(40) := '&course_input';
v_rows_present BOOLEAN := FALSE;
BEGIN
FOR course_rec IN (SELECT a.description,
a.cost,
a.prerequisite,
b.cost AS preq_cost
FROM course a
LEFT JOIN course b
ON a.prerequisite = b.course_no
WHERE upper(a.description) LIKE '%' || course_name || '%')
LOOP
v_rows_present := TRUE;
IF course_rec.prerequisite IS NULL
THEN
dbms_output.put_line('There is NO prerequisite course for any that starts on ' || course_name || '. Try again');
ELSE
dbms_output.put_line('Course: ' || course_rec.course_description);
dbms_output.put_line('Cost: ' || course_rec.cost);
dbms_output.put_line('Prerequisite: ' || course_rec.prerequisite);
dbms_output.put_line('Prerequisite Cost: ' || course_rec.prerequisite_cost);
dbms_output.put_line('=================================================');
END IF;
END LOOP;
IF NOT v_rows_present
THEN
dbms_output.put_line('There is NO VALID course that starts on ' || course_name || '. Try again.');
END IF;
END;
/
N.B. I've updated your code as you appear to have misapprehended how to use a cursor for loop.
Cursor-for-loops create their own record variable implicitly, so you don't need to declare one yourself.
You also don't need to declare a cursor explicitly either - that can be done as part of the cursor-for-loop statement.
You don't need to populate a new record with the same values from the cursor-for-loop record in order to use the values (as long as you're using them within the cursor-for-loop, of course!)
You could declare a counter, as say, PLS_INTEGER, initialize it to 0, then increment it inside the loop. After the loop, you can check the value and if it's 0, you know no rows were returned.
THE CURSOR FOR LOOP doesn't execute if there are no such courses in the courses table.So, check if a row exists before entering the loop.
Two other things to note:
LIKE '%'||'&course_input'||'%' is not required in the where clause
as the same variable is already passed from user input and assigned
in the declare section.Simply use LIKE '%' || course_name || '%'
RECORD is a PL/SQL reserved word and shouldn't be used as a loop
index variable, i've changed it to rec.
DECLARE
course_name VARCHAR2(40) := '&course_input';
TYPE course_r IS RECORD ( course_description course.description%TYPE,
cost course.cost%TYPE,
prerequisite course.prerequisite%TYPE,
prerequisite_cost course.cost%TYPE );
course_rec course_r;
cur_count NUMBER;
CURSOR course_cursor IS SELECT a.description,
a.cost,
a.prerequisite,
b.cost AS preq_cost
FROM course a
LEFT JOIN course b ON a.prerequisite = b.course_no
WHERE upper(a.description) LIKE '%' || course_name || '%';
BEGIN
SELECT COUNT(*)
INTO cur_count
FROM course a
WHERE upper(a.description) LIKE '%' || course_name || '%';
IF
cur_count > 0
THEN
FOR rec IN course_cursor LOOP
course_rec.course_description := rec.description;
course_rec.cost := rec.cost;
course_rec.prerequisite := rec.prerequisite;
course_rec.prerequisite_cost := rec.preq_cost;
IF
course_rec.prerequisite IS NULL
THEN
dbms_output.put_line('There is NO prerequisite course for any that starts on ' ||
course_name || '. Try again');
ELSE
dbms_output.put_line('Course: ' || course_rec.course_description);
dbms_output.put_line('Cost: ' || course_rec.cost);
dbms_output.put_line('Prerequisite: ' || course_rec.prerequisite);
dbms_output.put_line('Prerequisite Cost: ' || course_rec.prerequisite_cost);
dbms_output.put_line('=================================================');
END IF;
END LOOP;
ELSE
dbms_output.put_line('There is NO VALID course that starts on ' || course_name || '. Try again.'
);
END IF;
END;
/
I have a project which creates a procedure and takes Date parameter in the argument. Upon execution of the procedure, it displays the Order Id and Order details in the Order Date column using nested cursor loop. I am also trying to display an error message for the date which is not available in my order tables.
The code to create procedure is as
create or replace procedure a05_order_details_by_date(p_order_date in date)
as
v_msg varchar2(400);
v_order_id ppl_order_headers.order_id%type;
v_order_date ppl_order_headers.order_date%type := p_order_date;
cursor cur_orders is
select order_id, order_date
from ppl_order_headers
where extract(month from order_date) = extract(month from v_order_date) and
extract(year from order_date) = extract(year from v_order_date) ;
cursor cur_order_details is
select ppl_order_details.plant_id, ppl_order_details.quantity, ppl_order_details.price, sum(ppl_order_details.quantity*ppl_order_details.price) as Extcost
from ppl_order_details
join ppl_order_headers on ppl_order_details.order_id = ppl_order_headers.order_id
where ppl_order_headers.order_id = v_order_id
group by ppl_order_details.plant_id, ppl_order_details.quantity, ppl_order_details.price;
begin
<< order_loop >>
for rec_orders in cur_orders
loop
case
when (extract(month from v_order_date)) != (extract(month from rec_orders.order_date))
and
(extract(year from v_order_date))!= (extract(year from rec_orders.order_date)) then
pr.pr('There are no orders for the requested month: ' || to_char(v_order_date, 'Month YYYY'));
else
pr.pr('Order ID' || ' ' || 'Order Date');
v_order_id := rec_orders.order_id;
v_msg := rpad(v_order_id, 7) || ' ' || rec_orders.order_date;
pr.pr(v_msg);
<< order_details >>
for rec_order_details in cur_order_details
loop
pr.pr(' ' || ' Plant ID' || ' ' || 'Quantity' || ' ' || 'Price' || ' ' || 'ExtCost' );
v_msg := ' ' || rec_order_details.plant_id || ' ' || rec_order_details.quantity ||
' ' || rec_order_details.price || ' ' || rec_order_details.Extcost;
pr.pr(v_msg);
end loop;
end case;
end loop;
end;
/
The result is fine when the date is given within the dataset. but when I try to run the procedure with Future date or date which is not in dataset, it is supposed to show an error message. But instead, it just shows "Anonymous Block completed".
You're looping over orders where the order date year/month matches your argument year/month; so your loop only contains matching data. But then inside that loop you say:
case
when (extract(month from v_order_date)) != (extract(month from rec_orders.order_date))
and
(extract(year from v_order_date))!= (extract(year from rec_orders.order_date)) then
Firstly you probably meant that to be 'or' not 'and', otherwise the same month in a different year would still be valid. But much more importantly that case condition can never be true. You're inside a loop which already dictates that the month and year for this record must match your date argument, because of the cursor's where clause.
So this case statement is redundant. If any data is found by the cursor then you will always go into the 'else' clause. If no data is found then you won't come into the cursor loop at all (as Tony Andrews pointed out), so the case isn't even evaluated.
You could generate your message by counting the number of records found as you go around the loop, or by setting a boolean variable; and then checking that state after the loop:
...
-- initial state is that we haven't seen any matching records
v_record_found boolean := false;
begin
<< order_loop >>
for rec_orders in cur_orders
loop
-- we have seen records matching the argument
v_record_found := true;
pr.pr('Order ID' || ' ' || 'Order Date');
v_order_id := rec_orders.order_id;
...
<< order_details >>
for rec_order_details in cur_order_details
loop
pr.pr(...)
...
pr.pr(v_msg);
end loop;
end loop;
-- was the flag changed inside the loop?
if not v_record_found then
pr.pr('There are no orders for the requested month: '
|| to_char(v_order_date, 'Month YYYY'));
end if;
end;
If there are no matching records you don't go into the loop, and the flag is never changed to true. But if there are matching records it is set to true, and the 'no orders' messages isn't shown.
I have cursor which is selecting data and it is running quite fine
CURSOR Crs_c1 IS
SELECT a.GLOBAL_ACCOUNT_CODE,
a.LOCAL_ACCOUNT_CODE,
a.LOCAL_ACCOUNT_NAME,
c.GLOBAL_ACCOUNT_TYPE t_conto,
ltrim(rtrim(a.GLOBAL_ACCOUNT_CODE))||ltrim(rtrim(a.LOCAL_ACCOUNT_CODE)) GLOBAL_LOCAL
FROM V_LOCAL_ACCOUNTS#GDW_LIVE a,V_GLOBAL_ACCOUNTS#GDW_LIVE c --V_LOCAL_ACCOUNTS#GDWPP_ANY a,V_GLOBAL_ACCOUNTS#GDWPP_ANY c
WHERE a.enabled_flag = 'Y'
AND a.GLOBAL_ACCOUNT_CODE=c.GLOBAL_ACCOUNT_CODE
AND not exists (SELECT 1
FROM conto_gdw b -- considero solo i conti nuovi
WHERE a.LOCAL_ACCOUNT_CODE = b.c_conto_local_gdw
AND a.GLOBAL_ACCOUNT_CODE=b.C_CONTO_GLOBAL_GDW);
But at the time of insertion the code fails....
INSERT INTO conto_gdw
(C_CONTO_LOCAL_GDW,
S_CONTO_LOCAL_GDW,
C_CONTO_GLOBAL_GDW,
T_CONTO,
D_INIZIO,
GLOBAL_LOCAL)
VALUES (Rec_Crs_c1.LOCAL_ACCOUNT_CODE,
nvl(Rec_Crs_c1.LOCAL_ACCOUNT_NAME,'.'),
Rec_Crs_c1.GLOBAL_ACCOUNT_CODE,
Rec_Crs_c1.t_conto,
(v_anno_in * 100) + v_mese_in,
Rec_Crs_c1.GLOBAL_LOCAL);
May be this problem is occuring because of a single tuple (dataset). How can I find that culprit data?
I have checked all the data from cursor selection by taking it in a excel sheet, I could not find anything manually. Is there any way ORACLE would return me the failed data?
You need to have a proper exception handling while inserting data .Provide the output of the pl sql block .After than we can help you.
DECLARE
CURSOR Crs_c1
IS
SELECT a.GLOBAL_ACCOUNT_CODE,
a.LOCAL_ACCOUNT_CODE,
a.LOCAL_ACCOUNT_NAME,
c.GLOBAL_ACCOUNT_TYPE t_conto,
LTRIM (RTRIM (a.GLOBAL_ACCOUNT_CODE))
|| LTRIM (RTRIM (a.LOCAL_ACCOUNT_CODE))
GLOBAL_LOCAL
FROM V_LOCAL_ACCOUNTS#GDW_LIVE a, V_GLOBAL_ACCOUNTS#GDW_LIVE c
WHERE a.enabled_flag = 'Y'
AND a.GLOBAL_ACCOUNT_CODE = c.GLOBAL_ACCOUNT_CODE
AND NOT EXISTS
(SELECT 1
FROM conto_gdw b -- considero solo i conti nuovi
WHERE a.LOCAL_ACCOUNT_CODE = b.c_conto_local_gdw
AND a.GLOBAL_ACCOUNT_CODE =
b.C_CONTO_GLOBAL_GDW);
Rec_Crs_c1 Crs_c1%ROWTYPE;
BEGIN
OPEN Crs_c1;
LOOP
FETCH Crs_c1 INTO Rec_Crs_c1;
EXIT WHEN Crs_c1%NOTFOUND;
INSERT INTO conto_gdw (C_CONTO_LOCAL_GDW,
S_CONTO_LOCAL_GDW,
C_CONTO_GLOBAL_GDW,
T_CONTO,
D_INIZIO,
GLOBAL_LOCAL)
VALUES (Rec_Crs_c1.LOCAL_ACCOUNT_CODE,
NVL (Rec_Crs_c1.LOCAL_ACCOUNT_NAME, '.'),
Rec_Crs_c1.GLOBAL_ACCOUNT_CODE,
Rec_Crs_c1.t_conto,
(v_anno_in * 100) + v_mese_in,
Rec_Crs_c1.GLOBAL_LOCAL);
END LOOP;
CLOSE Crs_c1;
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line ('Error Message' || SQLERRM);
DBMS_OUTPUT.put_line( 'GLOBAL_ACCOUNT_CODE :'
|| Rec_Crs_c1.LOCAL_ACCOUNT_CODE
|| 'LOCAL_ACCOUNT_CODE '
|| Rec_Crs_c1.LOCAL_ACCOUNT_NAME
|| 'GLOBAL_ACCOUNT_CODE :'
|| Rec_Crs_c1.GLOBAL_ACCOUNT_CODE
|| 'GLOBAL_ACCOUNT_TYPE '
|| Rec_Crs_c1.t_conto
|| 'GLOBAL_LOCAL'
|| Rec_Crs_c1.GLOBAL_LOCAL);
END;
I would like to check if there's no data coming from SQL query then file should not be created.
Here is my code:
CREATE OR REPLACE PROCEDURE VR_AD_INTEGRATION_EXPORT AS
l_v_file UTL_FILE.file_type
BEGIN
l_v_file := UTL_FILE.fopen('integration', 'HRMtoAD1_'||to_char(sysdate,'YYYYMMDD')||'_'||to_char(sysdate,'HH24MISS'), 'w', 32767);
FOR x IN (SELECT * FROM (SELECT
decode(pid, NULL, RPAD(' ',7,' '), RPAD(user_id, 7, ' '))|| '' ||
decode(name_last, NULL, RPAD(' ',50,' '), RPAD(name_last, 50, ' '))
str FROM vr_ad_integration WHERE integrated = 'N') str WHERE rownum <= 1000 ORDER BY rownum)
LOOP
BEGIN
UTL_FILE.put_line(l_v_file, x.str);
END;
END LOOP;
UTL_FILE.fflush(l_v_file);
UTL_FILE.fclose(l_v_file);
END VR_AD_INTEGRATION_EXPORT;
Now I can create file successfully in a remote location. However, what if there's no data in select query? no file should be created. If I am correct, I need to include exception code but I have no idea how to do it in this case. Any suggestion?
Cheers! :-)
There are several ways to achieve this. One is to adopt a more procedural approach with a explicit cursor and only open the file once a record is fetched. A second is to modify your code to include a count inside the loop and delete the file if the count is zero.
Here is a third choice, which is a variant on the previous option. It tests the size of the file and if it is zero deleted it using the UTL_FILE.FREMOVE() command. Note the need to store the generated file name in a variable for reference later.
CREATE OR REPLACE PROCEDURE VR_AD_INTEGRATION_EXPORT AS
l_v_file UTL_FILE.file_type;
l_filename varchar2(128);
f_exists boolean;
f_size pls_integer;
f_blk_size pls_integer;
BEGIN
l_filename := 'HRMtoAD1_'||to_char(sysdate,'YYYYMMDD')||'_'||to_char(sysdate,'HH24MISS');
l_v_file := UTL_FILE.fopen('integration', l_filename , 'w', 32767);
FOR x IN (SELECT * FROM (SELECT
decode(pid, NULL, RPAD(' ',7,' '), RPAD(user_id, 7, ' '))|| '' || decode(name_last, NULL, RPAD(' ',50,' '), RPAD(name_last, 50, ' '))
str
FROM vr_ad_integration
WHERE integrated = 'N') str
WHERE rownum <= 1000 ORDER BY rownum) LOOP
BEGIN
UTL_FILE.put_line(l_v_file, x.str);
END;
END LOOP;
utl_file.fgetattr('integration', l_filename , f_exists, f_size, f_blk_size);
if f_size > 0 then
UTL_FILE.fflush(l_v_file);
UTL_FILE.fclose(l_v_file);
else
UTL_FILE.fclose(l_v_file);
utl_file.fremove('integration', l_filename);
end if;
END VR_AD_INTEGRATION_EXPORT;
There is some useful functionality in the UTL_FILE package beyond reading and writing lines. I suggest you read the documentation to find out more.
Use a flag to check if the file is created, and only create it once on the first run through your loop. Pseudocode:
bool fileCreatedFlag = false;
for x in (SELECT ...):
if(!fileCreatedFlag):
l_v_file = fopen(...);
fileCreatedFlag = true;
put_line(...);
if(fileCreatedFlag):
fflush;
fclose;
In the below oracle sql package body, I receive a "SQL Statement ignored" error and cannot determine the cause. Please see the SELECT statement of the dborLoans_cursor in the PROCEDURE updateLoansInLdcTab in the statement below:
create or replace
PACKAGE body PK_DBORUFT_SYNC AS
PROCEDURE mainProg(v_beginDate DATE, v_endDate DATE) IS
BEGIN
updateLoansInLdcTab(v_beginDate,v_endDate);
END mainProg;
FUNCTION searchForLdcToUpdate(v_beginDate DATE, v_endDate DATE) RETURN type_ref_cursor IS
v_ldcLoan type_ref_cursor;
BEGIN
DBMS_OUTPUT.ENABLE(1000000);
OPEN v_ldcLoan FOR
SELECT loan_id
FROM ldc.ldc_rel_tab
WHERE loan_id NOT IN
(SELECT loan_id
FROM dbor.vw_ldc_data dbor
WHERE dbor.closing_agent IS NOT NULL
AND dbor.closing_agent_phone IS NOT NULL
AND dbor.lock_expiration_date > sysdate)
AND TO_CHAR(request_date, 'MM/DD/YYYY') >= v_beginDate
AND TO_CHAR(request_date, 'MM/DD/YYYY') <= v_endDate;
RETURN v_ldcLoan;
END searchForLdcToUpdate;
PROCEDURE updateLoansInLdcTab(v_beginDate DATE, v_endDate DATE) is
TYPE dborLdcData IS TABLE OF dbor.vw_ldc_data%ROWTYPE;
v_ldcLoan_type_rec type_ref_cursor;
v_ldcLoanCursor_type ldcLoanCursor_type;
dborReference dborLdcData;
v_LDC_LOANID VARCHAR2(10);
v_LOAN_ID VARCHAR2(10);
v_BANKLINE VARCHAR2(20);
v_CHANNEL VARCHAR2(20);
v_PROPERTY_TYPE VARCHAR2(10);
v_STATE VARCHAR2(2);
v_STREET_NAME VARCHAR2(64);
v_FIRST_NAME VARCHAR2(64);
v_LAST_NAME VARCHAR2(64);
v_CLOSING_AGENT VARCHAR2(50);
v_CLOSING_AGENT_PHONE VARCHAR2(15);
v_REGION_CODE VARCHAR2(20);
v_CLPP_FLAG VARCHAR2(1);
v_INSTRUMENT_NAME VARCHAR2(30);
v_BROKER_OFFICER VARCHAR2(30);
v_COST_CENTER VARCHAR2(10);
v_PREPARED_BY VARCHAR2(30);
v_BUYPRICE NUMBER(9,4);
v_SRP NUMBER(8,3);
v_TOTAL_BUYPRICE NUMBER(9,4);
v_TOTAL_SRP NUMBER(8,3);
v_BRANCH_NAME VARCHAR2(30);
v_LOCK_EFFECTIVEDATE DATE;
dbor_count NUMBER;
CURSOR dborLoans_cursor IS
SELECT P.loan_id,
P.property_type,
P.state,
P.street_name,
P.close_date,
P.loan_purpose,
P.borrower_last_name,
P.borrower_first_name,
P.closing_agent,
P.closing_agent_phone,
P.region_code,
P.clpp,
P.instrument_name,
P.broker_officer,
P.lock_effective_date,
P.channel,
NVL(P.buyprice, 0) buyPrice
FROM dbor.vw_ldc_data P
LEFT JOIN dbor.wlnprogram W
ON upper(P.instrument_name) = W.ln_pgm
LEFT JOIN
(SELECT A.loan_id FROM ldc.ldc_rel_tab A WHERE A.ldc_status='LDC_PENDING'
) pend ON pend.loan_id = p.loan_id
LEFT JOIN
(SELECT DISTINCT A.loan_id
FROM ldc.ldc_rel_tab A, ldc.ldc_request_rel_tab B
WHERE A.ldc_status IN ('LDC_PENDING', 'DISBURSED','COMPLETE','RECON_PENDING','SUBMITTED','DISBURSEPAYOFF','VOIDREQUEST','FUNDS_REQUESTED')
AND A.ldc_id = B.ldc_id
AND (B.funding_reason = 'DL Payoff' OR B.funding_reason ='Original Disbursement')
) disbursed ON disbursed.loan_Id = p.loan_id
LEFT JOIN
(SELECT name, phone, agent_id, street1, city, zip, state FROM dbor.WCLOS_AGNT) wagnt
ON wagnt.agent_id=p.loan_id
LEFT JOIN
(SELECT loan,
company_name,
phone_phn,
street,
city,
zip_code,
state
FROM DBOR.WLOAN_PARTY
WHERE type='4'
) wloan ON wloan.loan =p.loan_id
WHERE P.closing_agent IS NOT NULL
AND p.loan_id not in (SELECT loan_id FROM ldc.ldc_rel_tab)
AND P.closing_agent_phone IS NOT NULL
AND P.lock_expiration_date > sysdate ;
v_dborLdcData dbor.vw_ldc_data%ROWTYPE;
BEGIN
DBMS_OUTPUT.ENABLE(1000000);
dborReference := dborLdcData();
v_ldcLoanCursor_type := searchForLdcToUpdate(v_beginDate, v_endDate);
dbor_count := 0;
WHILE dborLoans_cursor%FOUND LOOP
FETCH dborLoans_cursor INTO v_dborLdcData;
dbor_count := dbor_count + 1;
v_LOAN_ID := v_dborLdcData.LOAN_ID;
v_PROPERTY_TYPE := v_dborLdcData.property_type;
v_STATE := v_dborLdcData.state;
v_STREET_NAME := v_dborLdcData.street_name;
v_LAST_NAME := v_dborLdcData.borrower_last_name;
v_FIRST_NAME := v_dborLdcData.borrower_first_name;
v_CLOSING_AGENT := v_dborLdcData.closing_agent;
v_CLOSING_AGENT_PHONE := v_dborLdcData.closing_agent_phone;
v_CLPP_FLAG := v_dborLdcData.clpp;
v_INSTRUMENT_NAME := v_dborLdcData.INSTRUMENT_NAME;
v_BROKER_OFFICER := v_dborLdcData.BROKER_OFFICER;
v_CHANNEL := v_dborLdcData.CHANNEL;
EXECUTE IMMEDIATE 'SELECT region_code FROM dbor.Branch WHERE branch_name = '||v_dborLdcData.CHANNEL INTO v_REGION_CODE;
EXECUTE IMMEDIATE 'SELECT cost_center FROM ldc.REF_BANKLINE_REL WHERE channel = '||v_dborLdcData.CHANNEL INTO v_COST_CENTER;
EXECUTE IMMEDIATE 'SELECT bankline FROM ldc.REF_BANKLINE_REL WHERE channel = '||v_dborLdcData.CHANNEL INTO v_BANKLINE;
v_LOCK_EFFECTIVEDATE := v_dborLdcData.lock_effective_date;
v_BUYPRICE := v_dborLdcData.buyPrice;
LOOP
FETCH v_ldcLoan_type_rec INTO v_LDC_LOANID;
EXECUTE IMMEDIATE
'update ldc.ldc_rel_tabtest
set loan_id = ' ||''''|| v_LOAN_ID||''''||
',bankline = ' ||''''|| v_BANKLINE||''''||
',channel = ' ||''''||v_CHANNEL||''''||
',PROPERTY_TYPE= ' ||''''||v_PROPERTY_TYPE||''''||
',STATE = ' ||''''||v_STATE||''''||
',STREET_NAME = ' ||''''||v_STREET_NAME||''''||
',BORROWER_NAME = ' ||''''||v_LAST_NAME||','||''''||v_FIRST_NAME||''''||
',CLOSING_AGENT = ' ||''''||v_CLOSING_AGENT||''''||
',CLOSING_AGENT_PHONE = ' ||''''||v_CLOSING_AGENT_PHONE||''''||
',REGION_CODE = ' ||''''||v_REGION_CODE||''''||
',CLPP_FLAG = ' ||''''||v_CLPP_FLAG||''''||
',INSTRUMENT_NAME = ' ||''''||v_INSTRUMENT_NAME||''''||
',BROKER_OFFICER = ' ||''''||v_BROKER_OFFICER||''''||
',COST_CENTER = ' ||''''||v_COST_CENTER||''''||
',BUYPRICE = ' ||v_BUYPRICE ||
' where loan_id = ' ||v_LDC_LOANID;
END LOOP;
END LOOP;
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.PUT_LINE(SQLERRM);
END updateLoansInLdcTab;
END PK_DBORUFT_SYNC;
After quick glance at this (without running it), I would have though there are errors on the lines below as you have not put quotes around the value which is being concatenated in:
EXECUTE IMMEDIATE 'SELECT region_code FROM dbor.Branch WHERE branch_name = '||v_dborLdcData.CHANNEL INTO v_REGION_CODE;
EXECUTE IMMEDIATE 'SELECT cost_center FROM ldc.REF_BANKLINE_REL WHERE channel = '||v_dborLdcData.CHANNEL INTO v_COST_CENTER;
EXECUTE IMMEDIATE 'SELECT bankline FROM ldc.REF_BANKLINE_REL WHERE channel = '||v_dborLdcData.CHANNEL INTO v_BANKLINE;
However, from the comments above you seem to have gotten it working.
The bigger problem in this code is why are you using execute immediate at all? You don't need to, and worse you have created non scalable code as the three execute immediate statements above and the big update are not using bind variables. In PLSQL if you avoid using execute_immediate, you don't need to worry about binds at all, PLSQL does it all for you automagically.
Try converting the execute immediate select into something like:
select region_code
into v_region_code
from dbor.branch
where branch_name = v_dborLdcData.CHANNEL;
That will work find and fix the bind variable problem. Then do the same to the update:
update ldc.ldc_rel_tabtest
set loan_id = v_LOAN_ID
bankline = v_bank_line
...
...
where loan_id = v_LDC_LOANID;
The code will be simpler, easier to find errors in the SQL and more scalable.
Problem was due to missing grant on DBOR.WLOAN_PARTY.