Invalid host/bind variable name ORA-01745 - oracle

Hello i m having this error :
Invalid host/bind variable name ORA-01745 at line 47
The error , from the second insert (insert into TPILVALEUR )
when i m using the procedure below , i know that it happen when we use a Oracle variable in the request but im not using it (i think in my queries) , i dont know where he found the Oracle key word in my Insert request ...
create or replace
procedure computePilotageLFIICHN (pCampagne in number)
as
cSep constant varchar2(1) := ':';
cCodeGeoTableauDep constant varchar2(3) := 'DEP';
cCodeGeoTableauReg constant varchar2(3) := 'REG';
cCodeGeoTableauNat constant varchar2(3) := 'NAT';
cCodeTypeTableauCourant constant varchar2(12) := 'LFI_ICHN';
cCodeColTheorie constant varchar2(30) := 'LFI_ICHN_THEORIE';
cCodeColDosAvecLet constant varchar2(30) := 'LFI_ICHN_DOS_AVEC_LFI';
cCodeColAEditer constant varchar2(30) := 'LFI_ICHN_A_EDITER';
cCodeColAReediter constant varchar2(30) := 'LFI_ICHN_A_REEDITER';
cCodeColEditees constant varchar2(30) := 'LFI_ICHN_EDITEES';
idTypeDemd constant varchar2(12) := '20.2010';
lDateDebut timestamp;
lTempsExec varchar2(29);
cNbEtapes constant number := 5;
lEtapeCur number := 0;
begin
PCKISISLOGGER.logavancement('Début Calcul Pilotage LFI ICHN');
pilSupprimerTdB(cCodeTypeTableauCourant,pCampagne);
pilInitialiserTdB(cCodeTypeTableauCourant,pCampagne);
EXECUTE IMMEDIATE 'create global temporary table TPILTMPLFIICHN'||pCampagne||' As SELECT * from TPILTMPLFIICHN';
EXECUTE IMMEDIATE 'insert into TPILTMPLFIICHN'||pCampagne||'(CODEDDAF,NUMEROPACAGE,CAMPAGNE) (select CODEDDAF,NUMEROPACAGE,CAMPAGNE from TPILTMPLFIICHN)';
EXECUTE IMMEDIATE 'TRUNCATE TABLE TPILTMPLFIICHN'||pCampagne;
EXECUTE IMMEDIATE 'INSERT INTO TPILTMPLFIICHN'||pCampagne||'(codeDdaf, numeroPacage, campagne)
SELECT distinct sousReq.codeDdaf, sousReq.numeroPacage, '||pCampagne||'
FROM (
SELECT dos.CODEDDAF codeDdaf, dos.numeropacage numeroPacage
FROM TSRFDOSSIERSURFACE dos,TSRFDEMANDEAIDE dem, TVSFDOSSIERVALORISATION2P dvn
WHERE dem.IDTYPEDEMANDEAIDE = '||idTypeDemd||'
AND dem.IDDOSSIERSURFACE = dos.IDDOSSIERSURFACE
AND dos.campagne = '||pCampagne||' AND dos.DATEDERNIEREEVALUATION > dos.DATEDERNIEREMODIF and dos.DOSSIERMODIFIEAREEVALUER = 0
AND dem.DATEDERNIEREEVALUATION > dem.DATEDERNIEREMODIFICATION and dem.DOSSIERMODIFIEAREEVALUER = 0
AND dvn.ELIGIBLELFI = 1) sousReq';
-- Nombre de destinataires theoriques distincts
lEtapeCur := lEtapeCur + 1;
PCKISISLOGGER.logavancement('Etape ' || lEtapeCur || '/' || cNbEtapes || ' : Calcul du Nombre de destinataires théoriques distincts');
EXECUTE IMMEDIATE 'insert into TPILVALEUR (idValeur, idTableauDeBord, codeLigne, codeColonne, valeur)
SELECT
tab.idTableauDeBord || '||cSep||' || tmpLfi.codeDdaf || '||cSep||' || '||cCodeColTheorie||',
tab.idTableauDeBord,
tmpLfi.codeDdaf,
'||cCodeColTheorie||',
count(distinct tmpLfi.numeroPacage)
FROM
TPILTABLEAUDEBORD tab,
TPILTMPLFIICHN'||pCampagne||' tmpLfi
WHERE
tab.campagne = '||pCampagne||'
AND tmpLfi.campagne = '||pCampagne||'
AND tab.codeTypeTableauDeBord = '||cCodeTypeTableauCourant||'
AND tmpLfi.codeDdaf =
case
when tab.codeTypeGeoTableauDeBord = '||cCodeGeoTableauDep||' then tab.codeDepartement
when tab.codetypegeotableaudebord = '||cCodeGeoTableauReg||' and EXISTS(SELECT 1 FROM trefdepartement dept WHERE dept.code = tmpLfi.codeDdaf AND dept.codeRegion = tab.codeRegion) then tmpLfi.codeDdaf
when tab.codetypegeotableaudebord = '||cCodeGeoTableauNat||' then tmpLfi.codeDdaf
end
GROUP BY
tab.idTableauDeBord,
tmpLfi.codeDdaf';
EXECUTE IMMEDIATE 'drop table TPILTMPLFIICHN'||pCampagne;
PCKISISLOGGER.logavancement('Fin Calcul Pilotage LFI ICHN');
end computePilotageLFIICHN;
/
Thank you

Since you need more quotes to get literals for most of the local variables within the INSERT Statement such as
EXECUTE IMMEDIATE
'INSERT INTO TPILVALEUR (idValeur, idTableauDeBord, codeLigne, codeColonne, valeur)
SELECT
tab.idTableauDeBord || '''||cSep||''' || tmpLfi.codeDdaf || '''||cSep||''' || '''||cCodeColTheorie||''',
tab.idTableauDeBord,
tmpLfi.codeDdaf,
'''||cCodeColTheorie||''',
COUNT(DISTINCT tmpLfi.numeroPacage)
FROM
TPILTABLEAUDEBORD tab
JOIN
TPILTMPLFIICHN'||pCampagne||' tmpLfi
ON tmpLfi.codeDdaf =
CASE
WHEN tab.codeTypeGeoTableauDeBord = '''||cCodeGeoTableauDep||''' THEN tab.codeDepartement
WHEN tab.codetypegeotableaudebord = '''||cCodeGeoTableauReg||''' AND EXISTS(SELECT 1 FROM trefdepartement dept WHERE dept.code = tmpLfi.codeDdaf AND dept.codeRegion = tab.codeRegion) THEN tmpLfi.codeDdaf
WHEN tab.codetypegeotableaudebord = '''||cCodeGeoTableauNat||''' THEN tmpLfi.codeDdaf
END
WHERE tab.campagne = '''||pCampagne||'''
AND tmpLfi.campagne = '''||pCampagne||'''
AND tab.codeTypeTableauDeBord = '''||cCodeTypeTableauCourant||'''
GROUP BY tab.idTableauDeBord, tmpLfi.codeDdaf';

Related

How do I use a variable within another variable in an ORACLE SQL Loop?

I am attempting to use a loop in my Oracle SQL code that will change the name of the schema slightly each time the loop is run. I have tried the SQL code below, creating a NUMBER variable that counts up from 1 to 3 and then concatenating it with the schema name, but I keep receiving a long error message. The schema name should be 'x_rm_mt1_d' the first loop, 'x_rm_mt2_d' the second loop, and 'x_rm_mt3_d' on the final loop. The select statement in the code below is just a small example of what I am trying to do, I didn't think it would be pertinent to include the entire query that I am looking to use the variable for.
DECLARE
l_counter NUMBER := 0;
BEGIN
LOOP
l_counter := l_counter + 1;
IF l_counter > 3 THEN
EXIT;
END IF;
DEFINE StrSchema = 'x_rm_mt' || l_counter || '_d'
WITH aed AS (
SELECT DISTINCT SSN , STATE FROM (
--Effective Date During Quarter
SELECT *
FROM
(SELECT * FROM ADDRESS_EFF_DATE
WHERE STATE = 'VT'
AND EFF_DATE >= '01-JAN-20'
AND EFF_DATE < '01-APR-20'
AND ADDRESS_KEY = '0'
)aed
WHERE aed.EFF_DATE = (
SELECT MAX(aed2.EFF_DATE)
FROM ADDRESS_EFF_DATE aed2
WHERE aed2.CONTROL_ID = aed.CONTROL_ID
AND aed2.SSN = aed.SSN)
--Effective Date Prior to Quarter
UNION
SELECT *
FROM
(SELECT *
FROM Strschema.ADDRESS_EFF_DATE
WHERE STATE = 'VT'
AND EFF_DATE < '01-JAN-20'
AND ADDRESS_KEY = '0') aed
WHERE aed.EFF_DATE = (
SELECT MAX(aed1.EFF_DATE)
FROM Strschema.ADDRESS_EFF_DATE aed1
WHERE aed.ssn=aed1.ssn
AND aed.EFF_DATE < '01-JAN-20'
AND aed1.EFF_DATE < '01-JAN-20')) )
,
--Select all records from Employee Eff Date Where Latest Hire Date is before 4/1/20
--AND Term Date is Null or Term Date is Greater than 1/1/20 eed AS (
SELECT *
FROM
(SELECT *
FROM Strschema.EMPLOYEE_EFF_DATE eed
WHERE eed.CONTROL_ID = 'SMLMKT'
AND eed.EFF_DATE = (
SELECT MAX(eed1.EFF_DATE)
FROM Strschema.EMPLOYEE_EFF_DATE eed1
WHERE eed.SSN = eed1.SSN
AND eed1.CONTROL_ID = 'SMLMKT')
) eed3
WHERE eed3.LATEST_HIRE_DATE <= '04-APR-20'
AND (eed3.LAST_TERM_DATE > '01-JAN-20'
OR eed3.LAST_TERM_DATE is NULL) ) ,
ebe AS (
SELECT *
FROM Strschema.emp_ben_elects ebe
WHERE ebe.control_id = 'SMLMKT'
AND ebe.BENEFIT_ID = 'MEDICAL'
AND ebe.life_event_date = (
SELECT MAX(x.life_event_date)
FROM Strschema.employee_life_events x
WHERE x.ssn = ebe.ssn
AND x.control_id = 'SMLMKT'
AND ebe.p_company_id_i = x.p_company_id_i
AND x.life_event_status = 'C')
AND ebe.le_seq_no = (
SELECT MAX(x.le_seq_no)
FROM Strschema.employee_life_events x
WHERE x.ssn = ebe.ssn
AND x.control_id = 'SMLMKT'
AND ebe.p_company_id_i = x.p_company_id_i
AND x.life_event_status = 'C'
AND ebe.life_event_date = x.life_event_date)
)
SELECT cmp.NAME as "Client Name" , cssn.REAL_SSN as "Employee SSN"
--, aed.SSN as "FAKE SSN REMOVE" , eed.LAST_NAME as "Last Name" , eed.FIRST_NAME as "First Name" , aed.STATE as "Resident State" , eed.LATEST_HIRE_DATE as "Hire Date" , pi.DESCR1 as "Plan Name" , ebe.OPTION_ID as "Tier" , ebe.BENEFIT_EFF_DATE as "Coverage Start Date" , eed.LAST_TERM_DATE as "Coverage End Date"
--, eed.LAST_TERM_DATE
FROM eed INNER JOIN aed ON eed.SSN = aed.SSN
LEFT JOIN ebe ON eed.SSN = ebe.SSN
JOIN Strschema.COMP_SSN cssn ON eed.SSN = cssn.SSN
LEFT JOIN Strschema.PLAN_INFO pi ON ebe.PLAN_ID = pi.PLAN_ID AND ebe.BENEFIT_ID = pi.BENEFIT_ID
JOIN Strschema.COMPANY cmp ON eed.CURRENT_CO = cmp.COMPANY_ID
END LOOP;
END;
DECLARE the variable and then set its value in the loop:
DECLARE
TYPE employee_array IS TABLE OF EMPLOYEE%ROWTYPE;
-- Assuming the tables all have the same type.
l_StrSchema VARCHAR2(30);
t_employees employee_array;
BEGIN
FOR l_counter IN 1 .. 3 LOOP
l_StrSchema := 'x_rm_mt' || l_counter || '_d';
DBMS_OUTPUT.PUT_LINE( 'Loop ' || l_counter );
EXECUTE IMMEDIATE 'SELECT * FROM ' || l_Strschema || '.EMPLOYEE'
|| ' WHERE ROWNUM < 1000'
BULK COLLECT INTO t_employees;
FOR i IN 1 .. t_employees.COUNT LOOP
DBMS_OUTPUT.PUT_LINE( t_employees(i).name );
END LOOP;
END LOOP;
END;
/
You also need to use dynamic SQL if you are dynamically setting the table's schema and will need to collect the rows into a data structure as you are working in PL/SQL (and not in the SQL scope). You can also use a FOR loop.
db<>fiddle

Rewriting SQL statement into PL/SQL

I am trying to rewrite a SQL statement in PL/SQL but I am new to this and I can't get it right.
This is the original statement:
select f.flugnummer, p.nachname, pl.sitzplatznummer, l.bezeichnung, r.reisepassnr,
sum(g.gewicht) as Luggage
from passagierliste pl join flug f on f.flugID = pl.flugID
join gepaeck g on pl.personID = g.personID
join person p on pl.personID = p.personID
join reisepass r on p.personID = r.personID
join land l on r.landID = l.landID
where f.flugnummer ='AF3012'and pl.sitzplatznummer = '13'
group by f.flugnummer, p.nachname, pl.sitzplatznummer, l.bezeichnung, r.reisepassnr;
And this is my attempt in PL/SQL where I am trying to return a passenger who is on the flight AF3012 and seat 13:
CREATE OR REPLACE PROCEDURE getPassenger IS
v_flugnummer varchar2(30);
v_sitzplatz varchar2(30);
BEGIN
v_flugnummer := 'AF3012';
v_sitzplatz := '13';
select f.flugnummer, p.nachname into v_nachname, pl.sitzplatznummer, l.bezeichnung, r.reisepassnr into v_reisepassnr,
sum(g.gewicht) as Luggage into v_luggage
from passagierliste pl join flug f on f.flugID = pl.flugID
join gepaeck g on pl.personID = g.personID
join person p on pl.personID = p.personID
join reisepass r on p.personID = r.personID
join land l on r.landID = l.landID
where f.flugnummer =v_flugnummer and pl.sitzplatznummer = v_sitzplatz
group by f.flugnummer, p.nachname, pl.sitzplatznummer, l.bezeichnung, r.reisepassnr;
IF v_sitzplatz > 0 THEN
DBMS_OUTPUT.PUT_LINE(v_nachname || ' ' || v_flugnummer || ' ' || v_sitzplatz || ' ' || v_reisepassnr || ' ' || v_luggage);
ELSE
DBMS_OUTPUT.PUT_LINE( '0');
END IF;
COMMIT;
END;
/
exec getPassenger;
A little bit simplified (as I removed unnecessary columns your SELECT returned), this is what might work.
don't hardcode parameters; pass them into the procedure for more flexibility
every column select returns has to have its own variable to put that value into. You can't select e.g. 10 columns into e.g. 2 variables; that just won't work
if query doesn't return anything, it'll raise NO_DATA_FOUND you should handle
create or replace procedure getpassenger (par_flugnummer in varchar2,
par_sitzplatz in varchar2
)
is
v_nachname person.nachname%type;
begin
-- find the passenger
select p.nachname
into v_nachname
from passagierliste pl join flug f on f.flugid = pl.flugid
join gepaeck g on pl.personid = g.personid
join person p on pl.personid = p.personid
join reisepass r on p.personid = r.personid
join land l on r.landid = l.landid
where f.flugnummer = par_flugnummer
and pl.sitzplatznummer = par_sitzplatz;
-- passenger has been found - display it
dbms_output.put_line(v_nachname || ' ' || par_flugnummer || ' ' || par_sitzplatz);
exception
when no_data_found then
-- passenger hasn't been found so previous SELECT returned
-- NO_DATA_FOUND; handle it
dbms_output.put_line('Nobody sits there');
end;
/
exec getpassenger(par_flugnummer => 'AF3012', par_sitzplatz => '13');

Trying to create a dynamic merge script and passing the variables dynamically

I am trying to create a dynamic merge script and pass the variables dynamically, but the variable are not getting substituted in the code. Can someone help on this?
create or replace PROCEDURE MERGE_APPMODULE(institutionKey varchar2,applname varchar2,modulename varchar2,DESCRIPTION varchar2 )
as
--set serveroutput on;
--SET FEEDBACK OFF;
DATA long;
BEGIN
select
CONCAT ('declare
institutionkey varchar2(100) := '|| '''institutionkey''' ||' ;
actiondate DATE := SYSDATE;
actionuser VARCHAR2(100) := sys_context(''USERENV'', ''AUTHENTICATED_IDENTITY'');
supportedLanguages varchar2(100) := ''en'';
BEGIN',
'
MERGE INTO APPMODULE TARGET
USING (
SELECT 0 DISALLOW, NULL IMAGE, NULL IsMaintainence, moduleclass,1 ModuleIndex, ''modulename'' ModuleName , ApplId FROM APPLICATION WHERE ApplName = ''applname'' and FinInstKey = ''institutionKey'')
) source
ON (
target.ApplId=source.ApplId and target.ModuleName=source.ModuleName
)
WHEN NOT MATCHED THEN
insert (createddate, creatorusr, Disallow, Image, IsDefault, IsMaintainence, moduleClass, ModuleIndex, ModuleName, updatordate, updatorusr, ApplId)
values (actionDate, actionUser, source.Disallow, source.Image, 1, source.IsMaintainence, source.moduleClass, source.ModuleIndex, source.ModuleName, actionDate, actionUser, source.ApplId);
MERGE INTO APPMODULETXT target
USING (
SELECT ''DESCRIPTION'' DESCRIPTION, ModuleId FROM AppModule m JOIN Application a ON m.ApplId = a.ApplId WHERE m.ModuleName = ''ACCOUNTS_SERVICES_MODULE'' AND a.ApplName = applicationName AND a.finInstKey = ''institutionKey''
) source
ON (
target.ModuleId = source.ModuleId
)
WHEN NOT MATCHED THEN
insert (Description, TxtLanguage, ModuleId)
values (source.Description, ''en'', source.ModuleId);') INTO DATA from dual;
dbms_output.put_line(DATA);
END;
You are not doing concatanation properly.
Strings can be concated using || operaror or concat method.
In your code you used both and mess happened. Here, I tried using || operator as following:
create or replace PROCEDURE MERGE_APPMODULE(institutionKey varchar2,applname varchar2,modulename varchar2,DESCRIPTION varchar2 )
as
--set serveroutput on;
--SET FEEDBACK OFF;
DATA VARCHAR2(32767); -- using varchar2 data type variable
BEGIN
DATA := 'declare
institutionkey varchar2(100) := '''|| institutionkey ||''' ;
actiondate DATE := SYSDATE;
actionuser VARCHAR2(100) := sys_context(''USERENV'', ''AUTHENTICATED_IDENTITY'');
supportedLanguages varchar2(100) := ''en'';
BEGIN' || chr(10) ||
' MERGE INTO APPMODULE TARGET
USING (
SELECT 0 DISALLOW, NULL IMAGE, NULL IsMaintainence, moduleclass,1 ModuleIndex, '''|| modulename ||''' ModuleName , ApplId FROM APPLICATION WHERE ApplName = ''' || applname || ''' and FinInstKey = ''' || institutionKey || '''
) source
ON (
target.ApplId=source.ApplId and target.ModuleName=source.ModuleName
)
WHEN NOT MATCHED THEN
insert (createddate, creatorusr, Disallow, Image, IsDefault, IsMaintainence, moduleClass, ModuleIndex, ModuleName, updatordate, updatorusr, ApplId)
values (actionDate, actionUser, source.Disallow, source.Image, 1, source.IsMaintainence, source.moduleClass, source.ModuleIndex, source.ModuleName, actionDate, actionUser, source.ApplId);
MERGE INTO APPMODULETXT target
USING (
SELECT ''' || DESCRIPTION || ''' DESCRIPTION, ModuleId FROM AppModule m JOIN Application a ON m.ApplId = a.ApplId WHERE m.ModuleName = ''ACCOUNTS_SERVICES_MODULE'' AND a.ApplName = applicationName AND a.finInstKey = ''' || institutionKey || '''
) source
ON (
target.ModuleId = source.ModuleId
)
WHEN NOT MATCHED THEN
insert (Description, TxtLanguage, ModuleId)
values (source.Description, ''en'', source.ModuleId);';
dbms_output.put_line(DATA);
END;
Check if it is working for you.
Cheers!!
Why are you using type LONG in this century?
It has been sort of deprecated since Oracle 8.0 came out in 1997.
Using CLOB will generally make your life a lot easier, but in this case even a VARCHAR2 is probably large enough to fit your query.

How do i capture the update column value and use it?

Hi I have a scenario where in using a cursor loop getting all the invoice values and checking the details and updating flag values to 'E' if the update validation is satisfied and only inserting those invoices to another table which doesn't satisfy the update statement.
Is there a way by which based on the flag value we can insert those invoices?
Kindly find the Code:
Procedure
CURSOR c2
IS
SELECT *
FROM invoice_tl
WHERE process_flag = 'N';
BEGIN
FOR rec IN c2
LOOP
BEGIN
fnd_file.put_line (fnd_file.LOG, 'The Line Number is ' || ' ' || rec.line_number);
IF rec.line_number IS NOT NULL
THEN
UPDATE invoice_tl
SET process_flag = 'E',
error_description =
(SELECT 'Credit Memo line amount cannot be more than Invoice Line Amount : '
|| (rctl.extended_amount
- NVL (
(SELECT SUM (amount)
FROM ar_activity_details
WHERE customer_trx_line_id =
rctl.customer_trx_line_id),
0)
+ NVL (
(SELECT SUM (extended_amount)
FROM ra_customer_trx_lines_all
WHERE previous_customer_trx_line_id =
rctl.customer_trx_line_id),
0))
FROM ra_customer_trx_all rct,
ra_customer_trx_lines_all rctl
WHERE rct.customer_trx_id =
rctl.customer_trx_id
AND rct.org_id = 2326
AND rct.trx_number = rec.invoice_number
AND rctl.line_number = rec.line_number
AND rct.cust_trx_type_id =
ln_trans_type_id)
WHERE process_flag = 'N'
AND invoice_number = rec.invoice_number
AND line_number = rec.line_number
AND amount >
(SELECT (rctl.extended_amount
- NVL (
(SELECT SUM (amount)
FROM ar_activity_details
WHERE customer_trx_line_id =
rctl.customer_trx_line_id),
0)
+ NVL (
(SELECT SUM (extended_amount)
FROM ra_customer_trx_lines_all
WHERE previous_customer_trx_line_id =
rctl.customer_trx_line_id),
0))
FROM ra_customer_trx_all rct,
ra_customer_trx_lines_all rctl
WHERE rct.customer_trx_id =
rctl.customer_trx_id
AND rct.org_id = 2326
AND rct.trx_number =
rec.invoice_number
AND rctl.line_number =
rec.line_number
AND rct.cust_trx_type_id =
ln_trans_type_id);
fnd_file.put_line (
fnd_file.LOG,
'Error Message if the CM amount more than the Invoice Line amount.');
COMMIT;
END IF;
END;
BEGIN
fnd_file.put_line (
fnd_file.LOG,
'The Process FLag is : ' || rec.process_flag);
INSERT INTO second_table (
customer_number,
orig_system_cust_reference,
orig_system_add_reference,
customer_name,
locations,
inv_date,
creation_date,
inv_num,
balance_amount,
customer_trx_id,
customer_trx_line_id,
NAME,
term_desc,
term_id,
gl_date,
rec_segments1,
rec_segments2.....
END;
END LOOP;
END
Your best bet is to use the RETURNING INTO clause. So you'll define an array and capture the appropriate parts of the updated rows:
declare
type line_number_tt is table of invoice_tl.line_number%TYPE;
line_number_array line_number_tt;
begin
....
update invoice_tl
...
returning line_number bulk collect into line_number_array;
[do stuff with the array here]
end;
I would really try to get rid of the select-then-loop you have, if you can. That's row by row processing and there's a reason it's called "slow-by-slow."

Cursor issue with Stored Procedure

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.

Resources