zoukankan      html  css  js  c++  java
  • 【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)--根据字段信息生成对应的列
              )
  • 相关阅读:
    排序算法与数据结构复习总结
    Kafka知识总结及面试题
    深入理解Redis系列之事务
    深入理解Redis系列之持久化
    基于数据库、redis和zookeeper实现的分布式锁
    深入理解MySQL系列之优化
    Mysql-主从复制(Docker)
    Mysql-GTID主从复制
    Ansible基础
    Nginx + php-fpm源码编译
  • 原文地址:https://www.cnblogs.com/caizl/p/4450320.html
Copyright © 2011-2022 走看看