Skip to Main Content

SQL & PL/SQL

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Interested in getting your voice heard by members of the Developer Marketing team at Oracle? Check out this post for AppDev or this post for AI focus group information.

Deleting from collections

DevguyDec 29 2024

Hi community,

I am trying to delete data from two collections simultaneously, the results are inconsistent sometimes when I am trying to access the elements after deletion.

Oracle DB Version: 19.0

Attached table creation & sample data script

Here's the anonymous block

 DECLARE
CURSOR c_tmp
IS
select *
from xxc_temp;

CURSOR c_tmp_qty(p_order_no  IN VARCHAR2
                ,p_call_off_id IN NUMBER)
IS
SELECT SUM(qty_to_deliver)total_order_qty FROM  xxc_tmp_qty
WHERE order_number = p_order_no
 AND  call_off_id = p_call_off_id;
 TYPE po_rec_type IS RECORD
   (   cust_num                      VARCHAR2(30)
   ,   ship_to                       VARCHAR2(50)
   ,   po_num                        VARCHAR2(20)
   ,   mark_for                      VARCHAR2(30)
   ,   call_off_id                   NUMBER
   ,   balance_qty                   NUMBER
   ,   cumulative_qty_ordered        NUMBER
   ,   cumulative_qty_received       NUMBER
   );
TYPE po_Tbl_Type IS TABLE OF po_rec_type
   INDEX BY BINARY_INTEGER;
l_po_tbl      po_Tbl_Type;
TYPE quantity_rec_type IS RECORD
( po_num                        VARCHAR2(20)
, balance_qty                   NUMBER
, cumulative_qty_ordered        NUMBER
, cumulative_qty_received       NUMBER
);
TYPE quantity_tbl_type IS TABLE OF quantity_rec_type
   INDEX BY VARCHAR2(250);
l_qty_tbl      quantity_tbl_type; 
l_del_po   VARCHAR2(20);
i          PLS_INTEGER := 0;
BEGIN
   FOR rec IN c_tmp
   LOOP
       i := i + 1;
           l_po_tbl(i).cust_num                    := rec.cust_num;
           l_po_tbl(i).ship_to                     := rec.ship_to;
           l_po_tbl(i).po_num                      := rec.order_number;
           l_po_tbl(i).cumulative_qty_ordered      := rec.cumulative_qty_ordered;
           l_po_tbl(i).cumulative_qty_received     := rec.cumulative_qty_received;
           l_po_tbl(i).balance_qty                 := rec.balance_qty;
           l_po_tbl(i).call_off_id                 := rec.call_off_id;
           l_qty_tbl(rec.order_number).po_num                   := rec.order_number;
           l_qty_tbl(rec.order_number).balance_qty              := rec.balance_qty;
           l_qty_tbl(rec.order_number).cumulative_qty_ordered   := rec.cumulative_qty_ordered;
           l_qty_tbl(rec.order_number).cumulative_qty_received  := rec.cumulative_qty_received;
   END LOOP;
   
   dbms_output.put_line('l_po_tbl.COUNT at start: '|| l_po_tbl.COUNT);
       dbms_output.put_line('l_qty_tbl.COUNT at start: '|| l_qty_tbl.COUNT);
   
   IF l_po_tbl.count > 0
   THEN
       FOR j IN  l_po_tbl.FIRST..l_po_tbl.LAST
       LOOP
           FOR qty IN c_tmp_qty(l_po_tbl(j).po_num,l_po_tbl(j).call_off_id)
           LOOP
               dbms_output.put_line('PO: '|| l_po_tbl(j).po_num );
               IF l_po_tbl(j).cumulative_qty_ordered != l_po_tbl(j).cumulative_qty_received + l_po_tbl(j).balance_qty + qty.total_order_qty
               THEN
                       dbms_output.put_line('Quantity for PO: '|| l_po_tbl(j).po_num ||' doesn''t match');
                       
                       l_del_po := l_po_tbl(j).po_num;
                         
                         dbms_output.put_line('Deleting PO: '|| l_po_tbl(j).po_num);
                         dbms_output.put_line('Index: '|| j);
                         l_po_tbl.delete(j);
                         
                         
                         IF l_qty_tbl.EXISTS(l_del_po)
                         THEN
                               dbms_output.put_line('Deleting from qty table type PO: '|| l_qty_tbl(l_del_po).po_num);
                               l_qty_tbl.delete(l_del_po);
                         END IF;    
               END IF;
               
               
           END LOOP;
       END LOOP;
   END IF;
   
   dbms_output.put_line('l_po_tbl.COUNT at end: '|| l_po_tbl.COUNT);
         dbms_output.put_line('l_qty_tbl.COUNT at end: '|| l_qty_tbl.COUNT);
         
           FOR idx IN 1 .. l_po_tbl.COUNT LOOP
               -- Check if index exists before accessing it
               IF l_po_tbl.EXISTS(idx) THEN
                   l_del_po := l_po_tbl(idx).po_num;
                   
                   dbms_output.put_line('l_po_tbl(po_num): ' || l_del_po);
                   dbms_output.put_line('Index in 2nd loop: ' || idx);
                   
                   -- Check if the corresponding record exists in g_qty_tbl
                   IF l_qty_tbl.EXISTS(l_del_po) THEN
                       dbms_output.put_line('l_qty_tbl(po_num): ' || l_qty_tbl(l_del_po).po_num);
                   ELSE
                       dbms_output.put_line('No matching record in l_qty_tbl for PO: ' || l_del_po);
                   END IF;
               END IF;
           END LOOP;
END;

Is there anything wrong with how I am deleting the data from collections? I am getting inconsistent results. Any suggestions are appreciated.

Table_Script.sql

This post has been answered by Paulzip on Dec 29 2024
Jump to Answer
Comments
Post Details
Added on Dec 29 2024
6 comments
144 views