oracle中的存儲過程(實例一)


引子

這是公司測試環境的老問題了。

業務系統的生產環境,有專人配置基礎數據,有運維人員管理。而測試環境沒有人員維護,基礎配置信息數據過期后,導致系統無法正常使用。

以往的解決辦法:

1. 聯系外圍管理系統(銷售管理系統)負責人協助配置。

2. 配置信息,審核通過后同步到核心,確認后可以使用。

下面進入正題,存過實現遷移生產環境數據到測試環境

1. 解決方案(版本1.1)

工具:數據庫存過

思路:需要導入數據的表放在數據庫中。遍歷這些表,在遍歷過程中先刪除表中符合條件的數據,然后將生產環境符合條件的數據遷入到當前環境中

   /*****************************************************************************\
   * Name: P_IMPORT_CHA_DATA
   * PROCEDURE: 導生產環境基礎數據(代理人信息)
   * Paramater: IC_C_CHA_CDE 代理人代碼
   * Programmer: lyt
   * Date: 2019/10/12
   * Update:
   * 需導入表配置:T_IMPORT_TABLE WHERE C_MARK = '2';
   * 維護dbquery中間庫表結構:SELECT 'CREATE TABLE T_' || C_TABLE || ' AS SELECT * FROM ZSSYS.' || C_TABLE || ' WHERE ROWNUM = 0;',A.* FROM T_IMPORT_TABLE A;
   * 如果手續費打包時提示:算稅平台找不到該代理人,需聯系算稅平台(沈一棟)邵先路,將算稅生產環境信息同步到對應環境
  \*****************************************************************************/
 
  PROCEDURE P_IMPORT_CHA_DATA(IC_C_CHA_CDE VARCHAR2) AS
    LB_SQL      CLOB;
    LB_COLS     CLOB;
    LB_COND     CLOB;
    LN_ROWS     NUMBER;
    CURSOR CUR_TABLE IS
      SELECT * FROM T_IMPORT_TABLE WHERE C_MARK = '2';
  BEGIN     
    FOR LR_TABLE IN CUR_TABLE LOOP
    
      SELECT WM_CONCAT(COLUMN_NAME)
        INTO LB_COLS
        FROM USER_TAB_COLS@LINK_CORE
       WHERE TABLE_NAME = 'T_' || UPPER(LR_TABLE.C_TABLE)
       ORDER BY COLUMN_ID;
    
      LB_COND := ' WHERE ';
      
      IF (UPPER(LR_TABLE.C_TABLE) = 'WEB_CUS_COM_ACCT') THEN
        LB_COND := LB_COND || 'C_REL_CDE ';
      ELSIF (UPPER(LR_TABLE.C_TABLE) = 'WEB_CUS_CONFER') THEN
        LB_COND := LB_COND || 'C_CLNT_CDE ';
      ELSIF (UPPER(LR_TABLE.C_TABLE) = 'WEB_CUS_CONFER_DTL' OR UPPER(LR_TABLE.C_TABLE) = 'WEB_AUTH_CONFER') THEN
        LB_COND := LB_COND || 'C_AGT_AGR_NO IN (SELECT C_AGT_AGR_NO FROM ZSSYS.WEB_CUS_CONFER  WHERE C_CLNT_CDE';
      ELSIF (UPPER(LR_TABLE.C_TABLE) = 'WEB_ORG_SALES') THEN
        LB_COND := LB_COND || 'C_SLS_CDE IN(SELECT C_SLS_CDE FROM ZSSYS.WEB_CUS_CHA WHERE C_CHA_CDE';
      ELSE
        LB_COND := LB_COND || 'C_CHA_CDE ';
      END IF;
              
      IF (UPPER(LR_TABLE.C_TABLE) = 'WEB_CUS_CONFER_DTL' OR UPPER(LR_TABLE.C_TABLE) = 'WEB_AUTH_CONFER' OR UPPER(LR_TABLE.C_TABLE) = 'WEB_ORG_SALES') THEN
        LB_COND := LB_COND || '= ''' || IC_C_CHA_CDE || ''')';
      ELSE
        LB_COND := LB_COND || '= ''' || IC_C_CHA_CDE || '''';
      END IF;
      
      LB_SQL := 'DELETE FROM ZSSYS.' || LR_TABLE.C_TABLE || LB_COND;
      
      EXECUTE IMMEDIATE LB_SQL;

      LB_SQL := 'INSERT INTO ZSSYS.' || LR_TABLE.C_TABLE || '(' || LB_COLS ||
      ')  SELECT ' || LB_COLS || ' FROM ' || 'ZSSYS.' ||
                LR_TABLE.C_TABLE || '@LINK_CORE '|| LB_COND;
                
      EXECUTE IMMEDIATE LB_SQL;
    END IF;
    END LOOP;
    --COMMIT;
  END P_IMPORT_CHA_DATA;

涉及知識點

1.1  oracle 中的for循環

FOR LR_TABLE IN CUR_TABLE LOOP
END LOOP;

1.2  oracle 中的條件分支語句

IF () THEN
...;
ELSIF () THEN
...;
ELSE
...;
END IF;

1.3  存過中入參

1.4  游標 cursor

   Cursor類型包含三種: 隱式Cursor,顯式Cursor和Ref Cursor(動態Cursor)。 

1). 隱式游標:無需定義,Select /Update / Insert/Delete操作,就是隱式Cursor

2). 顯式游標:

cursor <cursor>[(<param_list>)]is <select_statement>;

3). 動態游標:

Type [Cursor type name] is ref cursor 

游標的屬性(4個)1.found  2.notfound  3.rowcount  4.isopen

2. 存過怎么調試?

2.1 如何打斷點

 2.2  如何調試

首先在左側列表中,選中對應存過,右鍵后點擊add debug informaintion(添加調試信息),然后在點Test,顯示如下頁面:

 最上面一排是debug相關按鍵區域,中間為代碼顯示部分,左下為變量值顯示區域(填寫變量名稱,執行過程中查看變量值)

2. 解決方案(版本1.2)

版本1.1存在的問題:由於部分表之間存在外鍵約束,導致刪除操作失敗。

解決思路:先反向遍歷表完成全部刪除操作(刪除符合條件的數據),在遍歷表完成插入操作,這里用到動態索引

  /*****************************************************************************\
   * Name: P_IMPORT_CHA_DATA
   * PROCEDURE: 導生產環境基礎數據(代理人信息)
   * Paramater: IC_C_CHA_CDE 代理人代碼
   * Programmer: lyt
   * Date: 2019/10/12
   * Update:
   * 需導入表配置:T_IMPORT_TABLE WHERE C_MARK = '2';
   * 如果手續費打包時提示:算稅平台找不到該代理人,需聯系算稅平台(沈一棟)邵先路,將算稅生產環境信息同步到對應環境
  \*****************************************************************************/

  PROCEDURE P_IMPORT_CHA_DATA(IC_C_CHA_CDE VARCHAR2) AS
    TYPE ref_cursor_type IS REF CURSOR;
    CUR_TABLE ref_cursor_type;
    LR_TABLE  ZSSYS.T_IMPORT_TABLE%ROWTYPE;
    LB_SQL    CLOB;
    LB_COLS   CLOB;
    LB_COND   CLOB;
  BEGIN
    FOR i IN 1 .. 2 LOOP
    
      IF (i = 1) THEN
        OPEN CUR_TABLE FOR
          SELECT *
            FROM ZSSYS.T_IMPORT_TABLE
           WHERE C_MARK = '2'
           ORDER BY C_TABLE_NO DESC;
      ELSE
        OPEN CUR_TABLE FOR
          SELECT *
            FROM ZSSYS.T_IMPORT_TABLE
           WHERE C_MARK = '2'
           ORDER BY C_TABLE_NO;
      END IF;
    
      LOOP
        FETCH CUR_TABLE
          INTO LR_TABLE;
        EXIT WHEN CUR_TABLE%NOTFOUND;
      
        SELECT WM_CONCAT(COLUMN_NAME)
          INTO LB_COLS
          FROM DBA_TAB_COLS@LINK_CORE
         WHERE TABLE_NAME = 'T_' || UPPER(LR_TABLE.C_TABLE)
           AND OWNER = 'ZSSYS'
         ORDER BY COLUMN_ID;
      
        LB_COND := ' WHERE ';
      
        IF (UPPER(LR_TABLE.C_TABLE) = 'WEB_CUS_COM_ACCT') THEN
          LB_COND := LB_COND || 'C_REL_CDE ';
        ELSIF (UPPER(LR_TABLE.C_TABLE) = 'WEB_CUS_CONFER') THEN
          LB_COND := LB_COND || 'C_CLNT_CDE ';
        ELSIF (UPPER(LR_TABLE.C_TABLE) = 'WEB_CUS_CONFER_DTL' OR
              UPPER(LR_TABLE.C_TABLE) = 'WEB_AUTH_CONFER') THEN
          LB_COND := LB_COND ||
                     'C_AGT_AGR_NO IN (SELECT C_AGT_AGR_NO FROM ZSSYS.WEB_CUS_CONFER@LINK_CORE  WHERE C_CLNT_CDE';
        ELSIF (UPPER(LR_TABLE.C_TABLE) = 'WEB_ORG_SALES') THEN
          LB_COND := LB_COND ||
                     'C_SLS_CDE IN(SELECT C_SLS_CDE FROM ZSSYS.WEB_CUS_CHA@LINK_CORE WHERE C_CHA_CDE';
        ELSE
          LB_COND := LB_COND || 'C_CHA_CDE ';
        END IF;
      
        IF (UPPER(LR_TABLE.C_TABLE) = 'WEB_CUS_CONFER_DTL' OR
           UPPER(LR_TABLE.C_TABLE) = 'WEB_AUTH_CONFER' OR
           UPPER(LR_TABLE.C_TABLE) = 'WEB_ORG_SALES') THEN
          LB_COND := LB_COND || '= ''' || IC_C_CHA_CDE || ''')';
        ELSE
          LB_COND := LB_COND || '= ''' || IC_C_CHA_CDE || '''';
        END IF;
      
        IF (i = 1) THEN
          LB_SQL := 'DELETE FROM ZSSYS.' || LR_TABLE.C_TABLE || LB_COND;
        ELSE
          LB_SQL := 'INSERT INTO ZSSYS.' || LR_TABLE.C_TABLE || '(' ||
                    LB_COLS || ')  SELECT ' || LB_COLS || ' FROM ' ||
                    'ZSSYS.' || LR_TABLE.C_TABLE || '@LINK_CORE' || LB_COND;
        END IF;
        EXECUTE IMMEDIATE LB_SQL;
      
      END LOOP;
      IF CUR_TABLE%ISOPEN THEN
        --close cursor
        CLOSE CUR_TABLE;
      END IF;
    END LOOP;
  END P_IMPORT_CHA_DATA;

 

  /*****************************************************************************\
   * Name: F_GET_LB_SQL
   * PROCEDURE: 導生產環境基礎數據(代理人信息)
   * Return: LB_COND 
   * Programmer: lyt
   * Date: 2019/10/24
   * Update:
  \*****************************************************************************/

  FUNCTION F_GET_LB_SQL(C_TABLE      IN VARCHAR2, --表名
                        IC_C_CHA_CDE IN VARCHAR2, --業務員編號
                        LB_COLS      IN OUT CLOB --表對應字段
                        ) RETURN CLOB IS
    LB_COND CLOB := '';
  BEGIN
    SELECT WM_CONCAT(COLUMN_NAME)
      INTO LB_COLS
      FROM DBA_TAB_COLS@LINK_CORE
     WHERE TABLE_NAME = UPPER(C_TABLE)
       AND OWNER = 'ZSSYS'
     ORDER BY COLUMN_ID;
  
    LB_COND := ' WHERE ';
    IF (UPPER(C_TABLE) = 'WEB_CUS_COM_ACCT') THEN
      LB_COND := LB_COND || 'C_REL_CDE ';
    ELSIF (UPPER(C_TABLE) = 'WEB_CUS_CONFER') THEN
      LB_COND := LB_COND || 'C_CLNT_CDE ';
    ELSIF (UPPER(C_TABLE) = 'WEB_CUS_CONFER_DTL' OR
          UPPER(C_TABLE) = 'WEB_AUTH_CONFER') THEN
      LB_COND := LB_COND ||
                 'C_AGT_AGR_NO IN (SELECT C_AGT_AGR_NO FROM ZSSYS.WEB_CUS_CONFER@LINK_CORE  WHERE C_CLNT_CDE';
    ELSIF (UPPER(C_TABLE) = 'WEB_ORG_SALES') THEN
      LB_COND := LB_COND ||
                 'C_SLS_CDE IN(SELECT C_SLS_CDE FROM ZSSYS.WEB_CUS_CHA@LINK_CORE WHERE C_CHA_CDE';
    ELSE
      LB_COND := LB_COND || 'C_CHA_CDE ';
    END IF;
  
    IF (UPPER(C_TABLE) = 'WEB_CUS_CONFER_DTL' OR
       UPPER(C_TABLE) = 'WEB_AUTH_CONFER' OR
       UPPER(C_TABLE) = 'WEB_ORG_SALES') THEN
      LB_COND := LB_COND || '= ''' || IC_C_CHA_CDE || ''')';
    ELSE
      LB_COND := LB_COND || '= ''' || IC_C_CHA_CDE || '''';
    END IF;
    RETURN LB_COND;
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      dbms_output.put_line('表:' || C_TABLE || '找不到');
  END F_GET_LB_SQL;
  /*****************************************************************************\
   * Name: P_IMPORT_CHA_DATA2
   * PROCEDURE: 導生產環境基礎數據(代理人信息)
   * Paramater: IC_C_CHA_CDE 代理人代碼
   * Programmer: lyt
   * Date: 2019/10/24
   * Update:
   * 需導入表配置:T_IMPORT_TABLE WHERE C_MARK = '2';
   * 如果手續費打包時提示:算稅平台找不到該代理人,需聯系算稅平台(沈一棟)邵先路,將算稅生產環境信息同步到對應環境
  \*****************************************************************************/

  PROCEDURE P_IMPORT_CHA_DATA2(IC_C_CHA_CDE VARCHAR2) AS
    TYPE ref_cursor_type IS REF CURSOR;
    CUR_TABLE ref_cursor_type;
    LR_TABLE  ZSSYS.T_IMPORT_TABLE%ROWTYPE;
    LB_SQL    CLOB;
    LB_COLS   CLOB;
    LB_COND   CLOB;
  BEGIN
    FOR i IN 1 .. 2 LOOP
      --刪除已有數據
      IF (i = 1) THEN
        OPEN CUR_TABLE FOR
          SELECT *
            FROM ZSSYS.T_IMPORT_TABLE
           WHERE C_MARK = '2'
           ORDER BY C_TABLE_NO DESC;
        LOOP
          FETCH CUR_TABLE
            INTO LR_TABLE;
          EXIT WHEN CUR_TABLE%NOTFOUND;
          LB_SQL := 'DELETE FROM ZSSYS.' || LR_TABLE.C_TABLE ||
                    F_GET_LB_SQL(LR_TABLE.C_TABLE, IC_C_CHA_CDE, LB_COLS);
          EXECUTE IMMEDIATE LB_SQL;
        END LOOP;
      ELSE
       --插入數據
        OPEN CUR_TABLE FOR
          SELECT *
            FROM ZSSYS.T_IMPORT_TABLE
           WHERE C_MARK = '2'
           ORDER BY C_TABLE_NO;
        LOOP
          FETCH CUR_TABLE
            INTO LR_TABLE;
          EXIT WHEN CUR_TABLE%NOTFOUND;
          LB_COND := F_GET_LB_SQL(LR_TABLE.C_TABLE, IC_C_CHA_CDE, LB_COLS);
          LB_SQL  := 'INSERT INTO ZSSYS.' || LR_TABLE.C_TABLE || '(' ||
                     LB_COLS || ')  SELECT ' || LB_COLS || ' FROM ' ||
                     'ZSSYS.' || LR_TABLE.C_TABLE || '@LINK_CORE' ||
                     LB_COND;
          EXECUTE IMMEDIATE LB_SQL;
        END LOOP;
      END IF;
    
      IF CUR_TABLE%ISOPEN THEN
        --close cursor
        CLOSE CUR_TABLE;
      END IF;
    END LOOP;
  END P_IMPORT_CHA_DATA2;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM