sql >> Databasteknik >  >> RDS >> Oracle

Fyll i en associativ array i en kapslad tabell

I svaret på din tidigare fråga nämnde jag att det skulle vara svårare att fylla i samlingen med %rowtype fält. Såvitt jag vet kan du inte använda bulk collect om du inte deklarerar en objekttyp på SQL-nivå istället för en posttyp. för detta (även om det är värt att kontrollera om det har ändrats i 12c kanske).

Jag tror att du har fastnat för att använda en enklare markörslinga som bygger de två fälten i din typ (d.v.s. %rowtype underfältet och rowid fält) separat och bygger sedan upp samlingen en rad i taget:

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;
/    

Som också diskuterats tidigare måste referenserna till underfältspostens fält vara korrekt kvalificerade, så jag har infogat .data_rec i referenserna i båda förfarandena. Jag har ändrat dummy-transformationen för att ändra värdet istället för ID, eftersom det betyder att inga uppdateringar någonsin kommer att ske.

Demo med lite dummydata:

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. 'en-till-många' relationsintegritetsfråga för tidsintervall

  2. Att använda IS NULL eller IS NOT NULL på anslutningsvillkor - Teorifråga

  3. SQL SELECT ORDER BY flera kolumner beroende på värdet för den andra kolumnen

  4. Distribuera Django-applikationen utan tjänstavbrott / ingen driftstopp