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!

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
262 views