批量游标常用套路

  
  
  1. declare
  2.  cursor cur_login is
  3.    select user_id, login, login_time from user_login;
  4.  type user_id_type is table of user_login.user_id%type;
  5.  type login_type is table of user_login.login%type;
  6.  type login_time_type is table of user_login.login_time%type;
  7.  id_tab         user_id_type;
  8.  login_tab      login_type;
  9.  login_time_tab login_time_type;
  10.  v_limit        pls_integer := 5000;
  11. begin
  12.  open cur_login;
  13.  loop
  14.    fetch cur_login bulk collect
  15.      into id_tab, login_tab, login_time_tab limit v_limit;
  16.    exit when id_tab.count = 0;
  17.    forall i in id_tab.first .. id_tab.last
  18.      insert into user_login_bak
  19.      values
  20.        (id_tab(i), login_tab(i), login_time_tab(i));
  21.    commit;
  22.  end loop;
  23.  close cur_login;
  24. end;
  25. /
  26. declare
  27.  cursor cur is
  28.    select USER_ID, LOGIN, LOGIN_TIME from USER_LOGIN;
  29.  v_user_id    dbms_sql.Number_Table; ---不是记录了,是集合
  30.  v_login      dbms_sql.Number_Table; ---不是记录了,是集合
  31.  v_login_time dbms_sql.date_Table; ------不是记录了,是集合
  32. begin
  33.  open cur;
  34.  loop
  35.    fetch cur bulk collect
  36.      into v_user_id, v_login, v_login_time limit 5000; ----一次批量获取5000行;
  37.    forall i in 1 .. v_user_id.count
  38.      insert into USER_LOGIN_bak
  39.      values
  40.        (v_user_id(i), v_login(i), v_login_time(i)); ----这里的 i 就是指 1..5000
  41.    commit;
  42.    exit when cur%notfound or cur%notfound is null;
  43.  end loop;
  44.  close cur;
  45.  commit;
  46. end;
  47. declare
  48.  cursor cur_user_login is
  49. select USER_ID, LOGIN, LOGIN_TIME from USER_LOGIN;
  50.  type cur_type is table of cur_user_login%rowtype index by pls_integer; ---  index by binary_integer 是数组的固定语法
  51.  cur_tab cur_type;
  52. begin
  53.  open cur_user_login;
  54.  loop
  55.    fetch cur_user_login bulk collect
  56. into cur_tab limit 5000; ----一次批量获取5000行;
  57.    forall i in 1 .. cur_tab.count
  58.      insert into USER_LOGIN_BAK
  59. (USER_ID, LOGIN, LOGIN_TIME)
  60.      values
  61. (cur_tab(i).USER_ID, cur_tab(i).LOGIN, cur_tab(i).LOGIN_TIME);
  62.    commit;
  63. exit when cur_user_login%notfound or cur_user_login%notfound is null;
  64. end loop;
  65.  close cur_user_login;
  66.  commit;
  67. end;
   
   
  1. 除了批量游标,还有是动态游标:
  2. 什么是动态游标呢?
  3. 在执行的时候才知道什么sql 语句,而不是一开始就知道:
  4. Ref cursor属于动态cursor(直到运行时才知道这条查询)。
  5. 我们来看一个例子:
  6. --- 这个是批量删除数据
  7. create or replace procedure delBigTab(p_TableName in varchar2,
  8.                                      p_Condition in VARCHAR2) AS
  9.  type mycur is ref cursor;
  10.  v_cur     mycur;
  11.  v_cur_sql VARCHAR2(3000);
  12.  Type v_rowid is table of varchar2(100) index by binary_integer; ---集合类型
  13.  var_rowid v_rowid;
  14.  v_count number :=0;
  15. BEGIN
  16.  v_cur_sql := 'select rowid from ' || p_TableName || ' where ' ||
  17.               p_Condition || ' order by rowid';
  18.  OPEN v_cur FOR v_cur_sql;
  19.  LOOP
  20.    FETCH v_cur BULK COLLECT
  21.      INTO var_rowid LIMIT 20000;
  22.    FORALL i IN 1 .. var_rowid.count EXECUTE IMMEDIATE
  23.                     'delete from ' || p_TableName || ' where  rowid=:1'
  24.                     USING var_rowid(i)
  25.      ;
  26.    COMMIT;
  27.    EXIT WHEN v_cur%NOTFOUND OR v_cur%NOTFOUND IS NULL;
  28.    v_count := var_rowid.count + v_count;
  29.  END LOOP;
  30.  CLOSE v_cur;
  31.  DBMS_OUTPUT.PUT_LINE(v_count||' '||'rows deleted');
  32. end;

用rowid

   
   
  1. declare
  2.  cursor mycursor is
  3.    SELECT ROWID FROM TEST WHERE XXX = XXXX order by rowid;
  4.  --------按ROWID排序的Cursor,删除条件是XXX=XXXX,根据实际情
  5.  况来定。 type rowid_table_type is table of rowid index by pls_integer;
  6.  v_rowid  rowid_table_type;
  7. BEGIN
  8.  open mycursor;
  9.  loop
  10.    fetch mycursor bulk collect
  11.      into v_rowid limit 5000;
  12.    --------每次处理5000行,也就是每5000行一提交
  13.    exit when v_rowid.count = 0;
  14.    forall i in v_rowid.first .. v_rowid.last
  15.      delete from test where rowid = v_rowid(i);
  16.    commit;
  17.  end loop;
  18.  close mycursor;
  19. END;
  20. /
  21. declare
  22.  cursor cur_user_login is
  23. select USER_ID, LOGIN, LOGIN_TIME from USER_LOGIN;
  24.  type cur_type is table of cur_user_login%rowtype index by pls_integer; ---  index by pls_integer 是数组的固定语法
  25.  cur_tab cur_type;
  26. begin
  27.  open cur_user_login;
  28.  loop
  29.    fetch cur_user_login bulk collect
  30. into cur_tab limit 5000; ----一次批量获取5000行;
  31.    forall i in 1 .. cur_tab.count
  32.      insert into USER_LOGIN_BAK
  33. (USER_ID, LOGIN, LOGIN_TIME)
  34.      values
  35. (cur_tab(i).USER_ID, cur_tab(i).LOGIN, cur_tab(i).LOGIN_TIME);
  36.    commit;
  37. exit when cur_user_login%notfound or cur_user_login%notfound is null;
  38. end loop;
  39.  close cur_user_login;
  40.  commit;
  41. end;
    
    
  1. declare
  2.  cursor mycursor is
  3.    SELECT ROWID FROM t_user_active_log_bak; --order by rowid;
  4. type rowid_table_type is table of rowid index by pls_integer;
  5.  v_rowid  rowid_table_type;
  6. BEGIN
  7.  open mycursor;
  8.  loop
  9.    fetch mycursor bulk collect
  10.      into v_rowid limit 5000;
  11.    exit when v_rowid.count = 0;
  12.    forall i in v_rowid.first .. v_rowid.last
  13.      update t_user_active_log_bak set ctime=ctime+90 where rowid = v_rowid(i);
  14.    commit;
  15.  end loop;
  16.  close mycursor;
  17. END;



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值