【Oracle】容易犯的错误和技巧集合

引言

     此文记录日常开发中容易遇到的oracle编程误区和一些使用技巧,不定期更新.

1.sum(),max(),min(),avg()等函数会得到null值

declare 
  n_num  number(5):='';
begin
select sum(1) into n_num  from dual where 1=2 ;
 n_num:= n_num+2;
dbms_output.put_line(n_num);
end;

上面代码描述了我们日常开发的一个场景,将某个表的数据求和,然后再各种计算.正常情况是没有问题的,但是求和表没有数据的,我们就会得到一个空值,然后导致后面的一系列计算都是空值,

造成业务误差.

处理办法:加上nvl()函数处理这种异常,如下:

declare 
  n_num  number(5):='';
begin
select nvl(sum(1),0) into n_num  from dual where 1=2 ;
 n_num:= n_num+2;
dbms_output.put_line(n_num);
end;

 2.超长字符拼接

     我们一般用函数wm_concat拼接字段,但是拼接超长字符串(长度大于32767)时,就抛错了.后来找到一个自定义函数能够无压力拼接超长字符串,代码是抄下来了,但是出处网址没记下来.......函数如下:

CREATE OR REPLACE TYPE t_long_concat
AUTHID CURRENT_USER AS OBJECT
(
  CURR_STR clob,
  STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX IN OUT t_long_concat) RETURN NUMBER,
  MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF IN OUT t_long_concat,
  P1 IN VARCHAR2) RETURN NUMBER,
  MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF IN t_long_concat,
  RETURNVALUE OUT clob,
  FLAGS IN NUMBER)
  RETURN NUMBER,
  MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF IN OUT t_long_concat,
  SCTX2 IN t_long_concat) RETURN NUMBER
);


CREATE OR REPLACE TYPE BODY t_long_concat
IS
  STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX IN OUT t_long_concat)
  RETURN NUMBER
  IS
  BEGIN
  SCTX := t_long_concat(NULL) ;
  RETURN ODCICONST.SUCCESS;
  END;
  MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF IN OUT t_long_concat,

  P1 IN VARCHAR2)
  RETURN NUMBER
  IS
  BEGIN
  IF(CURR_STR IS NOT NULL) THEN
  CURR_STR := CURR_STR || ',' || P1;
  ELSE
  CURR_STR := P1;
  END IF;
  RETURN ODCICONST.SUCCESS;
  END;
  MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF IN t_long_concat,
  RETURNVALUE OUT clob,
  FLAGS IN NUMBER)
  RETURN NUMBER
  IS
  BEGIN
  RETURNVALUE := CURR_STR ;
  RETURN ODCICONST.SUCCESS;
  END;
  MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF IN OUT t_long_concat,
  SCTX2 IN t_long_concat)
  RETURN NUMBER
  IS
  BEGIN
  IF(SCTX2.CURR_STR IS NOT NULL) THEN
  SELF.CURR_STR := SELF.CURR_STR || ',' || SCTX2.CURR_STR ;
  END IF;
  RETURN ODCICONST.SUCCESS;
  END;
END;


CREATE OR REPLACE FUNCTION long_concat(P1 VARCHAR2)
RETURN clob AGGREGATE USING t_long_concat ;

3.Group by 和 Having

    通常我们在存储过程中判断表的字段中有没有重复数据,可能会用到下面的SQL

select count(*) into N_Count from T_Table t Group by t.Name having count(*)>1;

if N_Count>0 then
  --操作
end if;

然而这种写法是有问题的.1.当没有重复数据时会引发NO_DATA_FOUND异常.2.当有多个重复组时会引发返回多行异常,正确的写法应该是这样的.

select  count(*) into N_Count from  ( select t.Name  from T_Table t group by t.Name having count(*)>1 )
if N_Count>0 then
  --操作
end if;

4.行转列

    有时候要将行数据转换为列.下面给出一个例子,目的是将成绩排名数据转成列显示.

  select * from (
        select 100 score, 1 ranknum, '一班' nam from dual
        union all
        select 99 score, 2 ranknum, '一班' nam from dual
        union all
        select 98 score, 1 ranknum, '二班' nam from dual
        union all
        select 90 score, 2 ranknum, '二班' nam from dual
        )
         PIVOT(
         max(score) --要转成行的字段
         for ranknum --根据哪个字段的信息进行转换
         IN(1 as col1, 2 as col2, 3 as col3)--根据字段信息生成对应的列
          )

 

posted @ 2015-05-08 16:10  Caizl  阅读(300)  评论(0编辑  收藏  举报