2017-04-17 55 views
0

我是Postgres的新手。我們正在將Oracle數據庫遷移到Postgres。在Oracle中,我們使用了很多軟件包。根據我的理解,Postgres中沒有類似Oracle的功能包。我只是試圖找到一些方法來 遷移Oracle包到Postgres。在Oracle軟件包中,全局變量就在那裏。軟件包轉換 - Oracle到PostgreSQL遷移

請讓我知道你對此的評論 - (這是爲了創建一個名爲NP_AC015_FETCH的軟件包)。

 create or replace package NP_AC015_FETCH is 

     function FUNC_GET_DATA(P_OUT_CUR out SYS_REFCURSOR) return varchar2; 
     function FUNC_GET_DATA_AUTO(P_OUT_CUR out SYS_REFCURSOR) return varchar2; 

     --Added 2006/12/07 - start 
     PV_LOG_START_MODE constant pls_integer := 0; 
     PV_LOG_RUNNING_MODE constant pls_integer := 1; 
     PV_LOG_CLOSE_MODE constant pls_integer := 2; 
     PV_LOG_ERR_CODE constant pls_integer := -20001; 

    procedure PROC_LOG(P_MSG in VARCHAR2, P_MODE in pls_integer default PV_LOG_RUNNING_MODE); 

    end NP_AC015_FETCH; 
    /

    create or replace package body NP_AC015_FETCH is 

     --Log file 
     GM_LOG_FILE UTL_FILE.FILE_TYPE; 

     --String and SQL Keyword 
     GM_Q constant CHAR := ''''; 
     GM_L constant CHAR := CHR(10); 
     GM_T constant CHAR := CHR(9); 

     --alias name 
     GM_A_HKNSMK constant CHAR(8) := '保険種目'; 
     GM_A_HKNSYR constant CHAR(8) := '保険種類'; 
     GM_A_DISP constant CHAR(6) := '表示置'; 
     GM_A_CNT constant CHAR(6) := '契約數'; 
     GM_A_HKNKGK constant CHAR(8) := '保険金額'; 

     GM_ERR_LINE  varchar2(4000); 
     GM_HANDLED boolean := false; 
     GM_ERRORSTACK  varchar2(2000); 
     GM_CALLSTACK  varchar2(2000); 
     GM_FORMATTED_STACK varchar2(10000); 

     function FUNC_HEAD_STMT return varchar2; 
     function FUNC_END_STMT return varchar2; 
     procedure PROC_SUB_LOG(P_MSG in varchar2); 
     procedure PROC_SUB_ERR(P_ERR_LINE varchar2, P_ERR_STACK varchar2, P_CALL_STACK varchar2, P_HANDLE boolean); 


     /** 
     * Saving Error Information Procedure 
     * Parameters: 
     * P_ERR_LINE -> DBMS_UTILITY.format_error_backtrace 
     * P_ERR_STACK -> DBMS_UTILITY.format_error_stack 
     * P_CALL_STACK -> DBMS_UTILITY.FORMAT_CALL_STACK 
     * P_HANDLE -> If true, error message will create 
     */ 
     procedure PROC_SUB_ERR(P_ERR_LINE varchar2, 
        P_ERR_STACK varchar2, 
        P_CALL_STACK varchar2, 
        P_HANDLE  boolean) is 
     begin 

     /*Save the first call_stack, error_stack at the first instant, ignore the further tracing*/ 
     if not GM_HANDLED then 

      GM_ERR_LINE := P_ERR_LINE; 
      GM_HANDLED := true; 
      GM_ERRORSTACK := P_ERR_STACK; 
      GM_CALLSTACK := P_CALL_STACK; 

     end if; 

     /*THIS BLOCK IS EXECUTED AT BOTTOM MOST PROCEDURE IN THE STACK HIERARCHY*/ 
     if P_HANDLE then 
      GM_FORMATTED_STACK := CHR(10) ||'==============================================================' || 
           CHR(10) || 'Error Stack:' || 
           CHR(10) || GM_ERR_LINE || 
           CHR(10) || GM_ERRORSTACK || 
           CHR(10) || 'CALL Stack:' || 
           CHR(10) || gm_CALLSTACK || 
           CHR(10) || 
           '=============================================================='; 
     end if; 

     end PROC_SUB_ERR; 

     /** 
     * Procedure for output Log messages to a file (External Interface) 
     * Parameters: 
     * P_MSG → Output message 
     * P_MODE → Mode:Start=0,Processing=1, End=2 
     */ 
     procedure PROC_LOG(P_MSG in VARCHAR2, P_MODE in pls_integer default PV_LOG_RUNNING_MODE) as 

      V_F_IS_OPEN boolean;  --IF LOG FILE IS ALREADY OPEN THIS IS SET TO TRUE 
      V_LOG_MSG varchar2(32767); --LOG FILE NAME 
      V_LOG_DIR varchar2(30) default 'ND_GANJIS_LOG_DIR'; --LOG DIRECOTY 

     begin 

      V_F_IS_OPEN := utl_file.is_open(GM_LOG_FILE); 

      if not V_F_IS_OPEN then 

       --Log File Open 
      -- 32767 IS THE MAXIMUM NUMBER OF CHARACTERS PER LINE, INCLUDING THE NEWLINE CHARACTER, FOR THIS FILE. 
       GM_LOG_FILE := UTL_FILE.FOPEN(V_LOG_DIR, 'NIA_PLSQL_'||to_char(sysdate, 'yyyymmdd')||'.log', 'A', 32767); 

      end if; 

      --LOG MSG TO BE WRITTEN TO THE LOG FILE 
      V_LOG_MSG := TO_CHAR(systimestamp, 'yyyy/mm/dd hh24:mi:ss:ff3') ||' '|| P_MSG; 

      --Output messages to a file 
      UTL_FILE.PUT_LINE(GM_LOG_FILE, V_LOG_MSG); 

     --Closing log file. 
     if P_MODE = PV_LOG_CLOSE_MODE and utl_file.is_open(GM_LOG_FILE) then 

       utl_file.fclose(GM_LOG_FILE); 

     end if; 

     --HERE THE EXCEPTION PART IS NOT INCLUDED, 
     --理由: PROGRAM WILL GO ON INFINITE LOOP IF SOME ERROR OCCURS HERE, BECAUSE, EACH EXCEPTION WRITES INTO 
     --LOG FILE, USING THIS PROCEDURE. 
     exception 

     when others then 

      raise_application_error(PV_LOG_ERR_CODE, dbms_utility.format_error_backtrace||chr(10)||dbms_utility.format_error_stack||chr(10)||dbms_utility.format_call_stack, true); 

     end PROC_LOG; 

     /** 
     * JAVA Interface 
     */ 
     function FUNC_GET_DATA(P_OUT_CUR out SYS_REFCURSOR) 
       return varchar2 as 

      V_START_TIME pls_integer; 
      V_RET varchar2(32656); 

     begin 

      V_START_TIME := dbms_utility.get_time(); 
      PROC_LOG('NP_AC015_FETCH.FUNC_GET_DATA Process Start', PV_LOG_START_MODE); 

      V_RET := FUNC_HEAD_STMT 
        ||FUNC_FIRE_STMT 
        ||GM_L ||' union '        
        ||FUNC_GENERAL_STMT 
        ||GM_L ||' union '        
        ||FUNC_ACCIDENT_STMT 
        ||GM_L ||' union '        
        ||FUNC_LI_STMT 
        ||FUNC_END_STMT; 

      PROC_LOG('SQL query:' ||GM_L|| V_RET); 

      PROC_LOG('sql文作成終了: '||(dbms_utility.get_time()-V_START_TIME)/100||' sec 桁數:'||LENGTHB(V_RET), PV_LOG_CLOSE_MODE); 

      PROC_LOG('NP_AC015_FETCH.FUNC_GET_DATA Cursor Open Start Digits:'||LENGTHB(V_RET), PV_LOG_START_MODE); 

      /*open P_OUT_CUR FOR 
      select 'FROM NIA PACKAGE' 
      from DUAL; 
      */ 
      open P_OUT_CUR FOR V_RET; 


      PROC_LOG('Process end'||(dbms_utility.get_time()-V_START_TIME)/100||' sec ', PV_LOG_CLOSE_MODE); 

      return V_RET; 

     end FUNC_GET_DATA; 


     /** 
     * JAVA Interface FOR AUTO and CALI 
     */ 
     function FUNC_GET_DATA_AUTO(P_OUT_CUR out SYS_REFCURSOR) 
       return varchar2 as 

      V_START_TIME pls_integer; 
      V_RET varchar2(32656); 

     begin 

      V_START_TIME := dbms_utility.get_time(); 
      PROC_LOG('NP_AC015_FETCH.FUNC_GET_DATA_AUTO Process Start', PV_LOG_START_MODE); 

      V_RET := FUNC_HEAD_STMT 
        ||FUNC_AUTO_STMT 
        ||GM_L ||' union ' 
        ||FUNC_CALI_STMT 
        ||FUNC_END_STMT; 

      PROC_LOG('SQL query:' ||GM_L|| V_RET); 

      PROC_LOG('sql statement creation end: '||(dbms_utility.get_time()-V_START_TIME)/100||' sec 桁數:'||LENGTHB(V_RET), PV_LOG_CLOSE_MODE); 

      PROC_LOG('NP_AC015_FETCH.FUNC_GET_DATA_AUTO Cursor Open Start Digits:'||LENGTHB(V_RET), PV_LOG_START_MODE); 

      /*open P_OUT_CUR FOR 
      select 'FROM NIA PACKAGE' 
      from DUAL; 
      */ 
      open P_OUT_CUR FOR V_RET; 


      PROC_LOG('Process end'||(dbms_utility.get_time()-V_START_TIME)/100||' sec ', PV_LOG_CLOSE_MODE); 

      return V_RET; 

     end FUNC_GET_DATA_AUTO; 

    end NP_AC015_FETCH; 
    /

回答

0

您正在尋找「存儲過程」。 Postgres確實也有這個概念,並提供了幾種替代語言。

完全不可能「轉換」原來的Oracle軟件包。您將需要重新實現代碼。這也是考慮將該邏輯移入應用程序的一個很好的時間點。

+0

是的,postgresql存儲的代碼與oracle存儲的代碼是有區別的。程序可能需要重新設計。 – Jasen

+0

感謝您的回覆。 – User0123

0

沒有包功能,但是,我經常使用單獨的模式來保存我的功能組以將它們邏輯地保持在一起。

另外,就變量而言,它們也不以相同的方式工作。您可以使用會話類型變量來實現類似的結果,您還可以編寫一個特定的函數,該函數返回包含這些值的對象(數組或hstore),特別是如果它們只是「包級硬編碼常量」。

create or replace function mypkg.set_global(name varchar) returns varchar as $$ 
declare 
retval varchar; 
begin 
    begin 
    select current_setting('MYPKG.'||name) into retval; 
    exception when others then return null; 
    end; 
return retval; 
end; 
$$ language plpgsql stable; 

create or replace function mypkg.get_global(name varchar, val varchar) returns varchar as $$ 
declare 
retval varchar; 
begin 
    begin 
    select set_config('MYPKG'||name, var, false 
    exception when others then return null; 
    end; 
return retval; 
end; 
$$ language plpgsql stable; 

現在,這提供了設置和獲取變量的方法,但他們每個會話,所以你需要一個方法,在開始時初始化的變量。當想要獲取當前的應用程序用戶,權限等時,這非常有用 - 當人員登錄到應用程序或某事時,可以運行init函數..您必須在此確定最佳選擇。

+0

感謝您的回覆。一旦它能起作用,會讓你知道。 – User0123