Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

INSERT e UPDATE um registro usando cursores no oracle


Esta é uma maneira altamente ineficiente de fazê-lo. Você pode usar o merge instrução e então não há necessidade de cursores, looping ou (se você puder fazer sem) PL/SQL.
MERGE INTO studLoad l
USING ( SELECT studId, studName FROM student ) s
ON (l.studId = s.studId)
WHEN MATCHED THEN
  UPDATE SET l.studName = s.studName
   WHERE l.studName != s.studName
WHEN NOT MATCHED THEN 
INSERT (l.studID, l.studName)
VALUES (s.studId, s.studName)

Certifique-se de commit , uma vez concluído, para poder ver isso no banco de dados.

Para realmente responder à sua pergunta, eu faria algo como o seguinte. Isso tem a vantagem de fazer a maior parte do trabalho em SQL e atualizar apenas com base no rowid, um endereço exclusivo na tabela.

Ele declara um tipo, no qual você coloca os dados em massa, 10.000 linhas por vez. Em seguida, processa essas linhas individualmente.

No entanto, como eu disse, isso não será tão eficiente quanto merge .
declare

   cursor c_data is
    select b.rowid as rid, a.studId, a.studName
      from student a
      left outer join studLoad b
        on a.studId = b.studId
       and a.studName <> b.studName
           ;

   type t__data is table of c_data%rowtype index by binary_integer;
   t_data t__data;

begin

   open c_data;
   loop
      fetch c_data bulk collect into t_data limit 10000;

      exit when t_data.count = 0;

      for idx in t_data.first .. t_data.last loop
         if t_data(idx).rid is null then
            insert into studLoad (studId, studName)
            values (t_data(idx).studId, t_data(idx).studName);
         else
            update studLoad
               set studName = t_data(idx).studName
             where rowid = t_data(idx).rid
                   ;
         end if;
      end loop;

   end loop;
   close c_data;

end;
/