oracle游标中使用select into查询结果为NULL导致异常提前退出循环——菜鸟解决办法(^_^)

首先贴出我的存储过程

create or replace procedure PROC_FILLANDREMOVECDEM As
  V_ERROR        NUMBER(10, 0); --异常
  e_cardnbr      varchar2(20); --卡号
  e_filename     varchar2(200); --文件名
  e_contents     clob; --内容
  e_productno    VARCHAR2(4); --产品编码
  e_PAGENO       VARCHAR2(4); --版面代码
  e_CUSTR        varchar2(20); --证件号码
  e_STATUS       VARCHAR2(5); --处理状态
  e_CREATED_TIME DATE; --处理时间

  CURSOR E_DATA IS
    SELECT * FROM DATASTRIPCARDERR t where t.pageno is null;

begin

  for err_data in E_DATA loop
  
    BEGIN
    --(select into多个变量时候如果查询的变量有一个为null则进入异常块,终止循环)
        select t.cardnbr,
               t.filename,
               t.contents,
               t.productno,
               t.pageno,
               t.custr,
               t.status,
               t.created_time
          into e_cardnbr,
               e_filename,
               e_contents,
               e_productno,
               e_PAGENO,
               e_CUSTR,
               e_STATUS,
               e_CREATED_TIME
          from datastripcard t
         where t.custr = err_data.custr
           and t.productno = err_data.productno;
 
    end;
  
  end loop;
  commit;

EXCEPTION
  WHEN OTHERS THEN
    V_ERROR := SQLCODE;
    DBMS_OUTPUT.put_line(V_ERROR);
    INSERT INTO s_syslog t
      (t.log_id, t.type, t.contents, t.memo)
    values
      (s_syslog_seq.nextval,
       '0008',
       v_error,
       '。。。。。');
    COMMIT;
    ROLLBACK;
end PROC_FILLANDREMOVECDEM;
更新后的存储过程:

添加的sql在  -------------------------------块之间

create or replace procedure PROC_FILLANDREMOVECDEM As
  V_ERROR        NUMBER(10, 0); --异常
  e_cardnbr      varchar2(20); --卡号
  e_filename     varchar2(200); --文件名
  e_contents     clob; --内容
  e_productno    VARCHAR2(4); --产品编码
  e_PAGENO       VARCHAR2(4); --版面代码
  e_CUSTR        varchar2(20); --证件号码
  e_STATUS       VARCHAR2(5); --处理状态
  e_CREATED_TIME DATE; --处理时间
  e_count        number;--注:控制变量

  CURSOR E_DATA IS
    SELECT * FROM DATASTRIPCARDERR t where t.pageno is null;

begin

  for err_data in E_DATA loop
  
    BEGIN
	  ------------------------------------注:每次循环先根据条件看查询的数据是否有值
      select count(1)
        into e_count
        from datastripcard t
       where t.custr = err_data.custr
         and t.productno = err_data.productno;
    
      IF e_count > 0 THEN
	  -------------------------------------注:有值的话再赋给变量,这样就不会有异常
        select t.cardnbr,
               t.filename,
               t.contents,
               t.productno,
               t.pageno,
               t.custr,
               t.status,
               t.created_time
          into e_cardnbr,
               e_filename,
               e_contents,
               e_productno,
               e_PAGENO,
               e_CUSTR,
               e_STATUS,
               e_CREATED_TIME
          from datastripcard t
         where t.custr = err_data.custr
           and t.productno = err_data.productno;
      
      END IF;
    end;
  
  end loop;
  commit;

EXCEPTION
  WHEN OTHERS THEN
    V_ERROR := SQLCODE;
    DBMS_OUTPUT.put_line(V_ERROR);
    INSERT INTO s_syslog t
      (t.log_id, t.type, t.contents, t.memo)
    values
      (s_syslog_seq.nextval,
       '0008',
       v_error,
       '。。。。。');
    COMMIT;
    ROLLBACK;
end PROC_FILLANDREMOVECDEM;

这是个笨方法,但是却最简单明了!

----------------------------------------------------------------------------------------------

说实话上面的存储过程我自己看不下去了,这上面的语句是坑啊!效率要多低有多低,千万别被我这个菜鸟的思想误导

其实完全没有必要声明那么多变量,也没必要select into 那么多变量,毕竟有游标,把所有的结果集查出来存游标里就好。

下面循环更新即可!           -------------------上面的代码是坑 (切记能查出来的就存游标,不管sql如何复杂)

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值