i have a stored procedure that will copy data from table A to table B and return id that is generated from table B to update table a record . this is sample data table A is :
id----Name---refId---value----KPI
1 ahmed 550 50 30
2 ali 30
3 soo 561 40 30
Table B is :
Id ---- Name ---- Value
550 ahmed 50
561 soo 30
i’ve tried the following i’ve defined a rec type
VAR_RECORD_A mySchema.A%rowtype;
refffId Number ;
BEGIN
select
*
into
VAR_RECORD_A
from mySchema.A
where (value passed to function)= var_kpi_element_req.BPM_KPI_ID ;
end ;
begin
insert into mySchema.B
(name , value)
Values
(VAR_RECORD_A.name , VAR_RECORD_A.value)
RETURNING Id into refffId ;
end;
begin
update A
set refId = refffId
where kpi =(value passed to function)
end;
my problem is the select into will return many records , i believe my code will work if only return 1 record
Advertisement
Answer
The simplest solution is to use a Cursor loop:
-- don't declare VAR_RECORD_A as rowtype ...
refffId Number ;
BEGIN
for VAR_RECORD_A in ( -- instead make it a cursor ref
select *
from mySchema.A
where (value passed to function)= var_kpi_element_req.BPM_KPI_ID
)
loop
insert into mySchema.B
(name , value)
Values
(VAR_RECORD_A.name , VAR_RECORD_A.value)
RETURNING Id into refffId ;
update A
set refId = refffId
where kpi =(value passed to function)
and a.PK = VAR_RECORD_A.pk -- identify current row of A for update
end loop;
Note: I have removed the unnecessary BEGIN … END notations. Only declare nested blocks when there’s real value in doing so.
In real life I would want to make this bulk operation more efficient by using collections and forall statements for a set-based approach.
Also I would consider whether I needed to lock the selected rows from A
FOR UPDATE OF KPI, in case my whole transaction failed due to another session having a lock on one row. Doing this would allow you to use the WHERE CURRENT OF syntax when updating A
.