我有2个表格student-studLoad都具有2个字段studID和studName。我想将数据从student表加载到stuLoad表中。如果studLoad表中已经存在数据,则应对其进行更新,否则应将其插入。以下是我这样做的代码:
student
studLoad
studID
studName
stuLoad
create or replace procedure studentLoad is v_id student.studID%type; v_name student.studName%type; v_sn studLoad.studName%type; cursor cur_load is select * from student; begin open cur_load; loop fetch cur_load into v_id,v_name; exit when cur_load%notfound; select studName into v_sn from studLoad where studID = v_id; if(v_sn!= v_name) then update studLoad set studName= v_name where studID= v_id; else insert into studLoad values(v_id,v_name); dbms_output.put_line(v_id || ' ' || v_name); end if; end loop; close cur_load; end;
没用 studLoad表中的行不会更新。我该如何解决?在SQL Server中,我们用于IF EXISTS(select...from stuLoad..)检查表中是否存在记录,是否可以在Oracle中执行相同的操作?如果是的话,请让我知道。
IF EXISTS(select...from stuLoad..)
这是一种非常低效的方式。您可以使用该merge语句,然后就不需要游标,循环或(如果可以的话)PL / SQL。
merge
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)
commit完成后,请确保您能够在数据库中看到此信息。
commit
为了真正回答您的问题,我将按照以下方式进行操作。这样的好处是可以完成大部分SQL工作,并且仅基于rowid(表中的唯一地址)进行更新。
它声明了一个类型,您可以一次将数据批量放入10,000行中。然后分别处理这些行。
但是,正如我所说的那样,它的效率不如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; /