1. 程式人生 > >ORACLE 儲存過程動態遊標例子

ORACLE 儲存過程動態遊標例子

一、

CREATE OR REPLACE PROCEDURE PRC_WAP_ACTIVEUSERS(RETCODE OUT VARCHAR2)
/***********************************************************
  * 功能:WAP指標--活躍使用者統計(分批提交)                     
  * 引數:RETCODE(返回編碼:0000成功)                        
  * 作者:
  * 建立時間:2013-01-16                                     
  * 版本:1.0                                                 
  * 修改人:                                                  
  * 修改時間:                                                
  **********************************************************/
 IS
  RET_CODE VARCHAR2(6);                 --錯誤資訊程式碼
  RET_MSG  VARCHAR2(200);               --錯誤資訊
  V_LAST_MONTH      VARCHAR2(8);        --上個月份
  V_FIRST_DAY_MONTH VARCHAR2(10);       --上個月第一天
  V_END_DAY_MONTH   VARCHAR2(10);       --上個月第二天
  V_COUNT           NUMBER;             --計數變數
  V_COMMITNUM CONSTANT NUMBER :=1000000;--一次提交記錄數(預設一百萬)

BEGIN
  --程式開始
  DBMS_OUTPUT.PUT_LINE('PRC_WAP_ACTIVEUSERS BEGIN : ' ||
                       TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS'));
                       
  RET_CODE := '0000';                   --返回編碼初始化
  V_COUNT  := 0;                        --計數器初始化
  --申明遊標
  DECLARE
    TYPE CUR_DATA_TYPE IS RECORD        --定義動態遊標資料型別
    (
      PHONE_NUM   VARCHAR2(20),         --電話號碼
      LOGIN_TIMES VARCHAR2(2000));      --訪問次數
  
    VRECORD CUR_DATA_TYPE;              --定義資料型別
  BEGIN
  
    SELECT TO_CHAR(ADD_MONTHS(LAST_DAY(SYSDATE), -1), 'YYYYMM')
      INTO V_LAST_MONTH
      FROM DUAL;
  
    SELECT TO_CHAR(ADD_MONTHS(LAST_DAY(SYSDATE) + 1, -2), 'YYYYMMDD')
      INTO V_FIRST_DAY_MONTH
      FROM DUAL;
  
    SELECT TO_CHAR(ADD_MONTHS(LAST_DAY(SYSDATE), -1), 'YYYYMMDD')
      INTO V_END_DAY_MONTH
      FROM DUAL;
  
    FOR VRECORD IN (SELECT TEL AS PHONE_NUM, COUNT(T.TEL) AS LOGIN_TIMES
                      FROM TEMP_BOSS_BIP1A021 T
                     WHERE T.DAY_ID BETWEEN V_FIRST_DAY_MONTH AND
                           V_END_DAY_MONTH HAVING COUNT(T.TEL) >= 2
                     GROUP BY T.TEL) LOOP
    
      INSERT INTO T_BIP1A021
        (PHONE_NUM, LOGIN_TIMES, LOGIN_MONTH)
      VALUES
        (VRECORD.PHONE_NUM, VRECORD.LOGIN_TIMES, V_LAST_MONTH);
    
      IF ((MOD(V_COUNT, V_COMMITNUM)) = 0) THEN 
        COMMIT;                         --求餘:一百萬提交一次
      END IF;
      
      V_COUNT := V_COUNT + 1;
    
    END LOOP;
  
    COMMIT;
  
    DBMS_OUTPUT.PUT_LINE('PRC_WAP_ACTIVEUSERS END: ' ||
                         TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS'));
  EXCEPTION
    WHEN OTHERS THEN
      BEGIN
        ROLLBACK;
        RET_CODE := '0001';
        RET_MSG  := '儲存過程 PRC_WAP_ACTIVEUSERS 執行錯誤!' || CHR(10) ||
                    '錯誤程式碼:' || SQLCODE || CHR(10) || '錯誤資訊:' ||
                    SUBSTR(SQLERRM, 1, 128);
        GOTO TOEND;
      END;
  END;

  --返回程式運作結果
  <<TOEND>>
  RETCODE := RET_CODE;
  IF (RET_CODE = '0000') THEN
    RET_MSG := '執行成功!';
    COMMIT;
  ELSE
    RET_MSG := '執行失敗!' || RET_MSG;
    ROLLBACK;
  END IF;

  DBMS_OUTPUT.PUT_LINE(RET_MSG);

  DBMS_OUTPUT.PUT_LINE('END TIME : ' ||
                       TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS'));

END PRC_WAP_ACTIVEUSERS;

二、

CREATE OR REPLACE PROCEDURE PRC_WAP_ACTIVEUSERS_BATCH(RETCODE OUT VARCHAR2,
                                                      V_TABLE IN VARCHAR2)
/***********************************************************
  * 功能:WAP指標--活躍使用者統計(分批提交)                *
  * 引數:RETCODE(返回編碼),V_TABLE(插入表)           *
  * 作者:ZENGMS                                           *
  * 建立時間:2013-01-16                                   *
  * 版本:1.0                                              *
  * 修改人:                                               *
  * 修改時間:                                             *
  **********************************************************/
 IS
  RET_CODE          VARCHAR2(6);                 --錯誤資訊程式碼
  RET_MSG           VARCHAR2(200);               --錯誤資訊
  EXEC_SQL          VARCHAR2(2000);              --SQL語句
  V_LAST_MONTH      VARCHAR2(8);                 --上個月份
  V_FIRST_DAY_MONTH VARCHAR2(10);                --上個月第一天
  V_END_DAY_MONTH   VARCHAR2(10);                --上個月第二天
  V_TOTALNUM        NUMBER;                      --總記錄數
  V_COMMITNUM       NUMBER;                      --一次提交數量
  V_RUNTIME         NUMBER;                      --執行次數
  V_NUM             NUMBER;                      --迴圈變數

BEGIN
  --程式開始
  DBMS_OUTPUT.PUT_LINE('PRC_WAP_ACTIVEUSERS_BATCH BEGIN : ' ||
                       TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS'));
  RET_CODE    := '0000';
  V_COMMITNUM := 1000000;                        --一百萬提交一次

  BEGIN
  
    SELECT TO_CHAR(ADD_MONTHS(LAST_DAY(SYSDATE), -1), 'YYYYMM')
      INTO V_LAST_MONTH
      FROM DUAL;
  
    SELECT TO_CHAR(ADD_MONTHS(LAST_DAY(SYSDATE) + 1, -2), 'YYYYMMDD')
      INTO V_FIRST_DAY_MONTH
      FROM DUAL;
  
    SELECT TO_CHAR(ADD_MONTHS(LAST_DAY(SYSDATE), -1), 'YYYYMMDD')
      INTO V_END_DAY_MONTH
      FROM DUAL;
  
    EXEC_SQL := 'SELECT COUNT(1) FROM(SELECT TEL AS PHONE_NUM, COUNT(T.TEL) 
                 AS LOGIN_TIMES,''' || V_LAST_MONTH ||
                ''' AS LOGIN_MONTH
                 FROM TEMP_BOSS_BIP1A021 T
                 WHERE T.DAY_ID BETWEEN ''' ||
                V_FIRST_DAY_MONTH || ''' AND ''' || V_END_DAY_MONTH ||
                ''' HAVING COUNT(T.TEL) >= 2 GROUP BY T.TEL)';
  
    EXECUTE IMMEDIATE EXEC_SQL INTO V_TOTALNUM;    --獲取總記錄數 
  
    --計算迴圈次數
    V_RUNTIME := V_TOTALNUM MOD V_COMMITNUM;
  
    IF (V_RUNTIME > 0) THEN
      V_RUNTIME := 1 + TRUNC(V_TOTALNUM / V_COMMITNUM);
    END IF;
    IF (V_RUNTIME = 0) THEN
      V_RUNTIME := 0 + TRUNC(V_TOTALNUM / V_COMMITNUM);
    END IF;
  
    --分批提交資料庫
    FOR V_NUM IN 1 .. V_RUNTIME LOOP
    
      EXEC_SQL := 'INSERT INTO ' || V_TABLE || ' 
        (PHONE_NUM, LOGIN_TIMES, LOGIN_MONTH, ROWNUMS)
        SELECT PHONE_NUM, LOGIN_TIMES, LOGIN_MONTH, ROWNUM AS ROWNUMS
          FROM (SELECT TEL AS PHONE_NUM,
                       COUNT(T.TEL) AS LOGIN_TIMES,''' ||
                  V_LAST_MONTH ||
                  ''' AS LOGIN_MONTH
                  FROM TEMP_BOSS_BIP1A021 T
                 WHERE T.DAY_ID BETWEEN ''' ||
                  V_FIRST_DAY_MONTH || ''' AND ''' || V_END_DAY_MONTH ||
                  ''' HAVING
                 COUNT(T.TEL) >= 2
                 GROUP BY T.TEL) WHERE ROWNUM>' ||
                  (V_NUM - 1) * V_COMMITNUM || ' AND ROWNUM <=' ||
                  V_NUM * V_COMMITNUM;
    
      EXECUTE IMMEDIATE EXEC_SQL;
      COMMIT; --提交
    
    END LOOP;
  
    DBMS_OUTPUT.PUT_LINE('PRC_WAP_ACTIVEUSERS_BATCH END: ' ||
                         TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS'));
  EXCEPTION
    WHEN OTHERS THEN
      BEGIN
        ROLLBACK;
        RET_CODE := '0001';
        RET_MSG  := '儲存過程PRC_WAP_ACTIVEUSERS_BATCH執行錯誤!' || CHR(10) ||
                    '錯誤程式碼:' || SQLCODE || CHR(10) || '錯誤資訊:' ||
                    SUBSTR(SQLERRM, 1, 128);
        GOTO TOEND;
      END;
  END;

  --返回程式運作結果
  RETCODE := RET_CODE;
  <<TOEND>>
  IF (RET_CODE = '0000') THEN
    RET_MSG := '執行成功!';
    COMMIT;
  ELSE
    RET_MSG := '執行失敗!' || RET_MSG;
  END IF;

  DBMS_OUTPUT.PUT_LINE(RET_MSG);

  DBMS_OUTPUT.PUT_LINE('END TIME : ' ||
                       TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS'));

END PRC_WAP_ACTIVEUSERS_BATCH;

三、

CREATE OR REPLACE PROCEDURE PRC_BS_ASS_MODIFYRESULT

(ASSESS_TIME IN VARCHAR2,       --時間
 OBJECT_ID   IN VARCHAR2,       --物件ID
 KPI_ID      IN VARCHAR2,       --指標ID
 MOD_DATA    IN VARCHAR2,       --修改後的資料
 O_INFO      OUT VARCHAR2       --返回執行資訊
 ) AS

  TYPE MYCURSOR IS REF CURSOR;  --定義遊標型別
  CUR MYCURSOR;                 --定義遊標
  TYPE CUR_DATA_TYPE IS RECORD  --定義遊標資料型別
  (
    RESULT_ID    VARCHAR2(20),  --系統(人工)結果ID
    RULE_CONTENT VARCHAR2(2000) --解析後的規則
    );
  VRECORD CUR_DATA_TYPE;        --定義資料型別

  RET_CODE VARCHAR2(6);         --錯誤資訊程式碼
  RET_MSG  VARCHAR2(200);       --錯誤資訊
  EXEC_SQL VARCHAR2(1500);      --SQL語句
BEGIN

  --程式開始
  DBMS_OUTPUT.PUT_LINE('START TIME : ' ||
                       TO_CHAR(SYSDATE, 'yyyy-mm-dd hh24:mi:ss'));
  RET_CODE := '000000';

  --修改資料明細
  BEGIN
    DBMS_OUTPUT.PUT_LINE('修改資料明細 BEGIN: ' ||
                         TO_CHAR(SYSDATE, 'yyyy-mm-dd hh24:mi:ss'));

    EXEC_SQL := 'UPDATE BS_ASS_RESULTLIST_INFO
                      SET KPI_VAL = ' || MOD_DATA || '
                    WHERE ASSESS_TIME = ''' || ASSESS_TIME || '''
                      AND KPI_ID = ''' || KPI_ID || '''
                      AND OBJECT_ID = ''' || OBJECT_ID || '''';
    EXECUTE IMMEDIATE EXEC_SQL;

    DBMS_OUTPUT.PUT_LINE('修改資料明細 END: ' ||
                         TO_CHAR(SYSDATE, 'yyyy-mm-dd hh24:mi:ss'));
  EXCEPTION
    WHEN OTHERS THEN
      BEGIN
        RET_CODE := '000001';
        RET_MSG  := '修改資料明細時資訊錯誤!' || CHR(10) || '錯誤程式碼:' || SQLCODE ||
                    CHR(10) || '錯誤資訊:' || SUBSTR(SQLERRM, 1, 128);
        GOTO TOEND;
      END;
  END;

  --藉助動態遊標,計算修改資料明細項
  BEGIN
    DBMS_OUTPUT.PUT_LINE('計算修改明細 BEGIN: ' ||
                         TO_CHAR(SYSDATE, 'yyyy-mm-dd hh24:mi:ss'));

    EXEC_SQL := 'SELECT RESULT_ID , RULE_CONTENT
                   FROM BS_ASS_RESULTLIST_INFO
                  WHERE ASSESS_TIME = ''' || ASSESS_TIME || '''
                    AND KPI_ID = ''' || KPI_ID || '''
                    AND OBJECT_ID = ''' || OBJECT_ID || '''';
    OPEN CUR FOR EXEC_SQL;
    LOOP
      FETCH CUR
        INTO VRECORD;
      EXIT WHEN CUR%NOTFOUND;
      EXEC_SQL := 'UPDATE BS_ASS_RESULTLIST_INFO
                   SET (ASS_MARK,
                        FINAL_MARK) = (SELECT (' ||
                  VRECORD.RULE_CONTENT || ') * A.KPI_COEFFICIENT,(' ||
                  VRECORD.RULE_CONTENT || ') * A.KPI_COEFFICIENT * A.REFER_COEFFICIENT
                        FROM BS_ASS_RESULTLIST_INFO A
                       WHERE A.RESULT_ID = ''' || VRECORD.RESULT_ID || ''')
                  WHERE RESULT_ID = ''' || VRECORD.RESULT_ID || '''';
      EXECUTE IMMEDIATE EXEC_SQL;
    END LOOP;

    DBMS_OUTPUT.PUT_LINE('計算修改明細 END: ' ||
                         TO_CHAR(SYSDATE, 'yyyy-mm-dd hh24:mi:ss'));
  EXCEPTION
    WHEN OTHERS THEN
      BEGIN
        RET_CODE := '000002';
        RET_MSG  := '計算修改明細時資訊錯誤!' || CHR(10) || '錯誤程式碼:' || SQLCODE ||
                    CHR(10) || '錯誤資訊:' || SUBSTR(SQLERRM, 1, 128);
        GOTO TOEND;
      END;
  END;

  --返回程式執行結果
  <<TOEND>>
  IF (RET_CODE = '000000') THEN
    RET_MSG := '執行成功!';
    O_INFO  := 'SUCCESS';
    COMMIT;
  ELSE
    RET_MSG := '執行失敗!' || RET_MSG;
    O_INFO  := 'FALSE';
    ROLLBACK;
  END IF;

  DBMS_OUTPUT.PUT_LINE(RET_MSG);
  DBMS_OUTPUT.PUT_LINE('END TIME : ' ||
                       TO_CHAR(SYSDATE, 'yyyy-mm-dd hh24:mi:ss'));

END PRC_BS_ASS_MODIFYRESULT;

相關推薦

ORACLE 儲存過程動態遊標例子

一、 CREATE OR REPLACE PROCEDURE PRC_WAP_ACTIVEUSERS(RETCODE OUT VARCHAR2) /***********************************************************

Oracle儲存過程以及遊標

一.儲存過程 1、儲存過程定義 所謂儲存過程(Stored Procedure),就是一組用於完成特定資料庫功能的SQL語句集,該SQL語句集經過 編譯後儲存在資料庫系統中。在使用時候,使用者通過指定已經定義的儲存過程名字並給出相應的儲存過程引數 來呼叫並執行它,從而完成一個或一系列的資料庫

Oracle 儲存過程小結 遊標 ,隨機生成UUID(32位)

    業務需求:            今天領導要求後天批量插入修改資料,將A表中的資料一條條的插入到B表中,中間還夾雜這業務邏輯。  技術需求:      

Oracle儲存過程遊標、函式

SQL99是什麼 (1)是操作所有關係型資料庫的規則 (2)是第四代語言 (3)是一種結構化查詢語言 (4)只需發出合法合理的命令,就有對應的結果顯示 SQL的特點 (1)互動性強,非過程化 (2)資料庫操縱能力強,只需傳送命令,無需關注如何實現 (3)多表操作時,自動導航簡單,例如

oracle儲存過程,動態sql

CREATE OR REPLACE PROCEDURE "TUBEMNG"."RE" (one OUT INTEGER,two OUT INTEGER,three OUT INTEGER,four OUT INTEGER,ptype IN VARCHAR2,D

ORACLE 儲存過程動態建立檢視

create or replace procedure "CREAR_PF_VIEW" is    pragma AUTONOMOUS_TRANSACTION;    cursor cur is  --定義遊標    SELECT SPBLX FROM YDS_SHBPDY

mybatis呼叫oracle儲存過程返回遊標 讀取到java的List

mapper: <select id="testP" statementType="CALLABLE" > {call P_TEST(#{v_cursor, mode=OUT, jdbcType=CURSOR})} </select> ja

Oracle儲存過程使用動態遊標

spool F:/dbtest12.log; set timing on; set serveroutput on; declare --定義遊標:獲取所有表 CURSOR c_allTables IS select t.OWNER,t.TABLE_NAME from

oracle 儲存過程(其中使用了遊標例子

create or replace procedure PRC_analysis_alert is ---獲得“預警研判分析-預警資訊統計”結果 的遊標 cursor CRS_AlERT i

oracle 儲存過程 例項 迴圈 給查詢賦值 遊標取值

CREATE OR REPLACE PROCEDURE p_updete_gs is     --僅供參考   i_jdid varchar(32);   i_ryid varchar(32);   cursor cur is --

Oracle 儲存過程 \ 遊標簡單定義和使用

-- Created on 2018/10/12 by 32580 declare -- 定義變數 變數賦值方式為: 變數名 := 值 i INTEGER ; sqls varchar2(500); user_id varchar2(36); l

ORACLE 儲存過程遊標返回多行

1、過程主體 --儲存過程迴圈 ,SELECT INTO 是隱式遊標只能返回一行 CREATE OR REPLACE PROCEDURE P_LOOP_PR ( P_TIME NUMBER) IS A_OVER NUMBER; A_NAME VARCHAR2(20); BE

Oracle 儲存過程 遍歷 遊標 資料集 效率比較

  Oracle中游標使用效率比較 2013年09月26日 21:09:08 進擊的胖蛇 閱讀數:4380 鳴謝:http://blog.163.com/[email protected]/blog/static/34469732201272534

mybatis 呼叫oracle儲存過程,傳參、返回遊標的值獲取--示例

1,dao層程式碼 Integer currentlq_fsx = getSqlSession().selectOne("lqMapper.maxscore"); Map<String,Object> map = new HashMap<String,O

oracle執行儲存過程返回遊標cursor

create or replace procedure TEST(s varchar2, r_result out sys_refcursor) is   --作者:lml   --功能:根據tokenid查詢放行指令   --詳情:   --1.返回放行指令   --時間

動態sql執行oracle儲存過程

     1、呼叫procedure:          v_sql  := 'Begin pkg_name.procedure_name(:in_v1, :in_v2, :out_v1, :out_v2); End;' ;           EXECUTE IMMEDI

oracle儲存過程----遊標(cursor)的學習

oracle儲存過程—-遊標(cursor)的學習   今天又學了一個新的概念Cursor ,即遊標。   接上一篇,oracle儲存過程—-儲存過程執行簡單的增刪改查sql ,上一篇中,寫到儲存過程的查詢sql ,當時在寫到查詢的時候,忽然不知道怎麼對查詢

Oracle儲存過程,遊標使用

Oracle儲存過程: 語法: CREATE [OR REPLACE] PROCEDURE procedure_name (arg1 [mode1] datatype1,arg2 [mode2] datatype2,...) IS [AS] PL/SQL BLOCK; mo

ORACLE定時任務呼叫儲存過程動態為表新增分割槽

1、建立需要自動分割槽的表 CREATE TABLE TEST(M DATA) PARTITION BY RANGE(M) ( PARTITION TEST_PAR_99991212 VALUES LESS THAN(TO_DATE('12-12-9999','DD-MM-

oracle 儲存過程 遊標巢狀

這是一段將裝置的GPS資料的工作小時數進行統計的儲存過程,首先通過遊標取出所有裝置資訊,然後對每一臺裝置進行工作小時數統計,其中用到了遊標巢狀 CREATE OR REPLACE PROCEDURE CMTOOLS.proc_statistics_workhour IS