Oracle
 sql >> Database >  >> RDS >> Oracle

INSERT e UPDATE un record usando i cursori in Oracle

Questo è un modo altamente inefficiente di farlo. Puoi usare il merge istruzione e quindi non c'è bisogno di cursori, loop o (se puoi farne a meno) 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)

Assicurati di commit , una volta completato, per poterlo vedere nel database.

Per rispondere effettivamente alla tua domanda, lo farei come segue. Questo ha il vantaggio di svolgere la maggior parte del lavoro in SQL e di aggiornare solo in base al rowid, un indirizzo univoco nella tabella.

Dichiara un tipo in cui inserisci i dati in blocco, 10.000 righe alla volta. Quindi elabora queste righe singolarmente.

Tuttavia, come ho detto, questo non sarà efficiente come 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;
/