oracle开发系列(一)让人抓狂的错误之null值与无值(无结果)

来源:互联网 发布:看图王软件下载 编辑:程序博客网 时间:2024/05/22 08:03

最近,在做开发、写存过的时候碰到一些问题,找了好长时间才发现原因,而且是以前不知道的。所以在这给记下来 给自己备忘和大家参考。

一 、null值

下面举个最简单的例子,平常工作当中肯定比这个sql复杂的多,在这只是把这个易错点呈现出来,他可能是一个复杂sql出错的小的 不容易被发现的一个问题。

\

上面是一个很简单表的所有数据。area_num 区域编码 area_name 区域名称 delflag 有无效标识 1有效 0无效(其中淮北 和宣城的delflag为null)。

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

\

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

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

NULL是数据库中特有的数据类型,当一条记录的某个列为NULL,则表示这个列的值是未知的、是不确定的。既然是未知的,就有无数种的可能性。因此,NULL并不是一个确定的值。

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

\

二、无结果

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

结果为null:\

无结果:\

表面看很的清楚明白,但是到了实际应用中可能 会容易搞错。

下面是示例的存储过程:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
create or replace functiongetProceessidAllDealBySkf_l(proceessidinnumber)
  returnvarchar2as
  cursorpcursoris(
    selectdistinctt.orgid, t.oper_name
      fromtssa_his_dsg.wh_common_busilog_td t
     wheret.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;--初始化
  openpcursor;--打开游标
 
  loop
    fetchpcursor
      intoorgidCursor;--把游标数据放进pcursor变量
    exitwhenpcursor%notfound;
   
    orgid_var     := orgidCursor.orgid;--从orgidCursor变量取值到orgid_var
    oper_name_var := orgidCursor.oper_name;--从orgidCursor变量取值到oper_name_var
   
    if (orgid_varisnull)then--orgid_var是可能为空的 表里面t.orgid为空
      null;
    else
      selectcount(1)
        intocount_var
        fromtssa_dsg.eosorg_t_organization b,
             (selecta.*
                fromtssa_dsg.bndict_t_dictionary a
               wherea.BUSINTYPEID ='WH_CH_ORAPROPERTY'
                 anda.status ='0') a
       whereb.orgproperty = a.businid(+)
         andb.orgid = orgid_var;--统计操作日志表的机构id是否在机构静态表里
      if (count_var > 0)then--在里面
        selectt.orgseq
          intoorgseqflag
          fromtssa_dsg.eosorg_t_organization t
         wheret.orgid = orgid_var
        --取orgseqflag
        ;
        selecta.businname
          intoskforgflag
          fromtssa_dsg.eosorg_t_organization b,
               (selecta.*
                  fromtssa_dsg.bndict_t_dictionary a
                 wherea.BUSINTYPEID ='WH_CH_ORAPROPERTY'
                   anda.status ='0') a
         whereb.orgproperty = a.businid(+)
           andb.orgid = orgid_var;--取组织分类
       
        if (orgseqflaglike'99999.7676.%'or skforgflag = '省客服'or
           (skforgflag !='省客支'and skforgflag != '省层面' and
           oper_name_var ='话务员追加信息'))then
          null;
        else
          returnflag :=null;--不满足id条件 置返回值为null
        endif;
      endif;
    endif;
  endloop;
  closepcursor;
  returnreturnflag;
end;
上面这个过程的作用就是根工单流程id 返回该工单是否只经过某个特定组织机构的人处理的标志。

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

如果不加这个条件 (且没有

?
1
2
3
4
5
6
7
8
9
select count(1)
        intocount_var
        fromtssa_dsg.eosorg_t_organization b,
             (selecta.*
                fromtssa_dsg.bndict_t_dictionary a
               wherea.BUSINTYPEID ='WH_CH_ORAPROPERTY'
                 anda.status ='0') a
       whereb.orgproperty = a.businid(+)
         andb.orgid = orgid_var;--统计操作日志表的机构id是否在机构静态表里
) 

下面这个语句

?
1
2
3
4
select t.orgseq
          intoorgseqflag
          fromtssa_dsg.eosorg_t_organization t
         wheret.orgid = orgid_var
查出来是没有结果的 就是无值
?
1
into orgseqflag
就会报错(调试会报错,直接运行不报错) 直接 跳出 loop 给 return 一个null 值 是不符合业务要求的。
?
1
2
3
4
5
6
7
8
9
10
select count(1)
        intocount_var
        fromtssa_dsg.eosorg_t_organization b,
             (selecta.*
                fromtssa_dsg.bndict_t_dictionary a
               wherea.BUSINTYPEID ='WH_CH_ORAPROPERTY'
                 anda.status ='0') a
       whereb.orgproperty = a.businid(+)
         andb.orgid = orgid_var;--统计操作日志表的机构id是否在机构静态表里
if (count_var > 0)then--在里面
上面这个条件作用跟if(orgid_var is null)是一样的 是忽略 操作日志表的机构id不在机构静态表里的情况。
阅读全文
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 魅蓝note6卡顿怎么办 苹果4s内屏坏了怎么办 魅族mx6一直重启怎么办 魅族充电慢了怎么办啊 笔记本玩游戏掉帧怎么办 psv玩游戏掉帧怎么办 ipad玩游戏掉帧怎么办 手机玩游戏严重掉帧怎么办 苹果7p掉电快怎么办 努比亚z11手机总是开关机怎么办 努比亚手机不能保存图片怎么办 小米8拍照和努比亚怎么办 oppor7手机开不了机怎么办 vivox5m手机开不开机怎么办 步步高x7图案解锁忘记怎么办 手机机锁定怎么办魅族 衣服买完降价了怎么办 在淘宝上不发货怎么办 一加3t吃鸡卡怎么办 小米max打游戏反应慢怎么办 小米max2手机玩游戏卡怎么办 魅蓝metal开不了机怎么办 魅蓝e手机信号差怎么办 魅蓝metal手机已锁定怎么办 魅族not3卡开了怎么办 魅族metal手机好卡怎么办 魅蓝手机锁机了怎么办 魅族note2屏坏了怎么办 魅族mx3开不开机怎么办 魅蓝max3充电慢怎么办? 魅族手机home键失灵怎么办 魅族开关键坏了怎么办 魅族开关键不灵怎么办 魅蓝开机键坏了怎么办 魅族开关机坏了怎么办 小米开机键坏了怎么办 魅族手机关机键失灵怎么办 魅蓝5s发热严重怎么办 华为荣耀v8信号差怎么办 贴膜白边去除液漏进屏幕里面怎么办 魅族pro6s电池休眠了怎么办