Have this employee table:
And a plsql query:
DECLARE
totaal_salaris INT := 0;
CURSOR medewerker_cur IS
SELECT naam, maandsal
FROM MEDEWERKERS;
medewerker_row medewerker_cur%rowtype;
BEGIN
OPEN medewerker_cur;
LOOP
FETCH medewerker_cur INTO medewerker_row;
EXIT WHEN medewerker_cur%NOTFOUND OR totaal_salaris > 50000;
UPDATE medewerkers
SET maandsal = (medewerker_row.maandsal * 1.10)
WHERE naam = medewerker_row.naam;
totaal_salaris := totaal_salaris + medewerker_row.maandsal;
END LOOP;
dbms_output.put_line('Totaal uit te keren salaris: ' || totaal_salaris);
END;
/
The intention was to increase all existing employees salary (maandsal) by 10% so long as the total salary < 50.000. But this is not working out at all..
I 3 double checked witch running the script and this is the result I get:
Some test results:
First time running:
PL/SQL procedure successfully completed.Totaal uit te keren salaris: 55000
maandsal changed into 5500;
Second time
PL/SQL procedure successfully completed.Totaal uit te keren salaris: 55000
maandsal changed into 6050
Thirth time
PL/SQL procedure successfully completed. Totaal uit te keren salaris: 54450
maandsal changed into 6655
This should be the solution.
DECLARE
total_salaris INT := 0;
CURSOR employee_cur IS
SELECT employee_id, first_name, salary
FROM employees;
employee_rec employee_cur%rowtype;
BEGIN
OPEN employee_cur;
LOOP
FETCH employee_cur INTO employee_rec;
total_salaris := total_salaris + (employee_rec.salary * 1.1);
EXIT WHEN employee_cur%NOTFOUND OR total_salaris > 50000;
UPDATE employees
SET salary = (employee_rec.salary * 1.10)
WHERE employee_id = employee_rec.employee_id;
END LOOP;
CLOSE employee_cur;
END;
Related
I have this plsql block that populates a table with information of two other tables and I have to use a variable array:
DECLARE nombre_grupo VARCHAR2(15);
direccion_tipo direccion;
persona_tipo persona;
personas_array personas := personas();
CURSOR departamento IS
SELECT * FROM departamentos;
CURSOR empleado IS
SELECT * FROM empleados, departamentos
WHERE empleados.dept_no = departamentos.dept_no;
i INTEGER;
BEGIN
FOR departamento IN (SELECT * FROM departamentos) LOOP
nombre_grupo := departamento.dnombre;
i := 1;
personas_array := personas();
FOR empleado IN (SELECT * FROM empleados WHERE dept_no = departamento.dept_no) LOOP
direccion_tipo := DIRECCION(departamento.loc, 'NULL', empleado.dir);
personas_array(i) := PERSONA(empleado.emp_no, empleado.apellido,
direccion_tipo, empleado.fecha_alt);
i := i + 1;
END LOOP;
INSERT INTO grupos VALUES (nombre_grupo, personas_array);
END LOOP;
END;
Here's the type personas:
CREATE OR REPLACE TYPE personas AS VARRAY(5) OF PERSONA
So when I execute that block and it reaches the personas_array(i) bit, it exits the execution with "subscript beyond count" error, no matter what value of i. What am I missing?
I've already deleted and created the type personas again, I've also tried creating the type inside the procedure, but it can't insert into the table
A few tips for a SQL beginner:
Don't learn 30 years old Oracle join syntax. Use modern ANSI join syntax, i.e.
SELECT *
FROM empleados
JOIN departamentos ON empleados.dept_no = departamentos.dept_no;
Your cursors are redundant. Either use
DECLARE
CURSOR cur_departamento IS
SELECT *
FROM departamentos;
BEGIN
FOR departamento IN cur_departamento LOOP
...
END LOOP;
END;
or
DECLARE
BEGIN
FOR departamento IN (SELECT * FROM departamentos) LOOP
...
END LOOP;
END;
You can also use this:
DECLARE
CURSOR cur_empleados(d IN EMPLEADOS.DEPT_NO%TYPE) IS
SELECT *
FROM EMPLEADOS
WHERE dept_no = d;
/*
-- Do not use this!
CURSOR cur_empleados(dept_no IN EMPLEADOS.DEPT_NO%TYPE) IS
SELECT *
FROM EMPLEADOS
WHERE EMPLEADOS.dept_no = dept_no; -> will return all rows
*/
BEGIN
FOR departamento IN (SELECT * FROM departamentos) LOOP
FOR empleado IN cur_empleados(departamento.dept_no) LOOP
...
END LOOP;
END LOOP;
END;
According to my feelings, VARRAYs are often part of student material but hardly used in real life.
Using string 'NULL' is most likely not want you want. Use literal NULL, i.e.
DIRECCION(departamento.loc, NULL, empleado.dir)
Type VARRAY(5) OF PERSONA defines a varray with maximum size of 5 elements. When you initialize it with personas_array := personas(); then the actual size is 0. You need to extend the varray.
You code may look like this:
DECLARE
nombre_grupo VARCHAR2(15);
direccion_tipo direccion;
persona_tipo persona;
personas_array personas;
i INTEGER;
BEGIN
FOR departamento IN (SELECT * FROM departamentos) LOOP
nombre_grupo := departamento.dnombre;
i := 1;
personas_array := personas();
FOR empleado IN (SELECT * FROM empleados WHERE dept_no = departamento.dept_no AND ROWNUM <= 5) LOOP
direccion_tipo := DIRECCION(departamento.loc, NULL, empleado.dir);
personas_array.extend();
personas_array(i) := PERSONA(empleado.emp_no, empleado.apellido, direccion_tipo, empleado.fecha_alt);
i := i + 1;
END LOOP;
INSERT INTO grupos VALUES (nombre_grupo, personas_array);
END LOOP;
END;
Just a note, such procedure would have rather low performance. The professional way of doing it would be a Nested Table and then insert the data with a single command:
CREATE OR REPLACE TYPE personas_NT AS TABLE OF PERSONA;
INSERT INTO grupos VALUES (nombre_grupo, personas_array)
SELECT dnombre,
CAST(MULTISET(
SELECT
emp_no,
apellido,
DIRECCION(dept.loc, NULL, dir),
fecha_alt
FROM EMPLEADOS
WHERE dept_no = dept.dept_no
) AS personas_NT) AS personas_array
FROM DEPARTAMENTOS dept;
But maybe, that would be a chapter in the "advanced" SQL course.
I have created Procedure which calculates gross salary of all employees from salary table.When executing stored procedure using execute statement Error:"invalid SQL statement" occurs and when i am executing procedure using PLSQL block then Error":PLS-00905 Object HR.PROC_GROSSSALARY is invalid" occurs
-- Creating Stored procedure --
create or replace procedure proc_grosssalary
AS
begin
select s.*,(Basic+HRA+DA+CA+Medical) Gross_Salary from salary s;
end;
-- Calling SP using EXECUTE --
execute proc_grosssalary;
-- Calling SP using PLSQL Block --
begin
proc_grosssalary;
end;
display all data in salary table with calculated Gross_Salary in the form of table structure
your PL/SQL syntax is not correct
create or replace procedure proc_grosssalary (out gross_salary number)
AS
begin
select (Basic+HRA+DA+CA+Medical)
into gross_salary
from salary s;
end;
You should also consider the option of creating a View.
Create or replace view v_grosssalary
as select s.*,(Basic+HRA+DA+CA+Medical) Gross_Salary
from salary s;
and simply do select * from v_grosssalary to get the output.
With procedures, there's also a PRINT command(which works in SQL* Plus and SQL developer) using CURSOR bind variables
VARIABLE x REFCURSOR
create or replace procedure proc_grosssalary
AS
begin
OPEN cursor :x for
select s.*,(Basic+HRA+DA+CA+Medical) Gross_Salary from salary s;
end;
/
Print x -- This will display the required result.
But.. What do you want to do? If you want calculate salary for every employee and you have your information in the same row, with a simple SQL you could have it, something like this:
Select id_emp, name_emp, surname_emp, (Basic+HRAs+DA+CA+Medical) as salary
from salary;
And it would be more quick than have strange functions and procedures.. If you don't like it, create a view like these and you'll have a column with the salary calculated, more clean and less obscure
You need to use a cursor so that you can loop on records in the table.
Here is what I did -
#create a table for sample data
create table tsalary0918(Basic number,HRA number,DA number,CA number,Medical number)
#inserting sample data
insert into tsalary0918 values (100,100,100,100,100)
#checking if data is inserted
select * from tsalary0918;
#query output
BASIC HRA DA CA MEDICAL
100 100 100 100 100
#create a stored procedure
create or replace procedure testproc
AS
cursor cur is select s.*,(Basic +HRA + DA +CA +Medical ) Gross_salary from tsalary0918 s;
begin
for records in cur
loop
dbms_output.put_line('DA is ' || records.DA);
dbms_output.put_line('Gross Salary is ' || records.Gross_salary);
end loop;
end;
/
#execute the stored procedure
begin
testproc;
end;
/
#output of the above execution
dbms_output:
DA is 100
Gross Salary is 500
Check online - https://dbfiddle.uk/?rdbms=oracle_11.2&fiddle=1744281398fe62a6cb42250641947249
Task completed:
create or replace procedure p1
IS
cursor c1 is select s.*,(Basic+HRA+CA+DA+Medical) Gross_Salary from salary s;
emp_rec c1%rowtype;
begin
open c1;
dbms_output.put_line('Emp_No Basic HRA Gross_Salary');
dbms_output.put_line('---------------------------------------');
loop
fetch c1 into emp_rec;
exit when c1%notfound;
dbms_output.put_line(emp_rec.employee_number||' '||emp_rec.Basic||' '||emp_rec.HRA||' '||' '||emp_rec.Gross_Salary);
end loop;
close c1;
end;
-- Executing the procedure using PLSQL block --
begin
p1;
end;
Below is expected Final result:
----------------------------------------------
Employee_number Basic HRA Gross_salary
----------------------------------------------
1 25000 10000 36750
2 7000 2800 11650
3 10000 4000 15950
I am trying to update the 'damage_amt' of cars by increasing the value by 'inc', but only for accidents that occurred in year 'year'.
CREATE or REPLACE PROCEDURE updateDMG(xyear VARCHAR2, inc NUMBER) AS
CURSOR cur1 IS
select a.DAMAGE_AMT
from participated a join accident b
on a.report_nr = b.report_nr
for update;
p_dmg PARTICPATED.damage_amt%TYPE;
p_year NUMBER;
inc_dmg NUMBER;
BEGIN
p_year:=xyear;
inc_dmg:=inc;
OPEN cur1;
LOOP
FETCH cur1 bulk collect INTO p_dmg;
EXIT WHEN cur1%NOTFOUND;
UPDATE PARTICIPATED
SET damage_amt = damage_amt * inc_dmg
WHERE p_dmg like xyear;
END LOOP;
CLOSE cur1;
END updateDMG;
/
EXEC updateDMG('08', 0.10);
But I'm getting the error:
PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following: begin function pragma procedure subtype <an identifier> <a double-quoted delimited-identifier> current cursor delete exists prior
Obviously I am lacking knowledge on the syntax of this type of answer. Can anyone point out my error? I can't seem to find anything from searching.
EDIT: Was missing a / after END. Now it doesn't actually update the rows.
FINAL EDIT: Figured it out. I think some of my variables are unnecessary, but I could be wrong.
CREATE or REPLACE PROCEDURE updateDMG(xyear NUMBER, inc DECIMAL) AS
CURSOR cur1 IS
select a.DAMAGE_AMT, extract(year from b.ACCIDENT_DATE)
from participated a join accident b
on a.report_nr = b.report_nr
for update;
p_dmg PARTICIPATED.damage_amt%TYPE;
p_year NUMBER;
input_year NUMBER;
inc_dmg DECIMAL;
BEGIN
input_year:=xyear;
inc_dmg:=inc;
OPEN cur1;
FETCH cur1 INTO p_dmg, p_year;
MERGE INTO PARTICIPATED x
USING ACCIDENT y
ON (x.report_nr = y.report_nr)
WHEN MATCHED THEN
UPDATE SET x.damage_amt = x.damage_amt * (1 + inc_dmg/100)
WHERE extract(year from y.accident_date) = input_year;
CLOSE cur1;
END updateDMG;
/
EXEC updateDMG(2008, 10);
I don't have a database right now to fully check syntax, but I would suggest something like this:
CREATE OR REPLACE PROCEDURE updatedmg (p_year NUMBER, p_inc DECIMAL)
AS
l_next_year NUMBER;
l_from_date DATE;
l_to_date DATE;
BEGIN
l_next_year := p_year + 1;
l_from_date := TO_DATE (p_year || '-01-01', 'RRRR-MM-DD');
l_to_date := TO_DATE (l_next_year || '-01-01', 'RRRR-MM-DD');
UPDATE participated pt
SET pt.damage_amt = pt.damage_amt * (1 + p_inc / 100)
WHERE pd.report_nr IN (SELECT ad.report_nr
FROM accident ad
WHERE ad.accident_date >= l_from_date
AND ad.accident_date < l_to_date);
END updatedmg;
Its simple and that way you probably can make better use of indexes on tables.
I hope it helps.
Good luck!
Not sure if this is possible, but I'm trying to see if I can convert this procedure to become a view because we've been having trouble with drives not populating the table when the procedure is run.
I'm trying to understand someone else's code and because of the cursors, I'm not even sure we can change this procedure to a view.
----------------------------------------------------------------------
--This Procedure will interface drive information on a nightly basis--
----------------------------------------------------------------------
Procedure HEMA_DRIVE_AUTO IS
v_start_date DATE := trunc(sysdate) -30;
v_end_date DATE := trunc(sysdate);
v_delete_stats_dt DATE := trunc(sysdate)-120;
v_total_registration_count NUMBER;
v_total_performed_count NUMBER;
v_total_collected_count NUMBER;
v_total_deferred_count NUMBER;
v_total_qns_count NUMBER;
v_existing_drive NUMBER;
v_existing_performed NUMBER;
v_maph_drive NUMBER;
--This Cursor will collect the initial data
cursor c_drive_info is
select dr.drive_id, dr.Start_time, dr.vehicle_id
from drives dr
--where dr.drive_id in(1605606);
where trunc(dr.start_time) between v_start_date and v_end_date;
--This Cursor will be used to decode the Donation Types
cursor c_procedure_codes is
select * from hema_donation_type_map hdt
where hdt.mobiles = 1 order by procedure_code_id;
--This Cursor will define the intentions but exclude theraputics inthe mapping
cursor c_intention is
select rsa_motivation_id,hema_intent_id from hema_intent_map
where rsa_motivation_id <> 4 order by rsa_motivation_id;
BEGIN
-- delete records older then 4 months
delete from hema_nightly h where trunc(h.drive_date) < v_delete_stats_dt;
commit;
FOR cur_drive IN c_drive_info LOOP
delete from hema_nightly where drive_id = cur_drive.drive_id;
commit;
-- Loop by motivation/intention
FOR cur_intent in c_intention LOOP
-- Loop to get the procedure code data
FOR cur_proc_code IN c_procedure_codes LOOP
v_total_registration_count := 0;
v_total_performed_count := 0;
v_total_collected_count := 0;
v_total_deferred_count := 0;
v_total_qns_count := 0;
v_maph_drive := 0;
-- get the count for all other procedures
select count(1)
into v_total_registration_count
from registration r
where r.drive_id = cur_drive.drive_id
and r.donation_type_id = cur_proc_code.donation_type_id
and r.motivation_id = cur_intent.rsa_motivation_id;
--get the deferral count
select count(unique(r.registration_id))
into v_total_deferred_count
from registration r
where r.drive_id = cur_drive.drive_id
and r.donation_type_id = cur_proc_code.donation_type_id
and r.motivation_id = cur_intent.rsa_motivation_id
and r.step_completed < 12
and exists (select rsc.registration_id
from reg_steps_completed rsc
where rsc.registration_id = r.registration_id
and rsc.collection_step_id = 99);
-- QNS count
select count(unique(r.registration_id))
into v_total_qns_count
from registration r
where r.drive_id = cur_drive.drive_id
and r.step_completed < 12
and not exists (select rsc.registration_id
from reg_steps_completed rsc
where rsc.registration_id = r.registration_id
and rsc.collection_step_id = 99)
and r.donation_type_id = cur_proc_code.donation_type_id
and r.motivation_id = cur_intent.rsa_motivation_id;
-- performed count is the difference between total registrations and total deferrals.
v_total_performed_count := v_total_registration_count -
(v_total_deferred_count +
v_total_qns_count);
-- not calulatind yield so keep count the same
v_total_collected_count := v_total_performed_count;
-- does this drive exist
select count(drive_id)
into v_existing_drive
from hema_nightly
where drive_id = cur_drive.drive_id
and procedure_id = cur_proc_code.procedure_code_id
and intent = cur_intent.hema_intent_id;
-- Is this an aph vehicle?
select count(vehicle_id)
into v_maph_drive
from vehicles
where veh_drive_type_uid = 2
and vehicle_id = cur_drive.vehicle_id;
if v_existing_drive > 0 then
update hema_nightly
set performed = performed + v_total_performed_count,
collected = collected + v_total_collected_count,
registered = registered + v_total_registration_count,
deferrals = deferrals + v_total_deferred_count,
qns = qns + v_total_qns_count,
drive_date = cur_drive.start_time,
mod_date = sysdate,
intent = cur_intent.hema_intent_id,
aph = v_maph_drive
where drive_id = cur_drive.drive_id
and procedure_id = cur_proc_code.procedure_code_id
and intent = cur_intent.hema_intent_id;
commit;
elsif v_existing_drive = 0 and v_total_registration_count > 0 then
insert into hema_nightly
(drive_id,
procedure_id,
performed,
collected,
registered,
deferrals,
qns,
drive_date,
mod_date,
intent,
aph)
values
(cur_drive.drive_id,
cur_proc_code.procedure_code_id,
v_total_performed_count,
v_total_collected_count,
v_total_registration_count,
v_total_deferred_count,
v_total_qns_count,
trunc(cur_drive.start_time),
sysdate,
cur_intent.hema_intent_id,
v_maph_drive);
commit;
end if;
v_existing_drive := 0;
end loop;
end loop;
end loop;
end hema_drive_auto;
Views don't perform DML (insert, update, delete) and they don't manage transactions with COMMIT and ROLLBACK; they only select and retrieve data.
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.