关于null值的一次错误小计

早晨到公司,得知有一笔资金出了问题。

了解问题后,我觉得此消息不太准确,因为此笔资金不平,数据库是会抛出一个错误以中断后续的处理。

于是来核对报表的结果,令人不爽的是,资金的确不平,但没有抛出异常。

抛出异常的语句如下:

     
select count(*) into v_count from sett_09_fundbalance
    where sszjcy!=sjlk;
    if(v_count!=0) then
         update sett_09_fundbalance set sszjcy=sjlk-sszjcy;
         commit;  
         RAISE_APPLICATION_ERROR(-20002,'实收资金与已付资金不一致');
    else     
      update sett_09_fundbalance set sszjcy=sjlk-sszjcy;
      commit;       
    end if;

但sszjcy查明为null值,所以这里没有抛出异常。我一直对null值的问题都很注意,但这次又中招了。

这是因为前面的一个更新语句所导致的连锁反应

    
update sett_09_fundbalance set (qtjyjfjyje,qtjyjfzjqsce)=
    (
      select sum(tp.txamt),sum(tp.txamt) from datasvr.cups_tpdet tp
      where tp.tipschkflag in('1','3','4') and settledate=v_settledate
    );

  其中datasvr.cups_tpdet表因为没有交易,所以产生的合计是null,将之前qtjyjfjyje与qtjyjfzjqsce的默认值0,都更新为了null
  而qtjyjfjyje与qtjyjfzjqsce又参与了其他的运算,从而导致了其他字段也出现null值
将更新语句更新为

update sett_09_fundbalance set (qtjyjfjyje,qtjyjfzjqsce)= 
(
      select sum(tp.txamt),sum(tp.txamt) from datasvr.cups_tpdet tp
      where tp.tipschkflag in('1','3','4') and settledate=v_settledate
    )
    where exists
    (
      select 1 from datasvr.cups_tpdet tp
      where tp.tipschkflag in('1','3','4') and settledate=v_settledate
    )


  就没有问题了。

1、等价于没有任何值、是未知数。
2、NULL与0、空字符串、空格都不同。
3、对空值做加、减、乘、除等运算操作,结果仍为空。
4、NULL的处理使用NVL函数。
5、比较时使用关键字用“is null”和“is not null”。
6、空值不能被索引,所以查询时有些符合条件的数据可能查不出来,
   count(*)中,用nvl(列名,0)处理后再查。
7、排序时比其他数据都大(索引默认是降序排列,小→大),
   所以NULL值总是排在最后

猜你喜欢

转载自have23.iteye.com/blog/1574608