ORACLE 存储过程动态游标例子

来源:互联网 发布:网络知识大赛 编辑:程序博客网 时间:2024/04/30 00:55

http://blog.csdn.net/dreamthen/article/details/8509177


一、

[html] view plain copy
  1. CREATE OR REPLACE PROCEDURE PRC_WAP_ACTIVEUSERS(RETCODE OUT VARCHAR2)  
  2. /***********************************************************  
  3.   * 功能:WAP指标--活跃用户统计(分批提交)                       
  4.   * 参数:RETCODE(返回编码:0000成功)                          
  5.   * 作者:  
  6.   * 创建时间:2013-01-16                                       
  7.   * 版本:1.0                                                   
  8.   * 修改人:                                                    
  9.   * 修改时间:                                                  
  10.   **********************************************************/  
  11.  IS  
  12.   RET_CODE VARCHAR2(6);                 --错误信息代码  
  13.   RET_MSG  VARCHAR2(200);               --错误信息  
  14.   V_LAST_MONTH      VARCHAR2(8);        --上个月份  
  15.   V_FIRST_DAY_MONTH VARCHAR2(10);       --上个月第一天  
  16.   V_END_DAY_MONTH   VARCHAR2(10);       --上个月第二天  
  17.   V_COUNT           NUMBER;             --计数变量  
  18.   V_COMMITNUM CONSTANT NUMBER :=1000000;--一次提交记录数(默认一百万)  
  19.   
  20. BEGIN  
  21.   --程序开始  
  22.   DBMS_OUTPUT.PUT_LINE('PRC_WAP_ACTIVEUSERS BEGIN : ' ||  
  23.                        TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS'));  
  24.                          
  25.   RET_CODE :'0000';                   --返回编码初始化  
  26.   V_COUNT  :0;                        --计数器初始化  
  27.   --申明游标  
  28.   DECLARE  
  29.     TYPE CUR_DATA_TYPE IS RECORD        --定义动态游标数据类型  
  30.     (  
  31.       PHONE_NUM   VARCHAR2(20),         --电话号码  
  32.       LOGIN_TIMES VARCHAR2(2000));      --访问次数  
  33.     
  34.     VRECORD CUR_DATA_TYPE;              --定义数据类型  
  35.   BEGIN  
  36.     
  37.     SELECT TO_CHAR(ADD_MONTHS(LAST_DAY(SYSDATE), -1), 'YYYYMM')  
  38.       INTO V_LAST_MONTH  
  39.       FROM DUAL;  
  40.     
  41.     SELECT TO_CHAR(ADD_MONTHS(LAST_DAY(SYSDATE) + 1, -2), 'YYYYMMDD')  
  42.       INTO V_FIRST_DAY_MONTH  
  43.       FROM DUAL;  
  44.     
  45.     SELECT TO_CHAR(ADD_MONTHS(LAST_DAY(SYSDATE), -1), 'YYYYMMDD')  
  46.       INTO V_END_DAY_MONTH  
  47.       FROM DUAL;  
  48.     
  49.     FOR VRECORD IN (SELECT TEL AS PHONE_NUM, COUNT(T.TEL) AS LOGIN_TIMES  
  50.                       FROM TEMP_BOSS_BIP1A021 T  
  51.                      WHERE T.DAY_ID BETWEEN V_FIRST_DAY_MONTH AND  
  52.                            V_END_DAY_MONTH HAVING COUNT(T.TEL) >= 2  
  53.                      GROUP BY T.TEL) LOOP  
  54.       
  55.       INSERT INTO T_BIP1A021  
  56.         (PHONE_NUM, LOGIN_TIMES, LOGIN_MONTH)  
  57.       VALUES  
  58.         (VRECORD.PHONE_NUM, VRECORD.LOGIN_TIMES, V_LAST_MONTH);  
  59.       
  60.       IF ((MOD(V_COUNT, V_COMMITNUM)) = 0) THEN   
  61.         COMMIT;                         --求余:一百万提交一次  
  62.       END IF;  
  63.         
  64.       V_COUNT :V_COUNT + 1;  
  65.       
  66.     END LOOP;  
  67.     
  68.     COMMIT;  
  69.     
  70.     DBMS_OUTPUT.PUT_LINE('PRC_WAP_ACTIVEUSERS END: ' ||  
  71.                          TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS'));  
  72.   EXCEPTION  
  73.     WHEN OTHERS THEN  
  74.       BEGIN  
  75.         ROLLBACK;  
  76.         RET_CODE :'0001';  
  77.         RET_MSG  :'存储过程 PRC_WAP_ACTIVEUSERS 执行错误!' || CHR(10) ||  
  78.                     '错误代码:' || SQLCODE || CHR(10) || '错误信息:' ||  
  79.                     SUBSTR(SQLERRM, 1, 128);  
  80.         GOTO TOEND;  
  81.       END;  
  82.   END;  
  83.   
  84.   --返回程序运作结果  
  85.   <<TOEND>>  
  86.   RETCODE :RET_CODE;  
  87.   IF (RET_CODE = '0000') THEN  
  88.     RET_MSG :'运行成功!';  
  89.     COMMIT;  
  90.   ELSE  
  91.     RET_MSG :'运行失败!' || RET_MSG;  
  92.     ROLLBACK;  
  93.   END IF;  
  94.   
  95.   DBMS_OUTPUT.PUT_LINE(RET_MSG);  
  96.   
  97.   DBMS_OUTPUT.PUT_LINE('END TIME : ' ||  
  98.                        TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS'));  
  99.   
  100. END PRC_WAP_ACTIVEUSERS;  

二、

[sql] view plain copy
  1. CREATE OR REPLACE PROCEDURE PRC_WAP_ACTIVEUSERS_BATCH(RETCODE OUT VARCHAR2,  
  2.                                                       V_TABLE IN VARCHAR2)  
  3. /***********************************************************  
  4.   * 功能:WAP指标--活跃用户统计(分批提交)                *  
  5.   * 参数:RETCODE(返回编码),V_TABLE(插入表)           *  
  6.   * 作者:ZENGMS                                           *  
  7.   * 创建时间:2013-01-16                                   *  
  8.   * 版本:1.0                                              *  
  9.   * 修改人:                                               *  
  10.   * 修改时间:                                             *  
  11.   **********************************************************/  
  12.  IS  
  13.   RET_CODE          VARCHAR2(6);                 --错误信息代码  
  14.   RET_MSG           VARCHAR2(200);               --错误信息  
  15.   EXEC_SQL          VARCHAR2(2000);              --SQL语句  
  16.   V_LAST_MONTH      VARCHAR2(8);                 --上个月份  
  17.   V_FIRST_DAY_MONTH VARCHAR2(10);                --上个月第一天  
  18.   V_END_DAY_MONTH   VARCHAR2(10);                --上个月第二天  
  19.   V_TOTALNUM        NUMBER;                      --总记录数  
  20.   V_COMMITNUM       NUMBER;                      --一次提交数量  
  21.   V_RUNTIME         NUMBER;                      --运行次数  
  22.   V_NUM             NUMBER;                      --循环变量  
  23.   
  24. BEGIN  
  25.   --程序开始  
  26.   DBMS_OUTPUT.PUT_LINE('PRC_WAP_ACTIVEUSERS_BATCH BEGIN : ' ||  
  27.                        TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS'));  
  28.   RET_CODE    := '0000';  
  29.   V_COMMITNUM := 1000000;                        --一百万提交一次  
  30.   
  31.   BEGIN  
  32.     
  33.     SELECT TO_CHAR(ADD_MONTHS(LAST_DAY(SYSDATE), -1), 'YYYYMM')  
  34.       INTO V_LAST_MONTH  
  35.       FROM DUAL;  
  36.     
  37.     SELECT TO_CHAR(ADD_MONTHS(LAST_DAY(SYSDATE) + 1, -2), 'YYYYMMDD')  
  38.       INTO V_FIRST_DAY_MONTH  
  39.       FROM DUAL;  
  40.     
  41.     SELECT TO_CHAR(ADD_MONTHS(LAST_DAY(SYSDATE), -1), 'YYYYMMDD')  
  42.       INTO V_END_DAY_MONTH  
  43.       FROM DUAL;  
  44.     
  45.     EXEC_SQL := 'SELECT COUNT(1) FROM(SELECT TEL AS PHONE_NUM, COUNT(T.TEL)   
  46.                  AS LOGIN_TIMES,''' || V_LAST_MONTH ||  
  47.                 ''AS LOGIN_MONTH  
  48.                  FROM TEMP_BOSS_BIP1A021 T  
  49.                  WHERE T.DAY_ID BETWEEN ''' ||  
  50.                 V_FIRST_DAY_MONTH || ''' AND ''' || V_END_DAY_MONTH ||  
  51.                 ''' HAVING COUNT(T.TEL) >= 2 GROUP BY T.TEL)';  
  52.     
  53.     EXECUTE IMMEDIATE EXEC_SQL INTO V_TOTALNUM;    --获取总记录数   
  54.     
  55.     --计算循环次数  
  56.     V_RUNTIME := V_TOTALNUM MOD V_COMMITNUM;  
  57.     
  58.     IF (V_RUNTIME > 0) THEN  
  59.       V_RUNTIME := 1 + TRUNC(V_TOTALNUM / V_COMMITNUM);  
  60.     END IF;  
  61.     IF (V_RUNTIME = 0) THEN  
  62.       V_RUNTIME := 0 + TRUNC(V_TOTALNUM / V_COMMITNUM);  
  63.     END IF;  
  64.     
  65.     --分批提交数据库  
  66.     FOR V_NUM IN 1 .. V_RUNTIME LOOP  
  67.       
  68.       EXEC_SQL := 'INSERT INTO ' || V_TABLE || '   
  69.         (PHONE_NUM, LOGIN_TIMES, LOGIN_MONTH, ROWNUMS)  
  70.         SELECT PHONE_NUM, LOGIN_TIMES, LOGIN_MONTH, ROWNUM AS ROWNUMS  
  71.           FROM (SELECT TEL AS PHONE_NUM,  
  72.                        COUNT(T.TEL) AS LOGIN_TIMES,''' ||  
  73.                   V_LAST_MONTH ||  
  74.                   ''AS LOGIN_MONTH  
  75.                   FROM TEMP_BOSS_BIP1A021 T  
  76.                  WHERE T.DAY_ID BETWEEN ''' ||  
  77.                   V_FIRST_DAY_MONTH || ''' AND ''' || V_END_DAY_MONTH ||  
  78.                   ''HAVING  
  79.                  COUNT(T.TEL) >= 2  
  80.                  GROUP BY T.TEL) WHERE ROWNUM>' ||  
  81.                   (V_NUM - 1) * V_COMMITNUM || ' AND ROWNUM <=' ||  
  82.                   V_NUM * V_COMMITNUM;  
  83.       
  84.       EXECUTE IMMEDIATE EXEC_SQL;  
  85.       COMMIT--提交  
  86.       
  87.     END LOOP;  
  88.     
  89.     DBMS_OUTPUT.PUT_LINE('PRC_WAP_ACTIVEUSERS_BATCH END: ' ||  
  90.                          TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS'));  
  91.   EXCEPTION  
  92.     WHEN OTHERS THEN  
  93.       BEGIN  
  94.         ROLLBACK;  
  95.         RET_CODE := '0001';  
  96.         RET_MSG  := '存储过程PRC_WAP_ACTIVEUSERS_BATCH执行错误!' || CHR(10) ||  
  97.                     '错误代码:' || SQLCODE || CHR(10) || '错误信息:' ||  
  98.                     SUBSTR(SQLERRM, 1, 128);  
  99.         GOTO TOEND;  
  100.       END;  
  101.   END;  
  102.   
  103.   --返回程序运作结果  
  104.   RETCODE := RET_CODE;  
  105.   <<TOEND>>  
  106.   IF (RET_CODE = '0000'THEN  
  107.     RET_MSG := '运行成功!';  
  108.     COMMIT;  
  109.   ELSE  
  110.     RET_MSG := '运行失败!' || RET_MSG;  
  111.   END IF;  
  112.   
  113.   DBMS_OUTPUT.PUT_LINE(RET_MSG);  
  114.   
  115.   DBMS_OUTPUT.PUT_LINE('END TIME : ' ||  
  116.                        TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS'));  
  117.   
  118. END PRC_WAP_ACTIVEUSERS_BATCH;  

三、

[sql] view plain copy
  1. CREATE OR REPLACE PROCEDURE PRC_BS_ASS_MODIFYRESULT  
  2.   
  3. (ASSESS_TIME IN VARCHAR2,       --时间  
  4.  OBJECT_ID   IN VARCHAR2,       --对象ID  
  5.  KPI_ID      IN VARCHAR2,       --指标ID  
  6.  MOD_DATA    IN VARCHAR2,       --修改后的数据  
  7.  O_INFO      OUT VARCHAR2       --返回执行信息  
  8.  ) AS  
  9.   
  10.   TYPE MYCURSOR IS REF CURSOR;  --定义游标类型  
  11.   CUR MYCURSOR;                 --定义游标  
  12.   TYPE CUR_DATA_TYPE IS RECORD  --定义游标数据类型  
  13.   (  
  14.     RESULT_ID    VARCHAR2(20),  --系统(人工)结果ID  
  15.     RULE_CONTENT VARCHAR2(2000) --解析后的规则  
  16.     );  
  17.   VRECORD CUR_DATA_TYPE;        --定义数据类型  
  18.   
  19.   RET_CODE VARCHAR2(6);         --错误信息代码  
  20.   RET_MSG  VARCHAR2(200);       --错误信息  
  21.   EXEC_SQL VARCHAR2(1500);      --SQL语句  
  22. BEGIN  
  23.   
  24.   --程序开始  
  25.   DBMS_OUTPUT.PUT_LINE('START TIME : ' ||  
  26.                        TO_CHAR(SYSDATE, 'yyyy-mm-dd hh24:mi:ss'));  
  27.   RET_CODE := '000000';  
  28.   
  29.   --修改数据明细  
  30.   BEGIN  
  31.     DBMS_OUTPUT.PUT_LINE('修改数据明细 BEGIN: ' ||  
  32.                          TO_CHAR(SYSDATE, 'yyyy-mm-dd hh24:mi:ss'));  
  33.   
  34.     EXEC_SQL := 'UPDATE BS_ASS_RESULTLIST_INFO  
  35.                       SET KPI_VAL = ' || MOD_DATA || '  
  36.                     WHERE ASSESS_TIME = ''' || ASSESS_TIME || '''  
  37.                       AND KPI_ID = ''' || KPI_ID || '''  
  38.                       AND OBJECT_ID = ''' || OBJECT_ID || '''';  
  39.     EXECUTE IMMEDIATE EXEC_SQL;  
  40.   
  41.     DBMS_OUTPUT.PUT_LINE('修改数据明细 END: ' ||  
  42.                          TO_CHAR(SYSDATE, 'yyyy-mm-dd hh24:mi:ss'));  
  43.   EXCEPTION  
  44.     WHEN OTHERS THEN  
  45.       BEGIN  
  46.         RET_CODE := '000001';  
  47.         RET_MSG  := '修改数据明细时信息错误!' || CHR(10) || '错误代码:' || SQLCODE ||  
  48.                     CHR(10) || '错误信息:' || SUBSTR(SQLERRM, 1, 128);  
  49.         GOTO TOEND;  
  50.       END;  
  51.   END;  
  52.   
  53.   --借助动态游标,计算修改数据明细项  
  54.   BEGIN  
  55.     DBMS_OUTPUT.PUT_LINE('计算修改明细 BEGIN: ' ||  
  56.                          TO_CHAR(SYSDATE, 'yyyy-mm-dd hh24:mi:ss'));  
  57.   
  58.     EXEC_SQL := 'SELECT RESULT_ID , RULE_CONTENT  
  59.                    FROM BS_ASS_RESULTLIST_INFO  
  60.                   WHERE ASSESS_TIME = ''' || ASSESS_TIME || '''  
  61.                     AND KPI_ID = ''' || KPI_ID || '''  
  62.                     AND OBJECT_ID = ''' || OBJECT_ID || '''';  
  63.     OPEN CUR FOR EXEC_SQL;  
  64.     LOOP  
  65.       FETCH CUR  
  66.         INTO VRECORD;  
  67.       EXIT WHEN CUR%NOTFOUND;  
  68.       EXEC_SQL := 'UPDATE BS_ASS_RESULTLIST_INFO  
  69.                    SET (ASS_MARK,  
  70.                         FINAL_MARK) = (SELECT (' ||  
  71.                   VRECORD.RULE_CONTENT || ') * A.KPI_COEFFICIENT,(' ||  
  72.                   VRECORD.RULE_CONTENT || ') * A.KPI_COEFFICIENT * A.REFER_COEFFICIENT  
  73.                         FROM BS_ASS_RESULTLIST_INFO A  
  74.                        WHERE A.RESULT_ID = ''' || VRECORD.RESULT_ID || ''')  
  75.                   WHERE RESULT_ID = ''' || VRECORD.RESULT_ID || '''';  
  76.       EXECUTE IMMEDIATE EXEC_SQL;  
  77.     END LOOP;  
  78.   
  79.     DBMS_OUTPUT.PUT_LINE('计算修改明细 END: ' ||  
  80.                          TO_CHAR(SYSDATE, 'yyyy-mm-dd hh24:mi:ss'));  
  81.   EXCEPTION  
  82.     WHEN OTHERS THEN  
  83.       BEGIN  
  84.         RET_CODE := '000002';  
  85.         RET_MSG  := '计算修改明细时信息错误!' || CHR(10) || '错误代码:' || SQLCODE ||  
  86.                     CHR(10) || '错误信息:' || SUBSTR(SQLERRM, 1, 128);  
  87.         GOTO TOEND;  
  88.       END;  
  89.   END;  
  90.   
  91.   --返回程序运行结果  
  92.   <<TOEND>>  
  93.   IF (RET_CODE = '000000'THEN  
  94.     RET_MSG := '运行成功!';  
  95.     O_INFO  := 'SUCCESS';  
  96.     COMMIT;  
  97.   ELSE  
  98.     RET_MSG := '运行失败!' || RET_MSG;  
  99.     O_INFO  := 'FALSE';  
  100.     ROLLBACK;  
  101.   END IF;  
  102.   
  103.   DBMS_OUTPUT.PUT_LINE(RET_MSG);  
  104.   DBMS_OUTPUT.PUT_LINE('END TIME : ' ||  
  105.                        TO_CHAR(SYSDATE, 'yyyy-mm-dd hh24:mi:ss'));  
  106.   
  107. END PRC_BS_ASS_MODIFYRESULT;
0 0
原创粉丝点击