程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> Oracle數據庫 >> Oracle教程 >> oracle開發系列(一)讓人抓狂的錯誤之null值與無值(無結果)

oracle開發系列(一)讓人抓狂的錯誤之null值與無值(無結果)

編輯:Oracle教程

oracle開發系列(一)讓人抓狂的錯誤之null值與無值(無結果)


最近,在做開發、寫存過的時候碰到一些問題,找了好長時間才發現原因,而且是以前不知道的。所以在這給記下來 給自己備忘和大家參考。

一 、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:\

無結果:\

表面看很的清楚明白,但是到了實際應用中可能 會容易搞錯。

下面是示例的存儲過程:

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不在機構靜態表裡的情況。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved