Oracle
 sql >> база данни >  >> RDS >> Oracle

Попълване на асоциативен масив във вложена таблица

В отговора на предишния ви въпрос споменах, че попълването на колекцията би било по-трудно с %rowtype поле. Доколкото ми е известно, освен ако не декларирате тип обект на SQL ниво вместо тип запис, не можете да използвате bulk collect за това (въпреки че си струва да проверите дали това се е променило в 12c може би).

Вярвам, че сте останали с използването на по-прост цикъл на курсора, който изгражда двете полета във вашия тип (т.е. %rowtype подполе и rowid поле) отделно и след това изгражда колекцията ред по ред:

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

Както също беше обсъдено по-рано, препратките към полетата на записа на подполе трябва да бъдат квалифицирани правилно, така че вмъкнах .data_rec в справките и в двете процедури. Промених фиктивната трансформация, за да модифицирам стойността вместо идентификатора, тъй като това означава, че няма да има актуализации.

Демо с някои фиктивни данни:

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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Разбор на tnsnames.ora с помощта на регулярен израз

  2. Предаване на масив от .Net приложение към съхранена процедура на Oracle

  3. Преобразуване на числа в думи в MYSQL резултат! Използване на заявка

  4. Актуализирайте колоната на набора от таблици, равна на това да изберете къде ID съвпада извън заявката в Oracle

  5. Oracle – Материализиран изглед все още е достъпен по време на пълно опресняване. Как работи това?