zoukankan      html  css  js  c++  java
  • oracle 让人抓狂的错误之 null值 与 无值(无结果)-开发系列(一)

    近期。在做开发、写存过的时候碰到一些问题,找了好长时间才发现原因。并且是曾经不知道的。

    所以在这给记下来 给自己备忘和大家參考。


    一 、null值

    以下举个最简单的样例。寻常工作其中肯定比这个sql复杂的多,在这仅仅是把这个易错点呈现出来,他可能是一个复杂sql出错的小的 不easy被发现的一个问题。


    上面是一个非常easy表的全部数据。area_num 区域编码 area_name 区域名称 delflag 有无效标识 1有效 0无效(当中淮北 和宣城的delflag为null)。

    如今想找出有效的那些区域信息,所以用以下的语句:


    上面的结果中没有淮北和宣城 跟预想中的不一样 一開始以为是 delflag不为0的全部应该都被查询出来 包含淮北和宣城。

    其实 淮北和宣城 delflag的字段是 null值。在oracle里面null值得概念:


    NULL是数据库中特有的数据类型,当一条记录的某个列为NULL,则表示这个列的值是未知的、是不确定的。

    既然是未知的,就有无数种的可能性。因此。NULL并非一个确定的值。


    所以null值(不确定的值) 并不符合 !='0' 这个 条件。相同以下语句也是这样。






    二、无结果

    无结果事实上就是一个select查询没有结果集(不是null,而是没有结果)

    结果为null:


    无结果:


    表面看非常的清楚明确,可是到了实际应用中可能 会easy搞错。



    以下是演示样例的存储过程:

    create or replace function getProceessidAllDealBySkf_l(proceessid in number)
      return varchar2 as
      cursor pcursor is(
        select distinct t.orgid, t.oper_name
          from tssa_his_dsg.wh_common_busilog_td t
         where t.processinstid = proceessid);--取操作日志表某个工单流程proceessid的操作人所属机构id。和操作名称
      orgidCursor   pcursor%rowtype;--定义类型为pcursor行数据的 变量
      orgid_var     varchar2(20);--存放操作人机构id变量
      returnflag    varchar2(20);--返回的标志位
      orgseqflag    varchar2(50);--操作人机构id及其全部父id 串起来字符
      skforgflag    varchar2(20);--存放操作人机构id变量
      count_var     number;--存放统计数字变量
      oper_name_var varchar2(100);--操作名称
    begin
      returnflag    := '1';--返回值初始化为1
      orgseqflag    := null;--初始化
      skforgflag    := null;--初始化
      count_var     := 0;--初始化
      oper_name_var := null;--初始化
      open pcursor;--打开游标
    
      loop
        fetch pcursor
          into orgidCursor;--把游标数据放进pcursor变量
        exit when pcursor%notfound;
      
        orgid_var     := orgidCursor.orgid;--从orgidCursor变量取值到orgid_var
        oper_name_var := orgidCursor.oper_name;--从orgidCursor变量取值到oper_name_var
      
        if (orgid_var is null) then--orgid_var是可能为空的 表里面t.orgid为空 
          null;
        else
          select count(1)
            into count_var
            from tssa_dsg.eosorg_t_organization b,
                 (select a.*
                    from tssa_dsg.bndict_t_dictionary a
                   where a.BUSINTYPEID = 'WH_CH_ORAPROPERTY'
                     and a.status = '0') a
           where b.orgproperty = a.businid(+)
             and b.orgid = orgid_var;--统计操作日志表的机构id是否在机构静态表里
          if (count_var > 0) then--在里面
            select t.orgseq
              into orgseqflag
              from tssa_dsg.eosorg_t_organization t
             where t.orgid = orgid_var
            --取orgseqflag
            ;
            select a.businname
              into skforgflag
              from tssa_dsg.eosorg_t_organization b,
                   (select a.*
                      from tssa_dsg.bndict_t_dictionary a
                     where a.BUSINTYPEID = 'WH_CH_ORAPROPERTY'
                       and a.status = '0') a
             where b.orgproperty = a.businid(+)
               and b.orgid = orgid_var;--取组织分类
          
            if (orgseqflag like '99999.7676.%' or skforgflag = '省客服' or
               (skforgflag != '省客支' and skforgflag != '省层面' and
               oper_name_var = '话务员追加信息')) then
              null;
            else
              returnflag := null;--不满足id条件 置返回值为null
            end if;
          end if;
        end if;
      end loop;
      close pcursor;
      return returnflag;
    end;
    上面这个过程的作用就是根工单流程id 返回该工单是否仅仅经过某个特定组织机构的人处理的标志。

     操作日志表的orgid有为空的情况。
    if(orgid_var is null) 这个条件 推断假设为空 视该记录无效,不參与推断(业务要求)。

    假设不加这个条件 (且没有

    select count(1)
            into count_var
            from tssa_dsg.eosorg_t_organization b,
                 (select a.*
                    from tssa_dsg.bndict_t_dictionary a
                   where a.BUSINTYPEID = 'WH_CH_ORAPROPERTY'
                     and a.status = '0') a
           where b.orgproperty = a.businid(+)
             and b.orgid = orgid_var;--统计操作日志表的机构id是否在机构静态表里

    以下这个语句

    select t.orgseq
              into orgseqflag
              from tssa_dsg.eosorg_t_organization t
             where t.orgid = orgid_var
    查出来是没有结果的 就是无值
     into orgseqflag
    就会报错(调试会报错,直接执行不报错) 直接 跳出 loop 给 return 一个null 值 是不符合业务要求的。


    select count(1)
            into count_var
            from tssa_dsg.eosorg_t_organization b,
                 (select a.*
                    from tssa_dsg.bndict_t_dictionary a
                   where a.BUSINTYPEID = 'WH_CH_ORAPROPERTY'
                     and a.status = '0') a
           where b.orgproperty = a.businid(+)
             and b.orgid = orgid_var;--统计操作日志表的机构id是否在机构静态表里
    if (count_var > 0) then--在里面
    上面这个条件作用跟if(orgid_var is null)是一样的 是忽略 操作日志表的机构id不在机构静态表里的情况。
    
    
    
    
    
    
  • 相关阅读:
    javascript线性渐变2
    javascript无缝滚动2
    javascript Object对象
    javascript无缝滚动
    javascript图片轮换2
    javascript图片轮换
    用C/C++写CGI程序
    linux shell 的 for 循环
    重磅分享:微软等数据结构+算法面试100题全部答案完整亮相
    查看linux服务器硬盘IO读写负载
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/5093801.html
Copyright © 2011-2022 走看看