Oracle
 sql >> Datenbank >  >> RDS >> Oracle

INSERT und UPDATE einen Datensatz mit Cursors in Oracle

Dies ist eine höchst ineffiziente Vorgehensweise. Sie können die merge verwenden -Anweisung und dann sind keine Cursor, Schleifen oder (wenn Sie darauf verzichten können) PL/SQL überflüssig.

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)

Stellen Sie sicher, dass Sie commit , um diese in der Datenbank einsehen zu können.

Um Ihre Frage tatsächlich zu beantworten, würde ich es ungefähr wie folgt machen. Dies hat den Vorteil, dass die meiste Arbeit in SQL erledigt wird und nur basierend auf der Rowid aktualisiert wird, einer eindeutigen Adresse in der Tabelle.

Es deklariert einen Typ, in dem Sie die Daten in großen Mengen mit jeweils 10.000 Zeilen platzieren. Verarbeitet diese Zeilen dann einzeln.

Wie ich bereits sagte, ist dies jedoch nicht so effizient wie 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;
/