Error(13,34): PLS-00201: identifier 'D.BNDNG_TYP' must be declared - sql

I wrote a procedure where i am trying to insert value from source to destination table, i used bulk collect in order to execute the data for large amount of data.
create or replace PROCEDURE TEST2 (
p_array_size IN NUMBER
) IS
CURSOR cur1 IS SELECT DISTINCT
*
FROM
test;
CURSOR cur3 IS SELECT * FROM test;
CURSOR cur2( BND_TYPE d.bndng_typ%TYPE, BND_VAL d.bndng_val%TYPE, FINANCIAL_INST_ID d.financial_institution_id%TYPE, PRDCT_ID d.prdct_id%TYPE,
PRDCT_SUB_ID d.prdct_sub_id%TYPE, INSTRUMENT_ID d.instrmnt_id%TYPE) IS SELECT
d.*
FROM
test1 d,
(
SELECT
b.prdct_id,
FROM
test2 a,
test1 b
WHERE
a.ir_id = b.ir_id
AND a.price_component_id = b.price_component_id
AND a.financial_institution_id = b.financial_institution_id
GROUP BY
b.prdct_id,
) e
WHERE
d.prdct_id = e.prdct_id
AND d.bndng_typ = BND_TYPE
AND d.bndng_val = BND_VAL
AND d.financial_institution_id = FINANCIAL_INST_ID
AND d.prdct_id = PRDCT_ID
AND d.prdct_sub_id = PRDCT_SUB_ID
AND d.instrmnt_id = INSTRUMENT_ID ;
TYPE loan_data_tbl IS TABLE OF cur1%rowtype INDEX BY PLS_INTEGER;
loan_data loan_data_tbl;
TYPE loanrate_tbl IS TABLE OF cur2%rowtype INDEX BY BINARY_INTEGER;
loan_rate loanrate_tbl;
BEGIN
DECLARE
v_noofDays NUMBER:=0;
currentDt DATE;
BEGIN
SELECT * INTO currentDt FROM dt;
BEGIN
IF cur1%Isopen Then
Close cur1;
End IF;
IF cur2%Isopen Then
Close cur2;
End IF;
OPEN cur1;
LOOP
FETCH cur1 BULK COLLECT INTO loan_data LIMIT p_array_size;
EXIT WHEN loan_data.COUNT = 0;
FOR i IN 1..loan_data.COUNT
LOOP
OPEN cur3;
OPEN cur2(loan_data(i).bndng_typ, loan_data(i).bndng_val,loan_data(i).financial_institution_id,
loan_data(i).prdct_id, loan_data(i).prdct_sub_id, loan_data(i).instrmnt_id);
loop
FETCH cur2 BULK COLLECT INTO loan_rate LIMIT p_array_size;
EXIT WHEN loan_rate.COUNT = 0;
FOR j IN 1..loan_rate.COUNT
LOOP
IF(cur3.POS_NUM = loan_data(i).POS_NUM AND cur3.POS_TYPE = loan_data(i).POS_TYPE
AND cur3.PRICE_COMPONENT_ID = loan_rate(j).PRICE_COMPONENT_ID
AND cur3.RPRTD_TILL_DT = loan_data(i).RPRTD_TILL_DT) THEN
update test SET SEQ_NUM=1,
WHERE SEQ_NUM=2;
ELSE
INSERT INTO test VALUES (
....
....
);
END IF;
COMMIT;
END LOOP;
END LOOP;
CLOSE cur2;
CLOSE cur1;
END LOOP;
END LOOP;
CLOSE cur1;
END;
END;
End ;
/
In above procedure, i removed some column names for security purpose.
I am getting two errors one is
PLS-00201: identifier 'D.BNDNG_TYP' must be declared and
PLS-00225: subprogram or cursor 'cur3' reference is out of scope
if any one can help to solve this.

In cursor, You cannot provide the type referring to alias from cursor query. You need to just provide the table name test1 instead of alias d.
CURSOR cur2( BND_TYPE test1.bndng_typ%TYPE,
BND_VAL test1.bndng_val%TYPE,
FINANCIAL_INST_ID test1.financial_institution_id%TYPE,
PRDCT_ID test1.prdct_id%TYPE,
PRDCT_SUB_ID test1.prdct_sub_id%TYPE,
INSTRUMENT_ID test1.instrmnt_id%TYPE)
IS SELECT
.....

This is untested as I don't have your tables and data, but as a first refactoring I would start with this type of structure:
create or replace procedure test2
as
cursor loan_data_cur
( bnd_type cr_loan_prima_rate_orig.bndng_typ%type
, bnd_val cr_loan_prima_rate_orig.bndng_val%type
, financial_inst_id cr_loan_prima_rate_orig.financial_institution_id%type
, prdct_id cr_loan_prima_rate_orig.prdct_id%type
, prdct_sub_id cr_loan_prima_rate_orig.prdct_sub_id%type
, instrument_id cr_loan_prima_rate_orig.instrmnt_id%type )
is
select d.*
from test1 d
join ( select b.prdct_id
from test2 a
join test1 b
on b.ir_id = a.ir_id
and b.price_component_id = a.price_component_id
and b.financial_institution_id = a.financial_institution_id
group by b.prdct_id ) e
on d.prdct_id = e.prdct_id
where d.bndng_typ = loan_data_cur.bnd_type
and d.bndng_val = loan_data_cur.bnd_val
and d.financial_institution_id = loan_data_cur.financial_inst_id
and d.prdct_id = loan_data_cur.prdct_id
and d.prdct_sub_id = loan_data_cur.prdct_sub_id
and d.instrmnt_id = loan_data_cur.instrument_id;
begin
for loan_data in (
select distinct *
from test
)
loop
for loan_rate in loan_data_cur
( loan_data.bndng_typ
, loan_data.bndng_val
, loan_data.financial_institution_id
, loan_data.prdct_id
, loan_data.prdct_sub_id
, loan_data.instrmnt_id )
loop
update test t set t.seq_num = 1
where t.seq_num = 2
and t.pos_num = loan_data.pos_num
and t.pos_type = loan_data.pos_type
and t.price_component_id = loan_rate.price_component_id
and t.rprtd_till_dt = loan_data.rprtd_till_dt;
if sql%rowcount = 0 then
insert into test values (x, y, z);
end if;
end loop;
end loop;
commit;
end test2;
I would also looking at doing the join from test to test1 as a single cursor instead of explicitly with two separate cursors, as the optimiser might find a more efficient method, such as a hash join.
Probably the update/insert combination could be written as a single merge. Once you have a merge working, you might find you can apply it to the whole table in one shot and not need any cursor loops at all.
Bulk-collecting into an array could be useful if the number of row-by-row updates causes performance problems (if it's more than a few thousand, say). If so, you would want to structure it so that you could apply the updates/inserts using a forall construction, not more loops.

Related

BULK COLLECT in a trigger

I need to create a trigger that updates a column in a table based on a transaction that happens in another table. Is there a way to use BULK COLLECT on joining two tables?
I need to collect data multiple times, is it possible to use BULK COLLECT inside another BULK COLLECT?
HERE is my existing trigger
create or replace trigger trans_hist_trg
AFTER INSERT OR UPDATE OF reason ON transaction_history
FOR EACH ROW
DECLARE
v_exists VARCHAR2(1);
v_valid code.valid_code%TYPE;
v_person_id person.id%TYPE;
TYPE Anumber_Type is TABLE of person.registration_number%TYPE INDEX BY binary_INTEGER;
v_NumberList Anumber_Type;
v_primaryAnumber person.primary_number%TYPE;
v_secondaryAnumber consolidated_numbers.secondary_number%TYPE;
v_anumber person.registration_number%TYPE;
BEGIN
IF(INSERTING) THEN
v_person_id := :NEW.person_id;
ELSE
v_person_id := :OLD.person_id;
END IF;
BEGIN
SELECT p.registration_number, p.primary_number, c.secondary_number INTO v_anumber, v_primaryAnumber, v_secondaryAnumber
FROM person p
LEFT JOIN consolidated_numbers c ON p.id = c.person_id WHERE p.id = v_person_id;
END;
BEGIN
SELECT women_act INTO v_exists
FROM person
WHERE id = v_person_id;
EXCEPTION
WHEN NO_DATA_FOUND THEN
v_exists := NULL;
END;
IF v_exists IS NULL AND :NEW.type_id IN (10,20,30,40,50) THEN
IF :NEW.reason NOT IN ('A1','B1') OR (:NEW.reason IN ('A1','B1') AND :NEW.action_date >= '01-JAN-00') THEN
BEGIN
SELECT valid_code INTO v_valid
FROM code
WHERE valid_code = :NEW.reason;
EXCEPTION
WHEN NO_DATA_FOUND THEN
v_exists := null;
END;
IF v_valid IS NOT NULL THEN
SELECT CASE
WHEN EXISTS (SELECT 1 FROM code WHERE valid_code = v_valid)
THEN 'Y' ELSE 'N' END INTO v_exists FROM dual;
END IF;
IF v_exists = 'Y' THEN
select registration_number BULK COLLECT into v_NumberList
FROM person where (registration_number=v_primaryAnumber OR
registration_number=v_anumber OR
registration_number=v_secondaryAnumber OR
primary_number= v_secondaryAnumber OR
primary_number=v_anumber OR
primary_number=v_primaryAnumber ) and (primary_number IS NOT NULL or primary_number <>'000000');
ELSE
select registration_number BULK COLLECT into v_NumberList
FROM person where (registration_number=v_primaryAnumber OR
registration_number=v_anumber OR
registration_number=v_secondaryAnumber OR
primary_number=v_anumber OR
primary_number=v_secondaryAnumber OR
primary_number=v_primaryAnumber OR
primary_number IS NULL);
END IF;
FOR indx IN 1 .. v_NumberList.COUNT
LOOP
update person set women_act = 'X'
where registration_number=v_NumberList(indx) and (women_act<>'X' or women_act IS NULL);
END LOOP;
update person set women_act = 'X'
where registration_number=v_anumber and (women_act<>'X' or women_act IS NULL);
END IF;
END IF;
mmm
END trans_hist_trg;
I need to make this block of code to be my main outer loop to iterate through all the numbers. But I'm unsure how. Please help.
SELECT p.registration_number, p.primary_number, c.secondary_number INTO v_anumber, v_primaryAnumber, v_secondaryAnumber
FROM person p
LEFT JOIN consolidated_numbers c ON p.id = c.person_id WHERE p.id = v_person_id;
Thank you!

PLS-00341: declaration of cursor 'cur2' is incomplete or malformed || PL/SQL: ORA-00918: column ambiguously defined

I wrote a procedure where i am trying to insert value from source to destination table, i used bulk collect in order to execute large volume of data.
While executing the below procedure, its showing cursor cus2 declaration is incomplete and its showing some column ambiguously defined in the cursor.
create or replace PROCEDURE TEST2 (
p_array_size IN NUMBER
) IS
CURSOR cur1 IS SELECT DISTINCT
*
FROM
test
CURSOR cur3 IS SELECT * FROM test;
CURSOR cur2(BND_TYPE cr_loan_prima_rate_orig.bndng_typ%TYPE, BND_VAL cr_loan_prima_rate_orig.bndng_val%TYPE, FINANCIAL_INST_ID cr_loan_prima_rate_orig.financial_institution_id%TYPE,
PRDCT_ID cr_loan_prima_rate_orig.prdct_id%TYPE,PRDCT_SUB_ID cr_loan_prima_rate_orig.prdct_sub_id%TYPE, INSTRUMENT_ID cr_loan_prima_rate_orig.instrmnt_id%TYPE) IS SELECT
d.*
FROM
test1 d,
(
SELECT
b.prdct_id,
FROM
test2 a,
test1 b
WHERE
a.ir_id = b.ir_id
AND a.price_component_id = b.price_component_id
AND a.financial_institution_id = b.financial_institution_id
GROUP BY
b.prdct_id,
) e
WHERE
d.prdct_id = e.prdct_id
AND d.bndng_typ = BND_TYPE
AND d.bndng_val = BND_VAL
AND d.financial_institution_id = FINANCIAL_INST_ID
AND d.prdct_id = PRDCT_ID
AND d.prdct_sub_id = PRDCT_SUB_ID
AND d.instrmnt_id = INSTRUMENT_ID ;
TYPE loan_data_tbl IS TABLE OF cur1%rowtype INDEX BY PLS_INTEGER;
loan_data loan_data_tbl;
TYPE loanrate_tbl IS TABLE OF cur2%rowtype INDEX BY BINARY_INTEGER;
loan_rate loanrate_tbl;
BEGIN
DECLARE
v_noofDays NUMBER:=0;
currentDt DATE;
BEGIN
SELECT * INTO currentDt FROM dt;
BEGIN
IF cur1%Isopen Then
Close cur1;
End IF;
IF cur2%Isopen Then
Close cur2;
End IF;
OPEN cur1;
LOOP
FETCH cur1 BULK COLLECT INTO loan_data LIMIT p_array_size;
EXIT WHEN loan_data.COUNT = 0;
FOR i IN 1..loan_data.COUNT
LOOP
OPEN cur3;
OPEN cur2(loan_data(i).bndng_typ, loan_data(i).bndng_val,loan_data(i).financial_institution_id,
loan_data(i).prdct_id, loan_data(i).prdct_sub_id, loan_data(i).instrmnt_id);
loop
FETCH cur2 BULK COLLECT INTO loan_rate LIMIT p_array_size;
EXIT WHEN loan_rate.COUNT = 0;
FOR j IN 1..loan_rate.COUNT
LOOP
IF(cur3.POS_NUM = loan_data(i).POS_NUM AND cur3.POS_TYPE = loan_data(i).POS_TYPE
AND cur3.PRICE_COMPONENT_ID = loan_rate(j).PRICE_COMPONENT_ID
AND cur3.RPRTD_TILL_DT = loan_data(i).RPRTD_TILL_DT) THEN
update test SET SEQ_NUM=1,
WHERE SEQ_NUM=2;
ELSE
INSERT INTO test VALUES (
....
....
);
END IF;
COMMIT;
END LOOP;
END LOOP;
CLOSE cur2;
CLOSE cur1;
END LOOP;
END LOOP;
CLOSE cur1;
END;
END;
End ;
/
For me everything looks good, not able to find the exact mistake.can anyone help me out with this.

Converting Merge clause with Bulk collect/FORALL in pl/sql

I wrote a procedure where the data gets updated/inserted simultaneously to the destination table from source table. The procedure is working fine for less no of records, but when i try to execute more records its taking more time to perform the operation.
Can we convert merge clause with bulk collect where the logic remains same ? i dint find any useful resources.
I have attached my merge procedure .
create or replace PROCEDURE TEST1 (
p_array_size IN NUMBER
) IS
CURSOR dtls IS SELECT DISTINCT
account_num
FROM
table1
WHERE
rprtd_till_dt = (
SELECT
dt - 1
FROM
dates
WHERE
id = 'odc'
);
TYPE data_tbl IS TABLE OF dtls%rowtype;
data data_tbl;
BEGIN
DECLARE
v_noofDays NUMBER:=0;
currentDt DATE;
BEGIN
SELECT dt INTO currentDt FROM dates WHERE id = 'odc';
BEGIN
OPEN dtls;
LOOP
FETCH dtls BULK COLLECT INTO data LIMIT p_array_size;
EXIT WHEN data.COUNT = 0;
FOR i IN 1..data.COUNT
LOOP
IF(TRUNC(data(i).creation_dt,'MM') = TRUNC(currentDt,'MM')) THEN
v_noofDays := currentDt - 1 - data(i).creation_dt;
ELSE
v_noofDays := currentDt - TRUNC(currentDt,'MM');
END IF;
MERGE INTO table1 updtbl USING ( SELECT
d.*
FROM
table2 d,
(
SELECT
b.prdct_id,
FROM
table3 a,
table2 b
WHERE
a.ir_id = b.ir_id
AND a.price_component_id = b.price_component_id
AND a.financial_institution_id = b.financial_institution_id
GROUP BY
b.prdct_id,
) e
WHERE
d.prdct_id = e.prdct_id
AND d.bndng_typ = data(i).bndng_typ
AND d.bndng_val = data(i).bndng_val
AND d.financial_institution_id = data(i).financial_institution_id
AND d.prdct_id = data(i).prdct_id
AND d.prdct_sub_id = data(i).prdct_sub_id
AND d.instrmnt_id = data(i).instrmnt_id
)
inp ON (
updtbl.POS_NUM = data(i).POS_NUM
AND updtbl.POS_TYPE = data(i).POS_TYPE
AND updtbl.PRICE_COMPONENT_ID = inp.PRICE_COMPONENT_ID
AND updtbl.RPRTD_TILL_DT = data(i).RPRTD_TILL_DT
)
WHEN NOT MATCHED THEN
INSERT VALUES (
data(i).loan_account_num,
inp.ir_id,
inp.price_component_id,
)
WHEN MATCHED THEN
update SET SEQ_NUM=1,
NET_INTRST_AMT=round(data(i).curr_loan_bal*inp.price_component_value*v_noofDays/36000,2),
DM_BTID=200
WHERE SEQ_NUM=2;
COMMIT;
END LOOP;
END LOOP;
CLOSE dtls;
END;
END;
END TEST1;
/
If anyone can help me to guide the syntax on how to achieve the above procedure using bulk collect will be helpful.
I know its a bit late, but use the following for future if you haven't solved it yet
drop table projects;
create table projects (
proj_id integer not null primary key,
proj_title varchar2(20)
);
insert into projects (proj_id, proj_title) values (1, 'Project One');
insert into projects (proj_id, proj_title) values (2, 'Project Two');
commit;
select *
from projects;
declare
type varray_t is varray(2) of projects%rowtype;
arr varray_t;
begin
with test_data as (select 2 as proj_id, 'New Project Two' as proj_title from dual
union all select 3 as proj_id, 'New Project Three' as proj_title from dual)
select proj_id, proj_title
bulk collect into arr
from test_data;
forall i in arr.first .. arr.last
merge into projects
using (select arr(i).proj_id as proj_id,
arr(i).proj_title as proj_title
from dual) mrg
on (projects.proj_id = mrg.proj_id)
when matched then update set projects.proj_title = mrg.proj_title
when not matched then insert (proj_id, proj_title) values (mrg.proj_id, mrg.proj_title);
dbms_output.put_line(sql%rowcount || ' rows merged');
commit;
end;
I hope this will give you kind of idea. Avoid the copy and paste and check the syntax.
create or replace PROCEDURE TEST1 (
p_array_size IN NUMBER
) IS
CURSOR dtls IS SELECT DISTINCT
account_num
FROM
table1
WHERE
rprtd_till_dt = (
SELECT
dt - 1
FROM
dates
WHERE
id = 'odc'
);
TYPE data_tbl IS TABLE OF dtls%rowtype;
data data_tbl;
BEGIN
DECLARE
v_noofDays NUMBER:=0;
currentDt DATE;
BEGIN
SELECT dt INTO currentDt FROM dates WHERE id = 'odc';
BEGIN
OPEN dtls;
LOOP
FETCH dtls BULK COLLECT INTO data LIMIT p_array_size;
EXIT WHEN data.COUNT = 0;
FORALL rec in data.first .. data.last
MERGE INTO table1 updtbl USING (
SELECT
d.* FROM
table2 d,(
SELECT
b.prdct_id
FROM
table3 a,
table2 b
WHERE
a.ir_id = b.ir_id
AND a.price_component_id = b.price_component_id
AND a.financial_institution_id = b.financial_institution_id
GROUP BY
b.prdct_id
) e
WHERE
d.prdct_id = e.prdct_id
AND d.bndng_typ = data(rec).bndng_typ
AND d.bndng_val = data(rec).bndng_val
AND d.financial_institution_id = data(rec).financial_institution_id
AND d.prdct_id = data(rec).prdct_id
AND d.prdct_sub_id = data(rec).prdct_sub_id
AND d.instrmnt_id = data(rec).instrmnt_id
)
inp ON (
updtbl.POS_NUM = data(rec).POS_NUM
AND updtbl.POS_TYPE = data(rec).POS_TYPE
AND updtbl.PRICE_COMPONENT_ID = data(rec).PRICE_COMPONENT_ID
AND updtbl.RPRTD_TILL_DT = data(rec).RPRTD_TILL_DT
)
WHEN NOT MATCHED THEN
INSERT VALUES (
data(rec)
)
WHEN MATCHED THEN
update SET SEQ_NUM=1,
NET_INTRST_AMT=round(data(rec).curr_loan_bal*inp.price_component_value*v_noofDays/36000,2),
DM_BTID=200
WHERE SEQ_NUM=2;
END LOOP;
CLOSE dtls;
END;
END;
END TEST1;
Merge is always better than forall for atomic updates.
A simplistic use case is
https://ograycoding.wordpress.com/2012/10/13/oracle-merge-v-bulk-collect-and-forall/

Logic of my Stored Procedure, Loop cursors

Let's see if i can make this clear. Basically what i want to do and i don't know how is this: inside my loop how can i iterate those 2 cursors? After fetching those rows i want to insert in those 2 tables as you can see in the snippet :
CREATE OR REPLACE PROCEDURE add_docs
IS
dom_doc DOM_DOCUMENT.DOMAIN_DOC%TYPE;
type_doc_pk TYPE_DOCS.TYPE_DOC_PK%TYPE;
type_doc TYPE_DOCS.TYPE_DOCUMENT%TYPE;
user_code TYPE_DOCS.USERCODE%TYPE;
result_code ECM_TIPO_DOCS.CODIGO_RESULTADO%TYPE;
LS_LOCAL INTEGER;
l_id INTEGER;
cursor get_local
is
SELECT ls_local_pk FROM rt_local_ls
rc_loc c_loc%ROWTYPE;
cursor get_docs
is
SELECT DOM_DOCUMENT.DOMAIN_DOC INTO dom_doc,
TYPE_DOCS.TYPE_DOC_PK INTO type_doc_pk,
TYPE_DOCS.TYPE_DOCUMENT INTO type_doc,
TYPE_DOCS.USERCODE INTO user_code,
TYPE_DOCS.CODE_RESULT INTO result_code
FROM TYPE_DOCS
JOIN DOM_TDOC_SIS
ON TYPE_DOCS.TYPE_DOC_PK = DOM_TDOC_SIS.TYPE_DOC_PK
JOIN DOM_DOCUMENT
ON DOM_TDOC_SIS.DOMAIN_DOC_PK = DOM_DOCUMENT.DOMAIN_DOC_PK
WHERE DOM_DOCUMENT.DOMAIN_DOC_PK IN (2, 10)
AND NOT EXISTS
(
SELECT 1
FROM TP_DOC_MAP
WHERE TP_DOC_MAP.LS_LOCAL_PK = LS_LOCAL ----this is the variable that i have to iterate it's what i am getting from the other cursor
AND TP_DOC_MAP.LS_SYSTEM_PK = 3
AND TP_DOC_MAP.ACTIVE = 1
AND TP_DOC_MAP.CODE = TYPE_DOCS.TYPE_DOC_PK
);
BEGIN
OPEN get_local;
FETCH get_local INTO rc_loc
IF get_local%FOUND
THEN
for md_local in get_local
LOOP
OPEN get_docs;
FETCH get_docs INTO....
---now this is where i don't know how to do inside this loop i want to repeat the cursor get_docs for each row in the cursor get_local
--and then insert with the values fetched for each iteration
INSERT INTO TP_DOC VALUES (
type_doc_pk,
type_doc,
1,
SYSDATE,
NULL)
RETURNING id INTO l_id;
INSERT INTO TP_DOC_MAP VALUES (
l_id,
LS_LOCAL,
3,
type_doc_pk,
1,
sysdate,
NULL
);
END LOOP
END IF;
END add_docs;
how can i do this? for each LS_LOCAL that exists it will have to run the sele
for each LS_LOCAL that exists, it will have to run the select in the cursor get_docs with the LS_LOCAL variable.
Embedded cursor FOR loops are one option. Here's how (I removed irrelevant parts of code to make it as simple as possible):
begin
for cur_l in (select ls_local_pk from rt_local_ls)
loop
for cur_d in (select domain_doc,
type_doc_pk, ...
from type_docs join dom_tdoc_sis ...
)
loop
insert into tp_doc ...
insert into tp_doc_map ...
end loop;
end loop;
end;

Getting an error in sql, when executing code below.How to declare a table type in plsql. Am a beginner . Please suggest

create or replace procedure BAS_NUM_UPD is
cursor cur is
select distinct o.oi_b,mpr.pa_ke_i,ltrim(substr(convert_171_to_711(cp.p_t_num),1,7),'0') bs_nbr
from t_obj o, mat_pa_rel mp, cor_pa cp
where o.ob_t = 'something'
and o.oi_b = mp.oi_b
and mp.pa_ke_i = cp.pa_ke_i;
l_ba_num_at_i number(10) := get_attribute_id('Ba timber');
flag1 VARCHAR2(10);
type t1 is table of varchar2(10);
par_k t1;
BEGIN
for x in cur loop
BEGIN
select pa_ke_i into par_k from mat_pa_rel where oi_b=x.oi_b ;
if par_k.count=null then
insert into cs_val (oi_b, at_i, value, flag, ) values (x.oi_b, l_ba_num_at_i, null, 1);
end if;
select flag into flag1 from cs_val where at_i = l_ba_num_at_i and oi_b = x.oi_b
and value = x.bs_nbr;
EXCEPTION
when NO_DATA_FOUND THEN
insert into cs_val (oi_b, at_i, value, flag, )
values (x.oi_b, l_ba_num_at_i, x.bs_nbr, 1);
flag1 :='Nothing';
when OTHERS
then
raise_application_error(-20011,'Unknown Exception in PROCEDURE');
END;
end loop;
end BAS_NUM_UPD;
error:
PLS-00642: local collection types not allowed in SQL statements
You should get it running if you do a bulk collect
select pa_ke_i bulk collect into par_k from mat_pa_rel where oi_b=x.oi_b ;
Then I think the if is not right. I think you need to do
if par_k.count = 0 then
But to be honest you might just make a count
select count(*) into l_cnt from mat_pa_rel where oi_b=x.oi_b;
If l_cnt = 0 then ...
Of course l_cnt has to be defined.
You should create type t1 in the schema and not in the pl/sql block.