INSERT和UPDATE使用的是Oracle游标记录(INSERT and UPDATE a re

2019-06-27 00:23发布

我有2表- studentstudLoad均具有2场studIDstudName 。 我想从数据加载student表到stuLoad表。 如果数据中已经存在studLoad表,那么它应该被其他人更新应该插入。 下面是我的代码可以这样做:

    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..)以检查是否在表中存在的记录,有没有办法做同样的甲骨文? 如果是,那么请让我知道一样。

Answer 1:

这是做的非常低效的方式。 您可以使用merge声明,那么就没有必要光标,循环或者(如果你也离不开谁)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)

确保你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;
/


文章来源: INSERT and UPDATE a record using cursors in oracle