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

來源:互聯網
上載者:User

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

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


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






在這個文章"怎寫sql語句去掉oracle返回結果中的空值(NULL)"中看見你的回答,不是很理解具體怎使用?

兩個資料表a(id,name,age)中4條記錄和b(id(外鍵),address)中3條記錄
select * from a right join b on a.id =b.id; 以右邊的表為主,顯示a和b中id相同的資料,返回3條資料,a表中的第四個id不顯示,因為b表中的address沒有值。
select * from a left join b a.id = b.id; 以左邊的表為主,顯示表a中所有的id ,但address有一條是空值。返回4條記錄。
 
怎寫sql語句去掉oracle返回結果中的空值(NULL)

沒有什麼簡便的方法,但是你可以通過查系統資料表來減少你寫文法的工作,例如:
select 'AND ' ||COLUMN_NAME||' IS NOT NULL' from all_tab_columns where table_name = 'table_name'

這樣這個表的所有欄位就自動組成了條件陳述式。
 

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.