我的一个PLSQL函数 先查询再插入数据库的函数 动态SQL拼接查询条件、通用游标、记录定义(封装部分查询字段并赋值给游标)、insert select 序列、常量【我】

 

先查询再插入数据库的函数

CREATE OR REPLACE FUNCTION F_REVENUE_SI(l_p_cd             in Varchar2,
                                        l_c_cd             in Varchar2,
                                        l_prod_type        in Varchar2,
                                        l_identity_type    in Varchar2,
                                        l_industry_type_id in Varchar2,

                                        l_p_id            in Varchar2,
                                        l_c_id            in Varchar2,
                                        l_region_name     in Varchar2,
                                        l_industry_code   in Varchar2,
                                        l_industry_name   in Varchar2,
                                        l_par_industry_id in Varchar2,
                                        l_industry_grade  in Varchar2

                                        ) return varchar2

 IS
  /*
  DECLARE
    l_p_cd             Varchar2(1000) := 8350000;
    l_c_cd             Varchar2(1000) := 8350102;
    l_prod_type        Varchar2(1000) := 10;
    l_identity_type    Varchar2(1000) := 2;
    l_industry_type_id Varchar2(1000) := 2;

    l_p_id            Varchar2(1000) := 1;
    l_c_id            Varchar2(1000) := 1;
    l_region_name     Varchar2(1000) := 1;
    l_industry_code   Varchar2(1000) := 1;
    l_industry_name   Varchar2(1000) := 1;
    l_par_industry_id Varchar2(1000) := 1;
    l_industry_grade  Varchar2(1000) := 1;
  */
  --定义变量接收参数,以便对参数进行修改
  ll_identity_type    varchar2(1000) := l_identity_type;
  ll_industry_type_id varchar2(1000) := l_industry_type_id;

  --函数返回值
  return_val varchar2(8000) := '开始';
  --通用游标
  cv SYS_REFCURSOR;
  --创建记录用于封装部分查询结果
  TYPE revenue_type IS RECORD(
    r1 REVENUE_STATISTICS_RES.Audit_Cust_Num%TYPE,
    r2 REVENUE_STATISTICS_RES.AUDIT_CUST_PARTY_NUM%TYPE,

    t1  REVENUE_STATISTICS_RES.TY_1%TYPE,
    t2  REVENUE_STATISTICS_RES.TY_1%TYPE,
    t3  REVENUE_STATISTICS_RES.TY_1%TYPE,
    t4  REVENUE_STATISTICS_RES.TY_1%TYPE,
    t5  REVENUE_STATISTICS_RES.TY_1%TYPE,
    t6  REVENUE_STATISTICS_RES.TY_1%TYPE,
    t7  REVENUE_STATISTICS_RES.TY_1%TYPE,
    t8  REVENUE_STATISTICS_RES.TY_1%TYPE,
    t9  REVENUE_STATISTICS_RES.TY_1%TYPE,
    t10 REVENUE_STATISTICS_RES.TY_1%TYPE,
    t11 REVENUE_STATISTICS_RES.TY_1%TYPE,
    t12 REVENUE_STATISTICS_RES.TY_1%TYPE,

    y1  REVENUE_STATISTICS_RES.TY_1%TYPE,
    y2  REVENUE_STATISTICS_RES.TY_1%TYPE,
    y3  REVENUE_STATISTICS_RES.TY_1%TYPE,
    y4  REVENUE_STATISTICS_RES.TY_1%TYPE,
    y5  REVENUE_STATISTICS_RES.TY_1%TYPE,
    y6  REVENUE_STATISTICS_RES.TY_1%TYPE,
    y7  REVENUE_STATISTICS_RES.TY_1%TYPE,
    y8  REVENUE_STATISTICS_RES.TY_1%TYPE,
    y9  REVENUE_STATISTICS_RES.TY_1%TYPE,
    y10 REVENUE_STATISTICS_RES.TY_1%TYPE,
    y11 REVENUE_STATISTICS_RES.TY_1%TYPE,
    y12 REVENUE_STATISTICS_RES.TY_1%TYPE);
  --声明变量为自定义记录类型
  revenue_rec revenue_type;
  --最终查询sql
  s_all varchar2(3000) := '';

  --基本SQL(注意 UPPER(m.PARTY_ID) != ''NULL'' 中字符串NULL要用4个单引号,否则执行不报错但查询结果是错的
  s1 varchar2(1000) := 'SELECT /*+PARALLEL(12)*/
                 COUNT(e.CUST_ID) AUDIT_CUST_NUM, COUNT(DISTINCT(m.PARTY_ID)) AUDIT_CUST_PARTY_NUM,
  SUM(TY_1) TY1 ,SUM(TY_2) TY2,SUM(TY_3) TY3,SUM(TY_4) TY4,SUM(TY_5) TY5,SUM(TY_6) TY6,SUM(TY_7) TY7,SUM(TY_8) TY8,SUM(TY_9) TY9,SUM(TY_10) TY10,SUM(TY_11) TY11,SUM(TY_12) TY12,
  SUM(LY_1) LY1 ,SUM(LY_2) LY2,SUM(LY_3) LY3,SUM(LY_4) LY4,SUM(LY_5) LY5,SUM(LY_6) LY6,SUM(LY_7) LY7,SUM(LY_8) LY8,SUM(LY_9) LY9,SUM(LY_10) LY10,SUM(LY_11) LY11,SUM(LY_12) LY12
             FROM EDA_CUST_INC e, CUST_CP_MERGE m
             WHERE
                   e.CUST_ID = m.CUST_ID
               AND e.STD_LATN_CD = m.STD_LATN_CD
               and m.PARTY_ID IS NOT NULL
               AND UPPER(m.PARTY_ID) != ''NULL''
               AND   e.STD_PRVNCE_CD = ' || l_p_cd ||
                       ' AND e.STD_LATN_CD = ' || l_c_cd;

  --产品类型
  s_prod_type varchar2(1000) := ' AND   e.PROD_TYPE =' || l_prod_type;

  --身份证类型
  s_identity varchar2(1000) := ' AND EXISTS (SELECT 1
                        FROM PARTY P
                       WHERE m.PARTY_ID = p.PARTY_ID
                           AND p.IDENTITY_TYPE = ' ||
                               l_identity_type || ')';

  --行业类型
  s_industry varchar2(1000) := ' and exists (select 1
                          from party_org po
                         where m.party_id = po.party_id
                             and po.INDUSTRY_TYPE_ID = ' ||
                               l_industry_type_id || ')';

BEGIN
  --处理产品类型参数
  /*
  IF l_prod_type is null
  THEN
    s_prod_type := ' AND e.PROD_TYPE is null';
  END IF;
  */
  --处理身份证类型参数
  IF l_identity_type = '-1' THEN
    s_identity := ' AND not EXISTS (SELECT 1
                            FROM PARTY P
                           WHERE m.PARTY_ID = p.PARTY_ID)';
  ELSIF l_identity_type = '-2' THEN
    s_identity := ' AND EXISTS (SELECT 1
                          FROM PARTY P
                         WHERE m.PARTY_ID = p.PARTY_ID
                             AND p.IDENTITY_TYPE is null)';
  END IF;

  --处理行业类型参数
  IF l_identity_type = '-1' THEN
    s_industry := ' and not exists (select 1
                            from party_org po
                           where m.party_id = po.party_id)';
  ELSIF l_identity_type = '-2' THEN
    s_industry := ' and exists (select 1
                          from party_org po
                         where m.party_id = po.party_id
                             and po.INDUSTRY_TYPE_ID is null)';
  END IF;

  --拼接最终查询sql
  s_all := s1 || s_prod_type || s_identity || s_industry;
  DBMS_OUTPUT.PUT_LINE(s_all);
  return_val := '查询sql:' || s_all;
  --打开通用游标
  OPEN cv FOR s_all;
  --将游标赋值给变量
  FETCH cv
    INTO revenue_rec;
  --关闭游标
  CLOSE cv;

  --给本地变量赋值以便后面插入时使用(适用于对传入参数转换后使用)
  IF l_identity_type != '1' and l_identity_type != '2' THEN
    ll_identity_type := null;
  END IF;

  IF l_industry_type_id = '-1' or l_industry_type_id = '-2' THEN
    ll_industry_type_id := null;
  END IF;

  --执行插入
  insert into REVENUE_STATISTICS_RES
    (ID,
     AUDIT_CUST_NUM,
     AUDIT_CUST_PARTY_NUM,
     TY_1,
     TY_2,
     TY_3,
     TY_4,
     TY_5,
     TY_6,
     TY_7,
     TY_8,
     TY_9,
     TY_10,
     TY_11,
     TY_12,
     LY_1,
     LY_2,
     LY_3,
     LY_4,
     LY_5,
     LY_6,
     LY_7,
     LY_8,
     LY_9,
     LY_10,
     LY_11,
     LY_12,

     PROVINCE_REGION_ID,
     CITY_REGION_ID,
     REGION_NAME,

     IDENTITY_TYPE,
     PROD_TYPE,

     INDUSTRY_TYPE_ID,
     INDUSTRY_TYPE_CODE,
     INDUSTRY_TYPE_NAME,
     PAR_INDUSTRY_TYPE_ID,
     INDUSTRY_TYPE_GRADE,

     IN_DATE)
    select SEQ_REVENUE_STATISTICS_RES.NEXTVAL, f.*
      from (SELECT revenue_rec.r1,
                   revenue_rec.r2,

                   revenue_rec.t1,
                   revenue_rec.t2,
                   revenue_rec.t3,
                   revenue_rec.t4,
                   revenue_rec.t5,
                   revenue_rec.t6,
                   revenue_rec.t7,
                   revenue_rec.t8,
                   revenue_rec.t9,
                   revenue_rec.t10,
                   revenue_rec.t11,
                   revenue_rec.t12,

                   revenue_rec.y1,
                   revenue_rec.y2,
                   revenue_rec.y3,
                   revenue_rec.y4,
                   revenue_rec.y5,
                   revenue_rec.y6,
                   revenue_rec.y7,
                   revenue_rec.y8,
                   revenue_rec.y9,
                   revenue_rec.y10,
                   revenue_rec.y11,
                   revenue_rec.y12,

                   l_p_id,
                   l_c_id,
                   l_region_name,

                   ll_identity_type,
                   l_prod_type,

                   ll_industry_type_id,
                   l_industry_code,
                   l_industry_name,
                   l_par_industry_id,
                   l_industry_grade,

                   sysdate
              from dual) f;
  COMMIT;
  return_val := '插入完成';
  return return_val;

EXCEPTION
  WHEN OTHERS THEN
    return_val := return_val || '异常编码:' || SQLCODE || ' 异常信息:' || SQLERRM;
    --return return_val;
    DBMS_OUTPUT.PUT_LINE(return_val);
    --抛出异常
    RAISE;
END;

 

 测试时,建议去掉 异常处理,避免出现异常不提示。

 

posted @ 2019-11-01 15:03  戈博折刀  阅读(589)  评论(0编辑  收藏  举报