sql >> Database >  >> RDS >> Oracle

Een associatieve array in een geneste tabel vullen

In het antwoord op uw vorige vraag zei ik dat het vullen van de verzameling moeilijker zou zijn met de %rowtype veld. Voor zover ik weet, kunt u, tenzij u een objecttype op SQL-niveau declareert in plaats van een recordtype, geen gebruik maken van bulk collect hiervoor (hoewel het de moeite waard is om te controleren of dat misschien in 12c is veranderd).

Ik geloof dat je vastzit aan het gebruik van een eenvoudigere cursorlus die de twee velden in je type bouwt (d.w.z. de %rowtype subveld en de rowid veld) afzonderlijk, en bouwt dan de verzameling regel voor regel op:

create or replace package body dat_pkg is

    procedure transform_dat (p_batch_name data_test.batch_name%type)
    is

        cursor cur_dat is
        select rowid, a.*
        from   data_test a
        where  batch_name = p_batch_name;

        l_dat_tst typ_dat_tst;
        l_rec data_test%rowtype;

    begin

        for rec_dat in cur_dat loop
            l_rec.data_id := rec_dat.data_id;
            l_rec.data_value := rec_dat.data_value;
            l_rec.batch_name := rec_dat.batch_name;
            -- or use a counter you increment for this...
            l_dat_tst(l_dat_tst.count + 1).data_rec := l_rec;
            l_dat_tst(l_dat_tst.count).data_rowid := rec_dat.rowid;
        end loop;

        -- Do the Transformation here. Example --            

        for i in 1..l_dat_tst.count loop
            if l_dat_tst(i).data_rec.data_value = 'hello' then
                l_dat_tst(i).data_rec.data_value := 'was hello';
            else            
                l_dat_tst(i).data_rec.data_value := 'was not hello';
            end if;
        end loop;

        -- update the table            
        proc_test (p_dat => l_dat_tst);

    end transform_dat;

    procedure proc_test (p_dat  typ_dat_tst)
    is
    begin

        for i in 1..p_dat.count loop

            update  data_test        
            set     data_value  = p_dat(i).data_rec.data_value  
            where   data_id     = p_dat(i).data_rec.data_id
            and     rowid       = p_dat(i).data_rowid;

        end loop;

    end proc_test;

end dat_pkg;
/    

Zoals ook eerder besproken, moeten de verwijzingen naar de velden van het subveld-record correct worden gekwalificeerd, dus heb ik .data_rec ingevoegd in de verwijzingen in beide procedures. Ik heb de dummy-transformatie gewijzigd om de waarde te wijzigen in plaats van de ID, omdat dat betekent dat er nooit updates zullen plaatsvinden.

Demo met enkele dummy-gegevens:

insert into data_test values (1, 'hello', 'test');
insert into data_test values (2, 'hello', 'test');
insert into data_test values (3, 'hello', 'exclude');
insert into data_test values (4, 'goodbye', 'test');


exec dat_pkg.transform_dat('test');

select * from data_test;

   DATA_ID DATA_VALUE           BATCH_NAME          
---------- -------------------- --------------------
         1 was hello            test                
         2 was hello            test                
         3 hello                exclude             
         4 was not hello        test                



  1. Kolom mag niet null zijn Mysql

  2. 4 manieren om dubbele rijen te selecteren in MariaDB

  3. Leer 2 met meerdere indexen

  4. Alleen tijd bijwerken in een mysql DateTime-veld