存储过程备忘

    不得不感慨逝者如斯夫,就这样,转眼间在公司呆了3年之多。3年前常用的sql proc相关知识,在今天接手离职同事工作时发现突然间无法完全忆起。于是,迫使自己找出3年之前的资料,罗列一下存储过程的常用方式,以此备案!

   

标准式游标用法和静态sql

CREATE OR REPLACE PROCEDURE p_use_cursor(
   i_seq_ids   IN       VARCHAR2,
   o_code      OUT      INT,
   o_msg       OUT      VARCHAR2
)
AS
/***********************************************************
注释区:采用标准式游标用法和静态sql
***********************************************************/
   TYPE t_cur IS REF CURSOR;

   v_count             INT;
   c_check             t_cur;
   sqlstr              VARCHAR2 (5000);
   v_code     VARCHAR2 (4);
   v_sid         VARCHAR2 (5);
BEGIN
   v_count := 0;
   o_code := 0;
   o_msg := 'success';
   sqlstr :=
         ' select LOCALNET_CODE,ORG_SID from xtable where seq_id in '
      || i_seq_ids;

   OPEN c_check FOR sqlstr;

   LOOP
      FETCH c_check
       INTO v_code, v_sid;

      EXIT WHEN c_check%NOTFOUND;

      --校验本地网区号
      SELECT COUNT (*)
        INTO v_count
        FROM localnet
       WHERE design_code = v_code;

      IF (v_count = 0)
      THEN
         o_code := 1;
         o_msg := '代码 ' || v_code || ' 不存在!';

         CLOSE c_check;

         RETURN;
      END IF;

      --ORG_SID定长5位
      IF (LENGTH (v_sid) <> 5)
      THEN
         o_code := 2;
         o_msg := 'ORG_SID ' || v_sid || ' 的长度必须为5位!';

         CLOSE c_check;

         RETURN;
      END IF;

      v_count := 0;

      --ORG_SID必须是数字
      SELECT NVL2 (TRANSLATE (v_sid, '\1234567890', '\'), 2, 1)
        INTO v_count
        FROM DUAL;

      IF (v_count = 2)
      THEN
         o_code := 3;
         o_msg := 'ORG_SID ' || v_sid || ' 必须为数字!';

         CLOSE c_check;

         RETURN;
      END IF;

   END LOOP;

   CLOSE c_check;
   
END p_use_cursor;
/

  

直接采用游标和静态sql

CREATE OR REPLACE PROCEDURE p_use_cursor (
   i_batch_id   IN       VARCHAR2,
   i_user_id    IN       VARCHAR2,
   o_code       OUT      INT,
   o_msg        OUT      VARCHAR2
)
AS
/***********************************************************
注释区:直接采用游标和静态sql
***********************************************************/
   CURSOR cur_adjust
   IS
      SELECT *
        FROM table a, table b
       WHERE a.user_id = i_user_id
         AND a.status = 1;

   l_count     INT;
   err_count   INT;
   ok_count    INT;
   now_date    VARCHAR2 (14);
   comp_date   VARCHAR2 (14);
BEGIN
   l_count := 0;
   err_count := 0;
   ok_count := 0;
   now_date := TO_CHAR (SYSDATE, 'YYYYMMDDhh24miss');
   comp_date := i_batch_id || '000000';
   
   FOR c_r IN cur_adjust
   LOOP
     IF (UPPER (c_r.service_code) = 'IVR' OR UPPER (c_r.service_code) = 'PIVR')
      THEN
         o_code := 9;
         err_count := err_count + 1;
         o_msg := 'xxxxxx';

         INSERT INTO zzyw_adjust_error
                     (user_id, user_name, error_time, error_desc,
                      ori_record
                     )
              VALUES (c_r.user_id, c_r.user_name, now_date, o_msg,
                         c_r.service_code
                      || ','
                      || c_r.localnet_abb);

         DELETE FROM yuy_report
               WHERE ROWID = c_r.ROWID;

         GOTO CONTINUE;
      END IF;

--其它操作

      ok_count := ok_count + 1;

      <<continue>>
      NULL;
   END LOOP;

   --其它静态sql

   o_code := 0;
   o_msg :=
         '成功提交的记录数为'
      || ok_count
      || ',错单数为'
      || err_count
      || ',用户可以到本期数据查询菜单中查询错单记录';
   COMMIT;
END p_use_cursor;
/

  

 静态sql完整事务模式

CREATE OR REPLACE PROCEDURE P_TMP_TP_TRUNK (
   i_dealdate		In      tl_data_audit.data_date%TYPE,
   o_returncode   OUT   INTEGER,
   o_returnmsg    OUT   VARCHAR2
)
--******************************************************************************************************************
-- SQL 存储过程
-- 名称  : P_TMP_TP_TRUNK
-- 注意  :
-- 参数  : i_dealdate:要统计的日期
-- 功能描述 : 取开始时间最近的trunk_id到临时表
--******************************************************************************************************************
AS
BEGIN
   o_returncode := -1;
   o_returnmsg := 'TradeOk!';

   --/* 取开始时间最近的入中继信息到中继临时表
   INSERT INTO table_trunk
               (。。。)
        SELECT source_id, trunk_code, trunk_side, start_date
          FROM (SELECT source_id, trunk_code, trunk_side, start_date ,
                       rank() over (PARTITION BY source_Id, trunk_code ORDER BY start_date DESC ) rank
                 FROM (SELECT source_Id, trunk_code, trunk_side, MAX(start_date) start_date
                         FROM tp_trunk_js
                        WHERE substr(end_date,1,8) > i_dealdate
                        GROUP BY source_id, trunk_code , trunk_side)
                WHERE trunk_side IN (0,1)
                GROUP BY 。。。
                )
         WHERE rank = 1
          ;


   --/* 取开始时间最近的入中继信息到入中继信息临时表
   -- sql语句略
   --/*删除中继临时表中的数据
   p_sd_truncatetable ('tmp_tp_trunk', o_returncode, o_returnmsg);

   

   --/* 取开始时间最近的入中继信息到入中继信息临时表
   --略;

   o_returncode := 0;

   IF o_returncode = 0
   THEN
      COMMIT;
   ELSE
      ROLLBACK;
   END IF;
EXCEPTION
   WHEN NO_DATA_FOUND
   THEN
      o_returncode := -1;
      o_returnmsg := SUBSTR ('[01]' || 'tp_trunk没有合适数据 ' || SQLERRM, 1, 255);
      ROLLBACK;

   WHEN OTHERS
   THEN
      o_returncode := -1;
      o_returnmsg :=
              SUBSTR ('[01]' || 'P_TMP_TP_TRUNK错误告警 ' || SQLERRM, 1, 255);
      ROLLBACK;
END;
/

 

CREATE OR REPLACE PROCEDURE P_EXE_MONTHPROC (
        O_ReturnCode    	Out     integer,
        O_ReturnMsg     	Out     varchar2
)
--*****************************************************************************************
-- SQL 存储过程
-- 名称  : P_EXE_MONTHPROC
-- 注意  :
-- 参数  :
-- 功能描述 : 调用月存储过程
--          : 该程序由P_AFTER调用
-- 未完功能 :
-- 返回值   : 0:正确,-1:错误
--***********************************************************************************************
as
     v_data_flag         INT;
     v_deal_date	       number;

     cursor cur1 is
     select distinct sett_month from table_dealdate;
BEGIN
     o_returncode := -1;
     o_returnmsg := 'TradeOk!';

     select 1 into v_data_flag
     from dual
     where exists(
             select 1 from table_dealdate
            );

     for c1 in cur1 loop

    	select (c1.sett_month*100 + 20) into v_deal_date from dual;

    	p_fact_settle_rule(v_deal_date, O_ReturnCode, O_ReturnMsg);
     	If O_ReturnCode <> 0 Then
     		goto ER;
     	End If;

     	p_fact_interconnect_month(v_deal_date, O_ReturnCode, O_ReturnMsg);
     	If O_ReturnCode <> 0 Then
     		goto ER;
     	End If;
		
     end loop;

     p_sd_truncatetable ('tmp_dealdate', o_returncode, o_returnmsg);

<<ER>>
     If O_ReturnCode = 0 Then
     	commit;
     Else
    	rollback;
     END IF;

     EXCEPTION
     when no_data_found   then
          O_ReturnCode := -1;
          O_ReturnMsg := substr('[01]'||'tmp_dealdate表中没有数据 '||sqlerrm,1,255);
          ROLLBACK;

     WHEN OTHERS THEN
          O_ReturnCode := -1;
          O_ReturnMsg := substr('[01]'||'P_EXE_MONTHPROC错误告警 '||sqlerrm,1,255);
     ROLLBACK;

END;
/

动态sql完整事务模式

CREATE OR REPLACE PROCEDURE              P_TMP_P01(i_dealdate   IN TMP_OTHER_TODAY_SETT.statdate%TYPE,
                                                       O_ReturnCode OUT INTEGER,
                                                       O_ReturnMsg  OUT VARCHAR2)
 AS
  v_Cursor         NUMBER;
  v_rows           NUMBER;
  v_SQL            VARCHAR2(5000);
  v_SQL_data       VARCHAR2(400);
  v_insert_sql     VARCHAR2(1000);
  v_select_sql     VARCHAR2(2000);
  v_from_sql       VARCHAR2(200);
  v_where_sql      VARCHAR2(800);
  v_groupby_sql    VARCHAR2(1500);
  v_partition_name VARCHAR2(5);

  v_parm      NUMBER;
  v_data_flag INT;
  v_tablename VARCHAR2(20);
BEGIN
  o_returncode     := -1;
  o_returnmsg      := 'TradeOk!';
  v_partition_name := 'p1';

  --/*从参数表取得结果表中的省份代码
  SELECT par_value INTO v_parm FROM xtableWHERE par_code = 1;

  --/*获得要处理的清单表名
  SELECT 'xtable_' || SUBSTR(i_dealdate, 7) INTO v_tablename FROM dual;

  --/*查看接口表是否有当天的数据
  v_sql_data := 'select 1 from dual where exists( select 1 from ' ||
                v_tablename || ' partition (' || v_partition_name ||
                ') where end_datetime between to_date(''' || i_dealdate ||
                '000000''' || ',''yyyymmddhh24miss'') and to_date(''' ||
                i_dealdate || '235959''' || ',''yyyymmddhh24miss''))';
  EXECUTE IMMEDIATE v_sql_data
    INTO v_data_flag;

  --/*向临时表中插入主叫数据
  v_insert_sql := 'INSERT INTO TMP_table_SETT (....) ';

  v_select_sql  := ' select   
            TO_CHAR(end_datetime,''yyyymmdd'') ,
            ....,SUM(local_discount_fee) , 
            SUM(toll_discount_fee) , SUM(local_discount_fee + toll_discount_fee), 
            SUM(sett_fee)';
  v_from_sql    := ' from ' || v_tablename || ' partition (' ||
                   v_partition_name ||
                   ') a , s_area b , tpw_iden_settle_type  c ';
  v_where_sql   := ' where end_datetime between to_date(''' || i_dealdate ||
                   '000000''' || ',''yyyymmddhh24miss'') and to_date(''' ||
                   i_dealdate || '235959''' ||
                   ',''yyyymmddhh24miss'') and called_area_code = b.area_code and b.prov_code = ' ||
                   v_parm || ' and a.sett_type = c.sett_type ' ||
                   ' and a.called_tsp_code = 11';
  v_groupby_sql := ' Group by    
            TO_CHAR(end_datetime,''yyyymmdd'') ,
            a.calling_code  ';
  v_sql         := v_insert_sql || ' ' || v_select_sql || ' ' || v_from_sql || ' ' ||
                   v_where_sql || ' ' || v_groupby_sql;

  BEGIN
    -- 开始执行动态SQL
    v_cursor := DBMS_SQL.OPEN_CURSOR;
    DBMS_SQL.PARSE(v_cursor, v_sql, DBMS_SQL.v7);
    v_rows := DBMS_SQL.EXECUTE(v_cursor);
    DBMS_SQL.CLOSE_CURSOR(v_cursor);
  EXCEPTION
    WHEN OTHERS THEN
      o_returnmsg := 'P_TMP_OTHER_TODAY_SETT_'||v_partition_name||'发生未知错误 01@: ' ||
                     SQLERRM;
      ROLLBACK;
      RETURN;
  END;

 
  o_returncode := 0;

  IF o_returncode = 0 THEN
    COMMIT;
  ELSE
    ROLLBACK;
  END IF;

EXCEPTION
  WHEN NO_DATA_FOUND THEN
    O_ReturnCode := 1;
    O_ReturnMsg  := SUBSTR('[01]' ||
                           'P_TMP_OTHER_TODAY_SETT_'||v_partition_name||'发生未知错误' ||
                           SQLERRM,
                           1,
                           255);
    ROLLBACK;
  
  WHEN OTHERS THEN
    O_ReturnCode := -1;
    O_ReturnMsg  := SUBSTR('[01]' ||
                           'P_TMP_OTHER_TODAY_SETT_'||v_partition_name||'发生未知错误' ||
                           SQLERRM,
                           1,
                           255);
    ROLLBACK;
  
END;
/

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值