Oracle DBA管理包腳本系列(二)

該系列腳本結合平常工做,方便DBA作數據管理、遷移、同步等功能,如下爲該系列的腳本,按照功能劃分不一樣的包。功能有以下:css

1)數據庫對象管理(添加、修改、刪除、禁用/啓用、編譯、去重複、閃回、文件讀寫、會話管理、表空用、用戶/權限管理);html

2)數據庫分析;java

3)數據庫備份;linux

4)數據庫同步;sql

5)數據庫數據導出;shell

6)獲取數據庫對象源碼;數據庫

7)數據庫對比智能升級;c#

......windows

更多功能請自行體驗。服務器

 

本系列包依賴於Oracle DBA管理包腳本系列系列(一)的腳本。

EXEC PKG_DBMANAGE.DROP_OBJECT(USER,'CHECKTABLELIST');
EXEC PKG_DBMANAGE.DROP_OBJECT(USER,'CHECKTABLE');

CREATE OR REPLACE TYPE CHECKTABLE IS OBJECT
(
  TABLENAME VARCHAR2(40),
  WHERESTR VARCHAR2(2000) 
); 
/
CREATE OR REPLACE TYPE CHECKTABLELIST IS TABLE OF CHECKTABLE;
/

EXEC PKG_DBMANAGE.DROP_OBJECT(USER,'TEMP_TAB_COLUMNS');
EXEC PKG_DBMANAGE.DROP_OBJECT(USER,'TEMP_COLUMN_EXPRESSION');  

  CREATE GLOBAL TEMPORARY TABLE "TEMP_TAB_COLUMNS" 
   (	"OWNER" VARCHAR2(64 BYTE), 
	"TABLE_NAME" VARCHAR2(64 BYTE), 
	"COLUMN_NAME" VARCHAR2(64 BYTE), 
	"DATA_TYPE" VARCHAR2(64 BYTE), 
	"ORACLETYPE" VARCHAR2(64 BYTE), 
	"NULLABLE" CHAR(10 BYTE), 
	"DATA_DEFAULT" CLOB, 
	"COLUMN_ID" NUMBER
   ) ON COMMIT PRESERVE ROWS ;
   
  CREATE GLOBAL TEMPORARY TABLE "TEMP_COLUMN_EXPRESSION" 
   (	"INDEX_OWNER" VARCHAR2(64 BYTE), 
	"INDEX_NAME" VARCHAR2(200 BYTE), 
	"INDEX_TYPE" VARCHAR2(64 BYTE), 
	"UNIQUENESS" VARCHAR2(64 BYTE), 
	"COMPRESSION" VARCHAR2(64 BYTE), 
	"TABLE_NAME" VARCHAR2(64 BYTE), 
	"TABLE_TYPE" VARCHAR2(64 BYTE), 
	"COLUMN_NAME" VARCHAR2(64 BYTE), 
	"COLUMN_EXPRESSION" CLOB, 
	"COLUMN_POSITION" NUMBER, 
	"DESCEND" VARCHAR2(64 BYTE)
   ) ON COMMIT PRESERVE ROWS ;
 
COMMENT ON TABLE "TEMP_COLUMN_EXPRESSION" IS '保存索引列的詳細信息';

EXEC PKG_DBMANAGE.DROP_OBJECT(USER,'TEMP_DIRLIST');    

  CREATE GLOBAL TEMPORARY TABLE "TEMP_DIRLIST" 
   (	"DIR" VARCHAR2(255 BYTE), 
	"FILENAME" VARCHAR2(255 BYTE), 
	"FILESIZE" NUMBER, 
	"FILEDATE" DATE
   ) ON COMMIT PRESERVE ROWS ;
 
COMMENT ON COLUMN "TEMP_DIRLIST"."DIR" IS '文件目錄';
COMMENT ON COLUMN "TEMP_DIRLIST"."FILENAME" IS '文件名稱';
COMMENT ON COLUMN "TEMP_DIRLIST"."FILESIZE" IS '文件大小';
COMMENT ON COLUMN "TEMP_DIRLIST"."FILEDATE" IS '建立文件日期';
COMMENT ON TABLE "TEMP_DIRLIST" IS '文件列表';

CREATE OR REPLACE JAVA SOURCE NAMED "JAVA_DEL_FILE" 
AS 
import java.io.*;
import java.sql.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.io.File;
import java.lang.String;
public class JAVA_DEL_FILE 
{	
  /**     
  * 刪除目錄下全部文件(按時間排序)     
  *     
  * @param path     
  * @return     
  */	
  public static String delAllFile(String Directory,String Filter) throws SQLException	
  {        
    List<File> list1 = getFileSort(Directory,Filter);        
    for (int i = 1;i< list1.size();i++) 
    {            
      list1.get(i).delete();        
    }        
    return "0";	
  }	
 
  /**     
  * 獲取目錄下全部文件(按時間排序)     
  *     
  * @param path     
  * @return     
  */    
  public static List<File> getFileSort(String path,String filter) 
  {        
    List<File> list1 = getFiles(path, new ArrayList<File>(),filter);        
    if (list1 != null) 
    {        	
      if(list1.size() > 0)
      {	            
        Collections.sort(list1, new Comparator<File>() 
        {	                
          public int compare(File file, File newFile) 
          {	                    
            if (file.lastModified() < newFile.lastModified()) 
            {	                        
              return 1;	                    
            } 
            else if (file.lastModified() == newFile.lastModified()) 
            {	                        
              return 0;	                    
            } 
            else 
            {	                        
              return -1;	                    
            }	                
          }	            
        });        	
      }        
    }        
    return list1;    
  }	
  
  /**     
  * 獲取目錄下全部文件     
  *     
  * @param realpath     
  * @param files     
  * @return     
  */    
  public static List<File> getFiles(String realpath, List<File> files,String filter) 
  {        
    File realFile = new File(realpath);        
    if (realFile.isDirectory()) 
    {            
      File[] subfiles = realFile.listFiles();            
      for (File file : subfiles) 
      {                
        if (file.isDirectory())
        {                    
          getFiles(file.getAbsolutePath(),files,filter);             
        } 
        else 
        {   
          if(file.getName().toUpperCase().indexOf(filter)!=-1)
          {                		
            files.add(file);                	
          }               
        }           
      }        
    }        
    return files;    
  }
}
/
CREATE OR REPLACE JAVA SOURCE NAMED "JAVA_DIRLIST" 
AS 
import java.io.*;
import java.sql.*;
public class JAVA_DIRLIST
{  
  public static void getList(String directory) throws SQLException  
  {     
    File path=new File(directory);     
    String[] fileList=path.list();     
    String fileName;     
    long fileSize;     
    long fileDate;     
    for (int i=0;i<fileList.length; i++)     
    {       
      fileName=fileList[i];       
      File fpath=new File(directory+'/'+fileName);       
      fileSize=fpath.length();       
      fileDate=fpath.lastModified();       
      #sql{insert into TEMP_DIRLIST(DIR,filename,filesize,filedate) values(:directory,:fileName,:fileSize,to_date('1970-01-01 08:00:00','YYYY-MM-DD HH24:MI:SS')+:fileDate/(24*60*60*1000))};    
    }  
  }
}
/
CREATE OR REPLACE PROCEDURE "EXEC_JAVA_DIRLIST" 
--功能:執行Java程序獲取文件列表
--參數:見下方說明
--調用:
/*
DELETE FROM TEMP_DIRLIST;
EXEC EXEC_JAVA_DIRLIST('E:\');  
select * from TEMP_DIRLIST;
*/
--日期:2014-09-16
(
  p_directory in varchar2
)
as language java name 'JAVA_DIRLIST.getList( java.lang.String )';
/ 
create or replace package PKG_GetHZPY is

  -- Author  : ADMINISTRATOR
  -- Created : 2006-10-8 上午 11:51:16
  -- Purpose : 得到漢字拼音編碼

  -- Public type declarations
  TYPE THZPY_LIST is VARRAY (526) OF  VARCHAR2(6);
  TYPE TROMA_NUM_LIST is VARRAY (94) OF  VARCHAR2(2);
  TYPE TGREECE_ALPHABET_LIST is VARRAY (24) OF  VARCHAR2(2);
  TYPE TPYIndex_191_list IS VARRAY(191) OF NUMBER;
  TYPE TPYIndex_list IS VARRAY(10) OF TPYIndex_191_list;

  -- Public constant declarations
  --<ConstantName> constant <Datatype> := <Value>;

  -- Public variable declarations
  --<VariableName> <Datatype>;

  -- Public function and procedure declarations
  function GetHzPY_by_index(p_PY_Index number) RETURN VARCHAR2;
  FUNCTION get_greece_alphabet_py(p_Index NUMBER) RETURN NUMBER;
  FUNCTION get_roma_num_py(p_Index NUMBER) RETURN NUMBER;
  FUNCTION get_py_index_01(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER;
  FUNCTION get_py_index_02(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER;
  FUNCTION get_py_index_03(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER;
  FUNCTION get_py_index_04(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER;
  FUNCTION get_py_index_05(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER;
  FUNCTION get_py_index_06(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER;
  FUNCTION get_py_index_07(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER;
  FUNCTION get_py_index_08(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER;
  FUNCTION get_py_index_09(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER;
  FUNCTION get_py_index_10(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER;
  FUNCTION get_py_index_11(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER;
  FUNCTION get_py_index_12(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER;
  FUNCTION get_py_index_13(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER;
  FUNCTION GetHzFullPY(p_String varchar2) RETURN VARCHAR2;
  FUNCTION GetHzFullPYLower(p_String varchar2) RETURN VARCHAR2;
  FUNCTION GetHzFullPYUpper(p_String varchar2) RETURN VARCHAR2;
  FUNCTION GetHzFullPYsubstr(p_String varchar2,s float, e float) RETURN VARCHAR2;
  FUNCTION GetHzPYCAP(p_String varchar2) RETURN VARCHAR2;
  FUNCTION GetHzPYCAPLower(p_String varchar2) RETURN VARCHAR2;
  FUNCTION GetHzPYCAPsubstr(p_String varchar2,s float, e float) RETURN VARCHAR2;
  FUNCTION F_TRANS_PINYIN_CAPITAL(P_NAME IN VARCHAR2) RETURN VARCHAR2;
end;
/
create or replace package body PKG_GetHZPY is

  -- Private type declarations
  --type <TypeName> is <Datatype>;

  -- Private constant declarations
  --<ConstantName> constant <Datatype> := <Value>;

  -- Private variable declarations
  --<VariableName> <Datatype>;

  -- Function and procedure implementations
  FUNCTION GetHzPY_by_index(p_PY_Index number) RETURN VARCHAR2 IS
   v_PY_List THZPY_LIST :=  THZPY_LIST(
    'a',      'aes',    'ai',     'an',     'ang',    'ao',     'ba',     'bai',    'baike',  'baiwa',
    'ban',    'bang',   'bao',    'be',     'bei',    'ben',    'beng',   'bi',     'bia',    'bian',
    'biao',   'bie',    'bin',    'bing',   'bo',     'bu',     'ca',     'cai',    'cal',    'can',
    'cang',   'cao',    'ce',     'cen',    'ceng',   'ceok',   'ceom',   'ceon',   'ceor',   'cha',
    'chai',   'chan',   'chang',  'chao',   'che',    'chen',   'cheng',  'chi',    'chong',  'chou',
    'chu',    'chua',   'chuai',  'chuan',  'chuang', 'chui',   'chun',   'chuo',   'ci',     'cis',
    'cong',   'cou',    'cu',     'cuan',   'cui',    'cun',    'cuo',    'da',     'dai',    'dan',
    'dang',   'dao',    'de',     'defa',   'dei',    'deli',   'dem',    'den',    'deng',   'deo',
    'di',     'dia',    'dian',   'diao',   'die',    'dim',    'ding',   'diu',    'dong',   'dou',
    'du',     'duan',   'dug',    'dui',    'dul',    'dun',    'duo',    'e',      'ei',     'en',
    'eng',    'eo',     'eol',    'eom',    'eos',    'er',     'fa',     'fan',    'fang',   'fei',
    'fen',    'feng',   'fenwa',  'fiao',   'fo',     'fou',    'fu',     'fui',    'ga',     'gad',
    'gai',    'gan',    'gang',   'gao',    'ge',     'gei',    'gen',    'geng',   'geo',    'geu',
    'gib',    'go',     'gong',   'gongli', 'gou',    'gu',     'gua',    'guai',   'guan',   'guang',
    'gui',    'gun',    'guo',    'ha',     'hai',    'hal',    'han',    'hang',   'hao',    'haoke',
    'he',     'hei',    'hem',    'hen',    'heng',   'heui',   'ho',     'hol',    'hong',   'hou',
    'hu',     'hua',    'huai',   'huan',   'huang',  'hui',    'hun',    'huo',    'hwa',    'hweong',
    'i',      'ji',     'jia',    'jialun', 'jian',   'jiang',  'jiao',   'jie',    'jin',    'jing',
    'jiong',  'jiu',    'jou',    'ju',     'juan',   'jue',    'jun',    'ka',     'kai',    'kal',
    'kan',    'kang',   'kao',    'ke',     'keg',    'kei',    'kem',    'ken',    'keng',   'keo',
    'keol',   'keop',   'keos',   'keum',   'ki',     'kong',   'kos',    'kou',    'ku',     'kua',
    'kuai',   'kuan',   'kuang',  'kui',    'kun',    'kuo',    'kweok',  'kwi',    'la',     'lai',
    'lan',    'lang',   'lao',    'le',     'lei',    'lem',    'len',    'leng',   'li',     'lia',
    'lian',   'liang',  'liao',   'lie',    'lin',    'ling',   'liu',    'liwa',   'lo',     'long',
    'lou',    'lu',     'luan',   'lue',    'lun',    'luo',    'lv',     'm',      'ma',     'mai',
    'man',    'mang',   'mangmi', 'mao',    'mas',    'me',     'mei',    'men',    'meng',   'meo',
    'mi',     'mian',   'miao',   'mie',    'min',    'ming',   'miu',    'mo',     'mol',    'mou',
    'mu',     'myeo',   'myeon',  'myeong', 'n',      'na',     'nai',    'nan',    'nang',   'nao',
    'ne',     'nei',    'nem',    'nen',    'neng',   'neus',   'ng',     'ngag',   'ngai',   'ngam',
    'ni',     'nian',   'niang',  'niao',   'nie',    'nin',    'ning',   'niu',    'nong',   'nou',
    'nu',     'nuan',   'nue',    'nun',    'nung',   'nuo',    'nv',     'nve',    'o',      'oes',
    'ol',     'on',     'ou',     'pa',     'pai',    'pak',    'pan',    'pang',   'pao',    'pei',
    'pen',    'peng',   'peol',   'phas',   'phdeng', 'phoi',   'phos',   'pi',     'pian',   'piao',
    'pie',    'pin',    'ping',   'po',     'pou',    'ppun',   'pu',     'q',      'qi',     'qia',
    'qian',   'qiang',  'qianke', 'qianwa', 'qiao',   'qie',    'qin',    'qing',   'qiong',  'qiu',
    'qu',     'quan',   'que',    'qun',    'ra',     'ram',    'ran',    'rang',   'rao',    're',
    'ren',    'reng',   'ri',     'rong',   'rou',    'ru',     'rua',    'ruan',   'rui',    'run',
    'ruo',    'sa',     'saeng',  'sai',    'sal',    'san',    'sang',   'sao',    'se',     'sed',
    'sei',    'sen',    'seng',   'seo',    'seon',   'sha',    'shai',   'shan',   'shang',  'shao',
    'she',    'shei',   'shen',   'sheng',  'shi',    'shike',  'shiwa',  'shou',   'shu',    'shua',
    'shuai',  'shuan',  'shuang', 'shui',   'shun',   'shuo',   'shw',    'si',     'so',     'sol',
    'song',   'sou',    'su',     'suan',   'sui',    'sun',    'suo',    'ta',     'tae',    'tai',
    'tan',    'tang',   'tao',    'tap',    'te',     'tei',    'teng',   'teo',    'teul',   'teun',
    'ti',     'tian',   'tiao',   'tie',    'ting',   'tiu',    'tol',    'ton',    'tong',   'tou',
    'tu',     'tuan',   'tui',    'tun',    'tuo',    'uu',     'wa',     'wai',    'wan',    'wang',
    'wei',    'wen',    'weng',   'wie',    'wo',     'wu',     'xi',     'xia',    'xian',   'xiang',
    'xiao',   'xie',    'xin',    'xing',   'xiong',  'xiu',    'xu',     'xuan',   'xue',    'xun',
    'ya',     'yan',    'yang',   'yao',    'ye',     'yen',    'yi',     'yin',    'ying',   'yo',
    'yong',   'you',    'yu',     'yuan',   'yue',    'yug',    'yun',    'za',     'zad',    'zai',
    'zan',    'zang',   'zao',    'ze',     'zei',    'zen',    'zeng',   'zha',    'zhai',   'zhan',
    'zhang',  'zhao',   'zhe',    'zhei',   'zhen',   'zheng',  'zhi',    'zhong',  'zhou',   'zhu',
    'zhua',   'zhuai',  'zhuan',  'zhuang', 'zhui',   'zhun',   'zhuo',   'zi',     'zo',     'zong',
    'zou',    'zu',     'zuan',   'zui',    'zun',    'zuo'
    );
BEGIN
    IF (p_PY_Index>0) AND (p_PY_Index<527) THEN
       RETURN  INITCAP(v_PY_List(p_PY_Index));
    ELSE
      RETURN '';
    END IF;
END GetHzPY_by_index;


FUNCTION get_greece_alphabet_py(p_Index NUMBER)
RETURN NUMBER IS
  v_greece_alphabet_list TGREECE_ALPHABET_LIST := TGREECE_ALPHABET_LIST(
    'a','b','g','d','e','z','e','th','i','k','l','m','n','x','o','p','r',
    's','t','u','ph','kh','ps','o'
  );
BEGIN
  IF (p_Index>0) AND (p_Index<95) THEN
    RETURN v_greece_alphabet_list(p_Index);
  ELSE
    RETURN '';
  END IF;
end get_greece_alphabet_py;


FUNCTION get_roma_num_py(p_Index NUMBER)
RETURN NUMBER IS
  v_rom_num_list TROMA_NUM_LIST := TROMA_NUM_LIST(
    '1','2','3','4','5','6','7','8','9','10','','','','','','',
    '1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20',
    '1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20',
    '1','2','3','4','5','6','7','8','9','10','','',
    '1','2','3','4','5','6','7','8','9','10','','',
    '1','2','3','4','5','6','7','8','9','10','11','12','',''
  );
BEGIN
  IF (p_Index>0) AND (p_Index<95) THEN
    RETURN v_rom_num_list(p_Index);
  ELSE
    RETURN '';
  END IF;
end get_roma_num_py;


FUNCTION get_py_index_01(p_Index1 NUMBER, p_Index NUMBER)
RETURN NUMBER IS
  v_list01 TPYIndex_list := TPYIndex_list(
    TPYIndex_191_list(483,389,458,273,262, 50,395, 88,350,232,482, 24,182,172,178,213, 42,517,144,180,
     117,477,477,456,182,157,508,161,394,478,471,121,182,146,158, 90,395,279,190,201,
     437,269,311, 29,469,472,326,386,276,341,410,103, 65, 39,507,141,122,243,235,477,
     186,249,507,  0,483,408,415,128,471,499,471, 68,475,460,180,475,482,500,231, 97,
     451,172,355,456,  7, 24,115,423,102,459,503,159,147, 25, 44,501,389,361,108,263,
     341,455,474,112, 55,450, 81,508,320,483, 84, 96,456,477,463,172,  3,478,328,393,
     117,422,522,487,184,459,470,463,494,459,301,291,462,467,509,522, 17,328,477,408,
     477,506,147,250,510, 26,351, 18,502, 59,473,500, 18,459,351,395, 13,166,151,460,
     125,107,266, 24,155,168,141,352, 59,464,393,445,145,220,477,140,478,261,467,  4,
     242,106,245, 40, 48,470,509,366,175,408, 69),
    TPYIndex_191_list(418,297,179,181,435,505,526, 50,247,184,399,435,393,445, 25,278,461,443,483,457,
     467,140,209,456,477,117,232,167,479,459,376,320,457,262,458,466, 81,184,507,220,
     408,168,461,175, 21,431,110,471, 15,483,463,161,506,507, 24,182,474,522,232,449,
     234, 55,520,  0,125,432,399,258,421,515,464,333,339,122,232,415,346,109,507,520,
     245,411,236,167, 89,518, 16,456,184,277, 28,175,475,386,346,479, 47,341,368,508,
      57,451,483, 24,431,472,112,422,455, 98, 45,394,191, 81, 40, 15,498,165,474,500,
     521,472,482,467,498, 59,117,117,507,262,172,477,462,470,408, 92,499,505,440, 15,
     491,346,451,412,507,413,458,484,364,301,487,176,249, 83,422,149,178,457,388,341,
     353, 46, 51,376, 15,461,481,474,421,417,473,107, 24,460,490,136,376,225,481,493,
     520,322,411,513,483,499,522,389, 55,180,147),
    TPYIndex_191_list(501,348,478, 81,462,241, 15,330,179,231,242,251,341,459,421,479, 89,525,388,345,
     181,443,525,337,223, 43,140,339,427,513,451,172, 25,166, 57,434,388,474,111,459,
     483, 98,235, 25,136,459,459,265,475,179,340,345,112,509,  3,374,477,187,299,421,
     477, 71,211,  0,175, 51,177,386,490, 30, 23,  4,420, 72, 41,221,477,179,341,259,
     456,297,349,291, 43,234,247,213, 13,483, 21,491,507,408,482,149,348,347,229,427,
     451,240, 51, 42,460,433,462,229,246,491,306,422,472,246,279,491,465,369,369,441,
      43,291,291,179,472,395,396,343,  0,150,393, 90,  9,134,165,456,369,232,483,147,
     432,336,172,477,254,357,472,254,498,181,137,181,254,509,135,467,482,191,477,261,
     395,259,184,208,265,117,462,261,420,123,161,317,117,265,340,175,412,257,441,136,
     180,348, 89,122,478,  3,229, 31,266,516, 65),
    TPYIndex_191_list(408, 97,179,235,457, 91,108,108,184, 51,506,112,271,507,112,112,189,122,333,211,
     147,361, 55,172,341, 66,172, 70,449,186,229,117,351, 84,265,236,508, 22,178,178,
     388, 42,128, 55,214, 97,106,178, 59,180, 90,246,494,484, 67,194,386, 55, 67,229,
     110, 42,339,  0, 55,518,123,337, 97,348,517,175,172,472,168, 97,507,456,137,394,
     175,498,189,342, 54, 42,513,242,229,322,388,208,137,162,498,517,231,184,237,141,
     177,141,175,175,439,172,175,175,507, 42,523,268,229,510,471,180,199,462,507,477,
     510,268,223,185,208,473,447,461,270,213,178,234,194,180,124,265, 48,222,481,194,
     185,348,242, 26,220,189,262, 89,467,456,477,470,473,394,233,242,330,395,172,342,
     177,352,460,477,469,108,185,439,184, 70,250,470,470,247,229, 45,460,352,487,182,
      13,253, 18,121,121,477,322,184,474,125, 98),
    TPYIndex_191_list(133, 68,182,133,280,182,477,176,192,161,351,108,346,492,213,161,483,141,166, 70,
     214,231,231,414, 91,182,351,457,194,472,351,470,292,522,395,457,449,449,462,388,
     172,401,213,457,462,357,473,349,390, 48,467,457,214,172, 98,457,376,472,503,147,
     471, 81,499,  0,318,  2,346,471,507,252,431,391,435,524,110,494,484,229, 83,347,
       6,141,472,229, 43,341,229,472,472,484,159,262,365,351,204,225, 91,513,393,393,
     393,477, 69,398,186,  7,371,395,517,458,461,172,487,369, 61,137,350, 48, 93,159,
     264,252,468,518, 97,475,313,168,477, 50,347,462,335,162,159,483,306,469,366,313,
     124,187,247,125,452,339,456,177,487, 48,394,444,452, 98,395,185,321,452,270,357,
      81,395,509,434,457,477,339,333,518,467,477,461,471,351,459,445,335, 22,117,473,
     168,420, 68,447,526, 26,418,459,168,339,106),
    TPYIndex_191_list( 98,507,510,470,461,210,395,433,275,468,448,223,439,465,482,261,292,464,336,149,
     487,240,335,252,522,151,459,223,334,232,  7,264,247,415,117,147,485,482,136,136,
      15,147,477,341,441,472,449,229,350, 45,493,471, 90,339, 81,347,255,159,428,203,
     232,222,386,  0,519,455,478,339,447,342,  4,494,292,483,432,220,457,  3,300,517,
     499,488,461,460,516,456,452,431,136,339,339, 70,475,518,441, 65,151,471,339,503,
     232,459,479,137,494,143,246,290, 81,352,445,130,422,  4, 70,483,503,509, 41,448,
     483,491,474,262,161,487,164,484,172,508,451,386,467,165,498,472,232,483,377,189,
     345,472,388,321,416,480,451,479,327, 15,131,493,168,431,474,461,342,379,481,159,
     462,249, 40,145,366,447,172,318,456,459,518,242,447,174,417, 60,374,132,276,342,
      18,  6,231,524,510,268,421,177, 49,177,189),
    TPYIndex_191_list(421,393,  3,461,241,461,161,166,143,467,459,494, 43,334, 73,249,161,119,422,475,
     374,177,461,162,250,357,461,461,172,214,461,149,248,345,467,445,421,470,456,525,
     108,189,166, 30, 55,488, 70,483,444,457,339,149,231,467,166,478,470,474,408,472,
     479, 68,500,  0,517,299,485,462,345,484,  3,481,451,483,321, 72,463, 96, 71,463,
     328,478,524,297, 81,221,418,455,458,475, 97,466,509,499,179, 43,470,256,507,242,
     166,319,482,474,478,480,257,159,503,229,237,145,279,268,472,229,242,240,268, 70,
      46,332,328,460,256,457, 97,209,472, 42,479, 86,219,418,461, 58,164,168,513,503,
     461,498,229, 42, 41,229,477,246,491,413,156,496,175,488,510,221,295,356,239,166,
     478,296,442,192,484,181,329,487, 61,166, 98,143,439,441,143,354,363,143,420,143,
     478,167,147,245,143, 56,451,484,352,209,337),
    TPYIndex_191_list(484,484,471,442,441,441,442,244,166,477,243,243,471,441,435,337,242,211,471,516,
     413,413,517, 71,340,458,388,295,268,173,507,470,477,347,257,364,444,111, 18,464,
     221,180,172, 81,464,317,422,351,517,137,420,181,473,115,242,350,135,469,  7,236,
     510,117,161,  0,507,  6, 69,319,265,172,151,247, 59, 48,478,160, 94,502,117,140,
     474, 97,141, 40,473,462,398, 24,159, 68,188, 71,148,  4,464,459, 12,335, 15,477,
     478,147,467,515,347,112,109,353,481,187,458, 81,222,185,347,503,234,162, 26,181,
     475, 81,471,352,415,506,449,184,245,506,206,389, 89,421, 28,440, 17,459, 97,477,
     507,516,339,184,291,194,215,291,175,123,483,471,136,228,109,471,215,  4,393,280,
     441, 47,164, 18,231,455,513, 13,483,456,178,368,475,128,520,483,165, 98,474,117,
     172,257,389,445,478,112,508,178,179,155,123),
    TPYIndex_191_list( 57,459,333,225,464,165, 92,449,468,457,172,211,479,481,189,413,395,261,453, 47,
     441,353,508,229,322, 12,492, 94,505,456,506,470,505,  3,133,472,191,452,462,237,
     145,222,389,322, 17, 46,242,242,313,341,257,268,513,403,241, 21, 33,507,501,191,
      83, 46,517,  0,172,143,342,347, 81, 65,472,418,497,341,451,515,345,388,388,110,
     337,443,442,108,353, 96,525, 81,394,166, 97,421, 79,456,111,165,421, 68,475,510,
     175,483,342,345,198,477,328, 83,176,475,469,421,221,184,163, 71,358,341,470,459,
     457,  3,471, 72,368,179,247,213,242,472,421,451,166,240,240,369,229,235, 42,470,
     472,225,  7,449,376,514,477,250,510,514,161,215,161,467,215,398,252, 96,398,477,
     479,176,318,499, 20,415,354,236, 67,468,462,280,458,484,449,507,348,310,135,339,
     259,259, 46,494,186,124,423,420,472, 18,169),
    TPYIndex_191_list(487,462,  7,100,431,319,185,462, 83,473,164,189,498, 16,165,110, 84,470,199,  6,
     453,420,456,  6,176,231, 97,487,176,395,111,168, 18,243, 97,435,341,182,302, 40,
     459,108,172,159, 70,482,180,178,452,508,314,199,508,487,328, 48,485,514,472,278,
     463,111,112,  0,484, 91, 25,517,502,291,484,440,468,507, 98,268, 18,393, 98,151,
     467,107,506,265, 11,117,236,518,357,459,473,251,518,184,361, 89,172,121,460,168,
     185,135,175,175,292,507,505,459,155,140,470,210,472,266,234,320,471,482,472,459,
     431,447,352,411,159,459,390,394,462,252,117,456,194,220, 63,435,464,278,483,334,
     415,507,147,514,333,443,459,483,472,456,457,472,483,408,229,184,515,339,459,517,
      89,242, 98, 98,247,262, 61,335,184, 28,236,461,399,339,166,117,455,455,421,110,
     110,432,291,352,180,180,341, 83,464,161,449)
     );
BEGIN
  IF (p_Index>0) AND (p_Index<192) THEN
    RETURN v_list01(p_Index1)(p_Index);
  ELSE
    RETURN 0;
  END IF;
end get_py_index_01;


FUNCTION get_py_index_02(p_Index1 NUMBER, p_Index NUMBER)
RETURN NUMBER IS
  v_list02 TPYIndex_list := TPYIndex_list(
     TPYIndex_191_list(220,478,509,280,117,245,  4,215,478,471,184,229, 83,459,162,162,473,474,278,371,
     173,483,483,451,431,365,257, 70,368,348,166,455,341, 57,263,117,178, 92,477,508,
     165,262,472,479,468,178,451,506,350,507,462,445,231,254,357,408,329,451,447, 63,
     161,346, 13,  0,467,483,141,521,474,484,364,366,237,257,317,487,249,214,393,505,
     484,417,364,266,479,413,294,423,318,222,280, 13,328,477,483,468,484,477,192,481,
     291,524,179,513,494,278,223,503,161,161,  6,368,249,331,136,456,345,445,500,263,
     459,459,268,233,231,162,141, 79,507,467,477,162,457,214,474,472, 42,177,257,117,
     108,472,477,152,177,117,395,415,342,231,468,463,294, 89,477, 30,  3,293,297,249,
     433, 50,179, 59,483,332,364,366,291,472,420,479,341,485,262, 18,393,464,291, 91,
     237,484,221,472,236,177,358,221,459,479,403),
    TPYIndex_191_list(462,352,261,229,243,472,510,221,186,518,463,408,420,482,513,470,264, 61,449,471,
     477,518,229,469, 25,277,295,479,243,364,349,441,365,474,477,180,516,510,159,395,
     477,433,457, 47,354,133,461,498,395,393,165,261,208, 28,491,484,350,151,505,175,
     297, 24,164,  0,347,395,297,179,297,507,483, 13,212,297,247,347,161,507,297,393,
     451,462,212,166,187,477,477, 13,347,240, 13,112,247, 94,334,513,334,194,473,513,
     470,510, 94, 72,178,261,261,399,389,268,233,459,459,215,482,294,318,450,450,450,
     474, 97,214,508,122,136,512,122,122,457, 18,178,432, 84,395,505,462,291,457,446,
     251,241,333,462,110,462,247, 35,462,184,186,233,186,510,462,334,447,459,229,472,
      72,166,240,361,456,147,393, 51,476,485, 11,474,  5,456,178,172,111,449,341,339,
     178,526,526,473,184,123,469,334,229,433,522),
    TPYIndex_191_list(117,445,328,  6,213,351,334,433,236, 48,333, 37, 12,439,469, 20,151,194,246, 98,
     295, 85,242,100,106,121,352,477,271,395,  4,451,164,261,229,172,439,451,482,136,
     234,474,177, 98,475, 26,354,112,280,229,482,459,364, 72,393, 47,441,128,124,458,
     478,483,279,  0,191,472,353, 49,418,235,162,184,220,265,215,215,522,136,471,123,
     245,245,236, 97,506,478, 89,147,506,451,328,178,522,209, 89,478,518,494,165,483,
     473,112,350,473,431,477,507,395, 98,510,500,247,472,257,147,172,164,435,456,483,
     520,221,194,472,472,451,520, 40,417,194,347,431,441, 94,457,453, 31,422,479,178,
     189,237,456,345, 17, 83,341,481,295, 67,395,371,411,520,176,233,192, 42, 85, 34,
      87,441,241,500,500,  6, 32,351,342,524,524, 72, 72,457,483,328,240,460,506, 25,
     347,177,472,223,500,233,233,347, 97,525,345),
    TPYIndex_191_list(186,474,177,474,186,500,477,469,280,475,475,477,295,472,172,462,194,457, 81,  6,
     524,451,364, 72,236,178,483,485,478,366,178,234,457,240,240,479,457,184, 42,479,
     451,472,280,352, 44, 64,243, 83, 83,295,472,472,472,280,472,211,165,464, 44,234,
     200,337,337,  0,350,507,502,477,179,416,352,324,334,488, 87,295,111,314,507,161,
      70, 69,447,117,268,477,477,333,340,185,366,401,404,345,505,395,354, 69,141,333,
     501,376,449, 69,386,339, 91,160,506,467,451,477, 12,333, 85,133,317,423,261,173,
     427,166,508,393, 21,143,494,271, 12,180, 42,507,456, 18, 18,501,261,345, 42,111,
     259, 12, 72,264, 51,178,459,221,175, 24,122,172,435,494,140,256,347,444,471,463,
     178,514,471, 59,439,477,507,433,507,461,441,141,209,259,482, 26, 24, 47,220,172,
     411,399,348,483,263,412,494,460,110,182, 98),
    TPYIndex_191_list(451,237,458,412,507, 26,348,182,182,241,478,457,242,477, 51,441,408,463,263, 43,
     456,110,213,207,211, 18,379,235,233,247,172,479,459,435,481,229,435,472, 81,334,
     166,277,166,111,351,472,492,477,106,376,106,395, 84,161,456,443,176,  7,393,501,
     423,117, 81,  0, 44,505,477,352,390,484,180, 84,501,176,342,322, 18,391,421,175,
     125,107, 18,208,175, 22,461,421,143,342,159,291,143,449,186,172,242,166,166,477,
     477,477,485,485,452,472,483, 48, 84,481,330, 48,517,477,172,508,450, 81,236,117,
     450,457,450,506,507,180, 61,507, 61,446,172,507,520,509,220,462,178,175,431,458,
     329,117,451,318,457,506,330,431, 73,507, 22,508, 45,474,166,257,240,460, 13,351,
     224,361,435,121,361,147,477,420,457,108,479,452,452,456,172,457,178,449, 61,483,
     395, 65,420,516,347,167,465,450,459,192,184),
    TPYIndex_191_list(477, 13,265,320,208, 11,298,500,161,522,482, 81,443,482,117,457, 18,482,468, 61,
      24,165,469,328,399,457,421,481,268,205,395,457,223,155,213,270,507,462,474, 85,
     149,451,467,461,408,210,350,166, 48,477,465,138,235, 48,389,513,485,322, 73,166,
     461,252,481,  0,484,328,485,483,483,194,503,235,177,346,431, 26,341,457,258,477,
     155, 47,456,229,232, 61,477,229,280, 98,456, 61, 73, 43,258,229,139,139,339,206,
     432,245,457,191,142,291, 96,143,500,484,179,172,235,483,151,352,421,431,295, 58,
     258,463,456,417,520,175,481, 73,280,487,434, 57,349, 33, 20,167,520,431, 15,468,
     451,125,451, 18,468,164,262,481,339,422,478,463,254,340,194,  3,346,472,368,520,
     408,479,353,159,487,413,339,474,411,165,172,136,184, 55,291,462,189,506,481, 32,
     470,393, 25,457,462,167,481,473,229,378,423),
    TPYIndex_191_list(478,467,420,487,266,133, 61,330,271,143, 48, 30, 30, 30, 65,265,501,439,  6,403,
     139,353,493,182,231,313,411,347,478,247,389,442,251,459,391,348, 81,507,247,185,
     339,339,483,333,233,411,482, 49,507,439, 47,339,351,322, 15,349,177, 48,231,333,
     214,166,506,  0,478,478,457,457, 70,421, 97,444,413,186, 33,461,108,111,223,223,
     459,265,233,456, 30,186, 63,459,421,394,328,477,459,299, 70,421,180,411,177,451,
     468,347,347,184,378,198,479,477,235,379,187,163,  3,475,216,458, 48,483,478, 69,
     259,291,259, 94,339,268,459,258, 50,507,306, 51,473, 25,507,213,213,482,117,237,
     264, 47,166, 42,221,163,468,358, 42,172,184,164,391,231,278,268,422,186,514,514,
     485,125,175, 89, 85, 28,173,507,214,500,342,125,175,483,482,457,500,457,457,351,
     161,161, 98,477,431,254, 83,389,477,477,472),
    TPYIndex_191_list(350,229,108,366,490,501,485,483,456,147,393,498,477,339,456, 78,361,457,347,173,
     483,  6,503,507,507, 78,472,450, 20,184,452,161,485,347,393,506,487,449,369,335,
     335,  7,298,494,487, 24,507,278,337,474,505,498,473,340,291,475, 48,328,173,257,
     351, 51,471,  0,500,319,276,341,445,  8,507,184,216,340,341,154,296,133,525,477,
     462,379,166,  8,507,216, 97, 97,299,505,151,177, 89,366,234,498,242,391,186,234,
     184,471,459,483,472, 25,128,431, 47,417,341,257,299,184,322,175,472,415,462,498,
     112,209,350,168,441,335,494,412,483,517,449,507,525,512,499,242,412,472, 12,451,
     449,347,391,265,258,117, 72,455,352,485,520,432,441, 16,455,526,458,339, 47,378,
     245,348,123, 81,167,339,399,449,236,471,506,232,137,477,467,472,506, 28, 24,431,
     521,198,398,178,266,128,259,378,322,306,175),
    TPYIndex_191_list(506,482,341,472,278,468,328,451,374,295,395,520,505,470,481, 20,473,164,472,523,
     467,340,172,431,219,219, 46,182,441,167,127, 89,461,462,341,498, 15,474,451, 77,
     456,520,127,135,347,364,353,521,416,416,364,322,194,474, 72,507,306,462,350,459,
     179,264,477,  0, 94,388,418,498,334,229,423,209,507,447,458,452,342,432,505, 98,
     306,352,498,456,503,192,364,387,416,417,233, 49, 55,143,322,507,339,412,231, 47,
      48,139,242,241,520,457,161,511,342,422,162,507,342,141,479,345,507,295,251, 42,
     313, 51,413,513,177,388,341,330,176,474,135,341,172,331,223, 96,459,371,141,496,
     477,470, 47,461,159,140,418,292,235,506,451,193,172, 32,463,421,107, 45,186,461,
      16,268,517,451,337,347, 96,162,177,418,474,511,231,481,279,242,517,499,337, 58,
     457, 71,379,348,178,211,388,462,498,  6,184),
    TPYIndex_191_list(475, 98,259,261,172,420, 72,221,184,475,366,475,475,291,455,178, 23,297,125,507,
     507,422,268,175,462,234,421,  8,412,242,485,359,507,473,225,372,399, 64,292,459,
     320,229,220,164,479,246,240,341,341,341,221,459,479,257,388,479, 64,462,503,246,
     257,268, 48,  0,523,243,421,387, 83,447,422,177,221,246,141,141,339,470,193,477,
     147, 11,334, 83,208,265,456,151, 33,398,143,467,177, 46,505, 97,483,  8,467, 97,
     295, 83,353,477,194,472,339,440,461, 97,473,458,265,510,  3, 81,505,399,233,351,
     465,477,177,388,177,517,477,231, 18,420,461,461,469,339,339,186,499,446, 11,483,
     221,451,394,173,173,483,177,440, 90,507,342,351,500,517,517,517,347,235,517, 51,
      92,510,178,148,320,482,272,339,328,237,117,109,180,502,477,390,175,105,507,108,
     330,108,500,211,415,483,172,172,168,462,433)
     );
BEGIN
  IF (p_Index>0) AND (p_Index<192) THEN
    RETURN v_list02(p_Index1)(p_Index);
  ELSE
    RETURN 0;
  END IF;
end get_py_index_02;


FUNCTION get_py_index_03(p_Index1 NUMBER, p_Index NUMBER)
RETURN NUMBER IS
  v_list03 TPYIndex_list := TPYIndex_list(
     TPYIndex_191_list(479, 81,467, 42,473,395,265,265,516, 57,456, 15, 11,178,394,161,109,181,468,111,
     347,161,472,494,109,393,184,473,109,468,334,505,236,149,268, 20,467,167,520,458,
     110,477,452, 89,  3, 24,  5,240,213,433,395,165,468,214,467,177,179,507,439,159,
     121,460,147,  0,187,459,215,509,457,394,503,503,147,149,449,432,517,524,509,388,
     291,457,339,506,477,472,449,235, 43,450,461,110,468,477,487,166,467,265,475,479,
     399,451,348,254,278,221,473, 57,474,417,337,177,189,149,453, 43,339,149,472,229,
     172,258,491,462,149,268, 61,291,501,166,147,468, 54,233,421,180,331,235,457,477,
     178,165, 69,475,475,229,421,439,461,110,393,502,149,477,460,464,388,177, 13,180,
     472,  3,475,366,259,229, 46,213, 85,446,474,168,247,364,240,246,243,387,422,472,
     510,485,477,161,399, 32,394,497,341,467,216),
    TPYIndex_191_list(478,346,111,328,111,236,209,446,307,433,222,524,266,450,444,339,479,520,450,439,
     222,223,240,332,399,429,361,  7, 97,433,229,350,182, 18,505, 59,366,341,483,456,
     470,108,518,361,503, 97,252, 48,477,125,133,507,176,388,449,182,252,507,484,110,
      89,459, 57,  0,399,162,463,298, 50,411,485,179,172,254,328,  5,111,477,117,278,
     161,475,510,463,474, 98,502,487,524,394, 97,242,411,278,505,420,457,138,117,268,
     477,475,475,395,295, 18,477,291,219,151,317,108,508, 69, 59,479,117,399,390,411,
     393,357,481,507,522, 70,136,337,  6,117,117,526, 22,498,408,510,320,395,138, 40,
     474,182,237,257,229,364,493,373,481,470,339,505,477,460,505,229,379,191, 24,361,
       8,361, 24,518, 50,477, 59,525,524,106,106,483,107,133,500,229,478,507,395,117,
     366,477,209,349,377,469, 97, 56,483,491,446),
    TPYIndex_191_list(479,178,237,500,470,372,505, 15,479,216,180,334, 16,369,457,222,237,112,339,452,
     187,147,478,350,482,240,322,514, 81,469,441,493,482, 18, 81,147,507,361, 15,459,
     164,449,306,173,433,172,461,247,212, 34,111,411,408, 90,347,479,184,215,517, 42,
     451,180,229,  0, 24,458,115,423,507,220,231,517,229,339, 24,245,411,341,339, 28,
      42,503,110,320,335,167, 47,493,234,483,483,136,142, 89,123,450, 67,108, 47,500,
     339,484,472,483,352,477,393,457,517,413,220,521,521,111, 46,348,295,449,242,149,
     346,509,184,184, 47,526,342,471,328,517,518, 23,322, 87, 51, 43,258,162,175,141,
     457, 72,141, 83,507,352,274,117,128,322,388,477,393, 97,117,451,451,173,520,175,
     477,457,472,472,500,483,151,455,329, 18,474,210,467,371,473,219,472, 16,166,214,
     178,214,408,112,445,507,271,254,209,161,435),
    TPYIndex_191_list(483,482,411,484,473,505,329,475,340,475,405,483,451,257,431,172,178,365,165,224,
     352,460,395,421,487,393, 51,328,173,477,505,117,306,261,136,179,418,474,462,484,
     518,266,413,173,474,178,165,147,341,249,484,364,395,507,452,435,364,422,499,408,
     394,194,457,  0,136,339,193,416,317,423,125, 57,505,300,172,178,342,459,257,467,
     123,517,445,345,473, 83,173,507, 72,240,377,457,172,231,166,481,341,143,121,121,
     442,162,393,524,322,482,176,161,164,141,477,477,124,192,141,141,449,507,514,487,
     222, 46,520,229,466,348,403,439,139,494,413,225,242,232,261,247,177,413,194, 21,
     242,233,503,498,399,251,294,473,433,322,510,386,352,175, 61,172,472,469,507,470,
     507,524, 61,337,399,162,214,505,388,457, 57, 83,110,268,456,359,235,237,345,459,
     370,108,500,223,487,405,443, 47,422,259,461),
    TPYIndex_191_list(186,463,166,172,306,445,297,369,439,497,111,349,472,155,347,136,237,223,124,457,
     394,518,376,172, 90,180,175, 51, 68,399,176,235,280,478,166,388,524,468, 47,122,
     184,524,477,337,112,166, 71,172,415,333, 47, 51,511,166,172,178,173,499,175,342,
      72,477, 21,  0,411,391,229,478,423,420,262,339,442, 24,168,172,341,291,297,477,
     124,191,478,368,348,472,339,261,502,141, 57,172,214,334, 79, 51,125,262,482,507,
     165,341,225,234,372,242,229, 64,247,264,166,313,247,507,124, 91,484,485,110,517,
     412,231,176, 51,348,510,247,472,229,510,347,178, 98,413,163,295,483,240,220,177,
     459,141,184,466,236,479,388,478,482,479,460,299, 25,500,231,184,403,391,524, 61,
     352,351, 31,183,483,246,229,523,243,422,186,472,221,221,510,246,229,  7,279,483,
     236,140,477,459,467, 44,457,339,194,478,186),
    TPYIndex_191_list(457,467,458,214,222,463,412,462,467, 53,478,341,463,341, 54,137,478,483,461,475,
     473,421,354,313,161,461,164,467,321,477,461,467,446,231, 51,477, 98,483, 58,164,
      26, 26,184,341,507,379, 48,379,508,417,415,229,494,483,229,214, 98,503,452,268,
     474,394,467,  0,186,340,350,413,348,477,475,475, 30,258, 85,505,487,452, 50,431,
     179,389,478, 84,182,214, 64, 70, 91,176,231, 23, 91,175,175,510,394,477,462,353,
     345,474,470,166,353,339,351,166, 92,477,461,139,257,  3,178,328, 42,446,446,328,
     234,173,374,271,445,470,106,364,459,184,350,306,446,320,184, 97, 18,376,254,415,
     399,445,194,418,376,399,271,254,439,364,500,378,500,259,242, 85,186,339,473,282,
      23,393,457,457,348,471, 89,473,487,506, 24, 71,404,224,291,108,350,314,494,262,
      84,517, 54,449,108, 69,445,252,482,332,341),
    TPYIndex_191_list(483,483,441,182,507,507,341,180,180,444,187,159,352, 20,147,508,318,469,165,482,
     467,467,487,472, 70,482,161,168,307,268,456, 49,318, 18,507,317,518,488,237,494,
     112,257,488,445,505,505,477,107,432,408,213,479,184,477,173,508,166, 16,494,510,
     482,136,161,  0,333,518,507,413, 47,408,184,469,394,469,117,172,139, 70,478,509,
     475,166,490, 47,451,160,175,408,106,464,117,518,507,478,456,193,446,472,431,270,
     225,477,261,352,334,461,477,413,213,346,184,333,465,507,165,266,456,351,477,180,
     395,323, 42,179,234,350,451,147,252,482, 25, 90,159,477,506,221,147,229,128,231,
      57,159,477,439,223,458, 49,181,415, 47,320,459,393,215,333,147,348,361,441,461,
     435, 98,487,229,404,408,225,404, 91,487,155,464,423, 58,501,279,484,445, 89,455,
     184,391,232,167,418,346, 73,185,161,143,472),
    TPYIndex_191_list(509,322,149, 43,341,109, 48,242,184,229,503,333,432,483,291,242,261,180,236,245,
     351,483,393,161,161,484,220,348,341,507,478,334, 16,484,452,371,110,484,194,339,
     391,379,339,328,457,484,365,164,175,302,456,435,112,455,431,451,368, 33,151,472,
     159,261,254,  0,479,472,348,394,257,490,167,277,141, 48, 98,231,339,339,257,432,
      62,451, 30,265,334,467,172,175,112,477,478,395,462,506,421,483, 18,265,395,441,
     394,481,184,439,442,350,350,473,240,168,484,278,317,482,352,514,232, 42,472,516,
     151,518,258,479,219,112,241,451,458,479,334,179,472,417,484,459,474,259,517, 47,
     420,418,447,208,378,498,395,245,249,451,490,456,452,342,494,395,  3,487,478,413,
     417,395,  3,317,467,453, 31,264,125,469,165,462, 81,507,479,178,125,415,177,166,
     478,494,403, 57,461,483,466,161, 18, 21,507),
    TPYIndex_191_list(176,208,393,389,261,  6,242,467,482, 42,108,481,142,258,348,483,172,471, 44,457,
     172,242,240,179,143,411,507,121,342,177, 61, 57,513,313,427,475,457,261,422,422,
     421,231,447,420,122,322,518,192,322,501,514,467,216,341,472,403,461, 65,431,176,
     520,479,159,  0,463,399,164,520,215,467,507,331,399,345,334,473,166,178,456,314,
     172,451,461,341,471,457,416, 96,265,370,413,505,520,477,507,449,421,478,462,475,
     498,376,152, 18, 42,399,337,235,451,379,379, 47,181,162,280,223, 66,159,147,487,
     237,159,117,149,151,459,175,388,457,483,242,297,483,235,394, 71,164,494,462,483,
     395,469,236,449,518,481,211, 30,231, 83,475,468,505,251, 70,477,415,328,184,418,
     347,517,299,455,347,321,379,386,451, 51,418,411,435,379,510,231,291,457,399,261,
     297,479,479,259,179,339,339,524,455,423,478),
    TPYIndex_191_list(478, 94, 59,168,348,221,470,194,451, 23,136,341,479, 23,216,110, 31,256,491,451,
     334,491,242,229,482,473,242,408,507,479, 91,450,166,462,317,393, 21, 42,268,237,
     175,379, 47,136, 23,168,459,242,347,364,229,180,461,479,415,451,448,469,510,403,
     220, 94,108,  0,161,220,399,236,479,291,172,231,525,479,235,477,175, 42, 69,358,
     175,221,108,403,484,517,112,391,225,221, 61,351,481,341,107,186,472,479,459,491,
     243,472,229,261,388,421, 71,177, 42,479,149,510,221,221,279,449,243,470,459,472,
     122,472,483,140,461,461,166,159,513,498,462, 48,490,339,508,111,298,452,337,477,
     328,189,317,472,318,271,233,140,463,140,140, 20, 68,458,506,510,194,502,117,  7,
     462,462,236,517,319,420,473,439,388,451,165,509,474,467,155,352,164,466,466,459,
     478,471,509,474,395,451,439,469,490,189,458)
     );
BEGIN
  IF (p_Index>0) AND (p_Index<192) THEN
    RETURN v_list03(p_Index1)(p_Index);
  ELSE
    RETURN 0;
  END IF;
end get_py_index_03;


FUNCTION get_py_index_04(p_Index1 NUMBER, p_Index NUMBER)
RETURN NUMBER IS
  v_list04 TPYIndex_list := TPYIndex_list(
     TPYIndex_191_list(468,506,334,166,140, 45,166, 46,446,234,117,181,462,337,435,517,435,145,222,472,
     467, 48,364,161,457,399,168,470,209,485,461,457,514,351, 81,462,339,446,247,472,
     184,235,215,167,444,457, 65,456,159,184,117,455, 61,112,333,349,371,477,349,463,
     477,345,483,  0,123,328,479,450,394,137,390,446,283,128,451, 46,151,214,508,458,
     487,112,231,464,177, 18,479,510,451,442,388,457,468,302, 42,472,181,181,257,451,
     498,179,349,365,164,108,350,415,473,234,178,493,137,487,278,395,232,135,422, 44,
     487, 25,475,462,457,456,487,151,461,477,487,277,388,349,474,261,341,479,456,133,
     472,342, 18, 21,520,242,175,241,322,415,477,439,186,520,161,477,507,451,237,357,
     313,360,181,215, 64,497,175,457,457,477,461, 48,165, 70,475,470,472,470,461,187,
      79,444,393,345,111,457,483,235,439,390,111),
    TPYIndex_191_list(470,221,257,422,477,181,258,180,446,479,477,469,221,420, 30,457,353,520,341,166,
     510,236,483,477,462,502,166, 68,305, 24,368,461,470,179, 50,423,474,151,221, 21,
     364,234,268,371,247,234,  6,470,213,485,233,229,242,186,233,472,457,462,240,475,
      30,358,485,  0,221, 61,439,139,184, 45,261,422,221,510,221,236,483,502,506,319,
      47,451,147,186,475,522,261, 55,194,492, 85,342,481,342,317, 44,175, 55,483,498,
     262,317, 25, 55,482, 91, 47,298,224,445,361,252,109,123,472,492, 15,408,482,125,
     271,499,352,352,518,252,199,341,229,335,123,507, 16,352, 57,173,112,194,184, 51,
     457, 15,246,178,249,376,451,254, 96,439,345,457,229, 91,234,315,330, 25,457, 50,
     451,359, 50,  7,172, 41,517,151,192,320,160,471,478,164,514,213,508,271,328,184,
     477,464,477,236,328,291,474,482,469, 70, 25),
    TPYIndex_191_list(  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
    TPYIndex_191_list(  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
    TPYIndex_191_list(  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0, 98,  0,  0,  0,171,  0,  0,
       0,248,275,309,  0,338,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  1,  0,  0,  0, 98,  0,  0,  0,171,  0,  0,  0,248,275,309,  0,338,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
    TPYIndex_191_list(  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
    TPYIndex_191_list(  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
    TPYIndex_191_list(  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,
       0, 98,  0, 98,  0,171,  0,  0,248,275,  0,309,  0,  0,  0,  0,  0,  0,  0,  0,
     309,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0, 98,  0, 98,  0,171,  0,  0,
     248,275,  0,309,  0,  0,  0,  0,  0,  0,  0,  0,309,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
    TPYIndex_191_list(  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
    TPYIndex_191_list(  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0)
     );
BEGIN
  IF (p_Index>0) AND (p_Index<192) THEN
    RETURN v_list04(p_Index1)(p_Index);
  ELSE
    RETURN 0;
  END IF;
end get_py_index_04;


FUNCTION get_py_index_05(p_Index1 NUMBER, p_Index NUMBER)
RETURN NUMBER IS
  v_list05 TPYIndex_list := TPYIndex_list(
     TPYIndex_191_list(  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
    TPYIndex_191_list(209,459,468,268,502,178,470,388,418,439,223,517,457,458, 15,507,472,386,147,180,
     315,110,461,328,339, 21,478,220,175,342,215,472,520,507,506,471,234, 38,520,118,
     112,455,484,388,442,471,462,173,329,482,474,416,334,266,412,249,484, 69,483,395,
     149,342,477,  0,505, 31,149,251,176,271, 42,  6,124, 65,111, 18, 18,165,337,235,
     483,514,474,457,461,398, 96,177,125,468, 91,166,211,459,459,297, 20,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
    TPYIndex_191_list(168,366,259,234,482,180,398,242,418,459,261,358,280,246,459,339,186,474,518,242,
     413,350,119,224,  7,159, 81, 54,122,483,339,483, 43,159,456,117,178,471,258, 12,
     485,186,487,186,478, 70,332,342,477,122,333,117,468, 62,135,173,390, 59,357,394,
     393,477,522,  0,237, 18,505,179,177,175,229,140,459,509,472,466,473,467,413,347,
     478,470, 13,460,458,141, 49,467,320,223, 71,479,452, 98,435,431,456,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
    TPYIndex_191_list(456, 47,187,257, 15,435,459, 51,147,468,472,468,466,117,457,236,229,179,417,112,
     449, 83,332,500,379,265,483,220,265,450,483,432, 51,320, 47, 98, 43, 17,242,352,
      84,320,342,517,347,107,179, 91,178,167,483,257, 57,468,431,464, 69,365,265,175,
     451,368,164,  0,462, 54,175,513,473,231,352, 92,471,165,237,395,364,417,474,452,
     456,505,179,479,249,423,237,229,222,432,342, 67,186,502, 23,441, 43,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
    TPYIndex_191_list(215,513, 61,477,339,180,493,350,  6,231,258,478,162,451,456, 79,466,497,470,351,
      71,235,233,349,413,141,180,108,179,237,172,166,180,  3,493, 71,177,142,421,211,
     164,379,415,432, 51,483,179,242,329,399,524,221,457,518,468,368,455,121,225, 91,
     229,507,365,  0,229,491,468,431,141,415,219,240,242,229,221,479,457,460,451,139,
      72,491,475, 25,319,507,229,397,460,344, 11,321,109, 70,113,  0,447,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
    TPYIndex_191_list(161,477, 10,185, 43, 48,238, 71,259,515,333, 20,509,238, 59,479,339,459,241, 81,
     313,513,235,456, 70,453,479,472,432,147, 43,348,393, 42, 42,369,413,393,242,112,
     498,117,333, 87,516,259, 18,237,416,237,271,487,117,128,178,117,432,271,424,176,
     447,117,278,  0,271,271,172,432,121, 18, 68,507,244,317,477,162,483,483,271,187,
     477,237, 85,162, 71,515,176, 47, 43,444,225, 40,237, 85,235,176, 50,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
    TPYIndex_191_list(328, 85, 85,346, 70,399,507,277, 18,123,509,458,467, 46,469,339,471, 65, 18,520,
     469,507,107,507,110,184,388,295,427,439,178,483,166,421, 48,257,180,461,441,252,
     461,414,337, 97,398,477,322,501,139,249,235,172,432,475, 48,328,265, 94,194,471,
      63,393,508,  0,507,483,112,473, 46,441,143,452,164,209,478,186,457,139,477, 55,
     225,308, 83,501,393, 63,477,520,412,379, 84,241,247,347,117,406,345,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
    TPYIndex_191_list(237,223,459,110,421,478,151,459,139,451,299,483,451,481,225,229,399, 70,235,235,
      22,172, 48,473,178,506,256,229,168,220,172,468,479,478,481,421, 83,246,243,243,
      25,446,  7,107,107,346,172,493,254,314, 59,236,268,172,322,124, 98,147, 18, 50,
     341,  3,461,  0,149,165,149,494, 65,149,461,475,149,177,  3,464,165,246,330,151,
     177,122,319,350,353,498,136,187,187,509,498,446,502, 91,339,479, 15,  1,  1,  3,
       3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  4,  4,  4,  4,  4,  4,  4,  4,
       4,  5,  5,  5,  6,  6,  6,  6,  6,  6,  6,  6,  6,  7,  7,  7,  7,  7,  7,  7,
       7,  7,  7,  7,  7,  7,314,  7,  7,  7,  7,  8,  8,  8,  8,  8,  8,  8,  8, 11,
      11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12,
      12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13),
    TPYIndex_191_list(502,151,151, 25,449,483,108,117,350, 72,242,500,229,179,467,191,468,  4,247,467,
     509, 71,  4,136,229,122,450,339,484,459,463,457,112,265,266,395,487,317,109,257,
     459,395,479,506,474,393,168, 68,505,213,467,393,257,268,510,505,395, 85,291,518,
      44,109,317,  0,240,439,507, 81,281,266,470,505,473,268,508,268,257,461,147,164,
      47,512,185, 98,251,459,457,215,388,432,245,449,228,395,349,234,506, 13, 13, 13,
      13, 13, 13, 13, 13, 13, 13, 13, 13, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
      15, 15, 15, 15, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18,
      18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,328, 18, 18, 18, 18, 20, 20,
      20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 23, 23,
      23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24),
    TPYIndex_191_list(229,220,524,185,328,167,242,494,509,483,167,249,458,464,166,142,490, 57,175,257,
     160,468,432,467,107,455,141,261,453,208, 71,432,349,268,111,494,501,477, 90,208,
     268,405, 61,247, 48,258,141,164,405,457,337,393,233, 45,459,475,469,456,451,175,
     475,  3,166,  0,175,502,257, 50,378,297,470,474,485,259,262,332,262,225,213,468,
     262,168,242,259,240,352,251,457,422,191,510,347,483,406,517,186,393, 24, 24, 25,
      25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 25,
      26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
      28, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 33, 33,
      33, 33, 33, 35, 35, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 42,
      42, 42, 42, 42, 42, 42, 42, 42, 42, 43, 43)
     );
BEGIN
  IF (p_Index>0) AND (p_Index<192) THEN
    RETURN v_list05(p_Index1)(p_Index);
  ELSE
    RETURN 0;
  END IF;
end get_py_index_05;


FUNCTION get_py_index_06(p_Index1 NUMBER, p_Index NUMBER)
RETURN NUMBER IS
  v_list06 TPYIndex_list := TPYIndex_list(
     TPYIndex_191_list(160,479,509,177,497,485,  7, 87,339,518,456,503,340,342, 70,186,229,117,452, 98,
     192,507,178,332, 98,503,415,447,179,268,522,483,246,445, 98,271,510,301,333,236,
     337,224, 98,334,481,213,199,352,510,213, 98,340,242,451,  3,478,472,333,223,159,
     348,451,345,  0, 36,348,353, 42,222,159,483,461,458,252,246,481, 45, 45,472,386,
     215,136, 36,162,242, 46,303,411,517,199,472,515,206, 47,339,520,348, 43, 43, 43,
     501, 43, 43, 43, 43, 43, 43, 43, 44, 44, 44, 44, 44, 44, 44, 44, 44, 45, 45, 45,
      45, 45, 45, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 47,
      47, 47, 47, 47, 47, 47, 47, 47, 48, 48, 48,395, 48, 48, 48, 48, 48, 48, 48, 48,
      48, 48, 48, 48, 49, 49, 49, 49, 49, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
      50, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51),
    TPYIndex_191_list(235,187,317,265,500,151,457,228,478,456,339,245,280,368,472, 87,445,479,194,451,
     406,505, 92,458, 71,431,280,432,339, 96,112,353,353,249,133,462, 98,237,431,422,
     194,328,451,432,471,339,231,451,487,515,219,316,474,513, 42,339,345,322,237,242,
     191, 55, 46,  0,478,225,330,339,510, 65,520, 58,245,172,388,223,497,175,457, 87,
      83,317,488,345, 81,229,175,457,501,345,459,483,515,345,194,494,225, 51, 51, 51,
      51, 51, 51, 53, 54, 54, 54, 54, 54, 54, 54, 55, 55,514, 55, 55, 55, 56, 56, 56,
      56, 56, 57, 57, 57, 57, 57, 57, 57, 58, 44, 59, 59, 59, 59, 59, 59, 59, 59, 59,
      59, 59, 59, 61, 61, 61, 61, 61, 61, 62, 63, 63, 63, 63, 64, 64, 64, 65, 65, 65,
      65, 65, 65, 65, 65, 66, 66, 66, 67, 67, 67, 67, 67, 67, 68, 68, 68, 68, 68, 68,
      69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69),
    TPYIndex_191_list(178, 51,475,353, 71,477,328,328,483,332,339,477,194,175,483,368,319, 59, 25,473,
     249,463,213,225,225,507,229,246,108,353,319,479,229,240,240,268,403,139,221, 27,
     472,362,485,418,249,462,474,507,109, 94,508,446,477,395,482,507,433,117,261,414,
     257, 41,247,  0,483,456,510,141,458,507,124,124,404,179,393,121,215, 81,423,136,
     139,524,236,242, 72,507, 18, 51,166,482,478,518,168,505,484,456,459, 69, 70, 70,
      70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 71, 71, 71, 71, 71, 72, 72,
      72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 73, 73, 73, 79, 79, 79, 79, 79, 79, 79,
      81, 81, 81, 81, 81, 81, 81, 81,499, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 83,
      83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 84, 84, 84, 84, 84,
      84, 84, 84,433, 85, 85, 85, 85, 85, 85, 85),
    TPYIndex_191_list(473,507,477,257,408, 81, 15,505,481,172,124,422,408,249,418,117,468,339,483,339,
     408,421, 70,141,415,229,299,459, 72,229,485,507,491,225,365,462,441,361,518,276,
     507,459,292,350,111,254,487,507,180,507,483,209, 11,328,291,229,482,328, 25,236,
     292,526,507,  0,184,168,439,507,216,151,478,518,507,361, 91,510,299,337,124,494,
     445,215,122,180,431,441,471,245,242,136,526,516, 12,339,507,215,228, 87, 87, 87,
      87, 87, 87, 87, 87, 87, 88, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 90, 90, 90,
      90, 90, 90, 90, 90, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 92,
      92, 92, 92, 92, 92, 94, 94, 94, 94, 96, 96, 96, 96, 96,444, 96, 96, 96, 97, 97,
      97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
      98, 98, 98,100,106,106,106,106,106,106,106),
    TPYIndex_191_list(322,235,524,483,413,446,477,457, 20,172,117,328,306,178,508,520,467, 47, 72,459,
     518,483,467,507,193,136,364,415,364,172,192,388,261,507,172,242,413,172,479,452,
     350,217,477,165,346,172,461,337,177,517,508,524,247,415,299,379,166,358,306,483,
     332,518,443,  0,452, 47,168,213,247,319,379,517,229,491,471,483,393,180,474,223,
     474, 13, 24,447,510,319, 84,456,447, 55,474,461, 47,208, 70,517,467,106,107,107,
     107,107,107,107,107,107,108,108,108,108,108,108,108,108,108,108,108,108,108,108,
     108,108,108,109,109,109,109,109,109,109,109,109,109,109,110,110,110,110,110,110,
     110,110,110,110,110,110,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
     111,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,115,116,117,117,
     117,117,117,117,117,117,117,117,117,117,117),
    TPYIndex_191_list(413,139,517,455,447,475,349,474,474,433, 44,432, 84,241,233,457,456,214, 55,502,
     212,212, 47, 65,233,493, 64,345,349, 91,493,240,346, 51,395,117,341, 51,159,339,
     149,394,111,263,351,510,236,285, 24,  8,408,159,505, 84,477,399,180,351,333,229,
     513, 35, 79,  0, 66,448,180,191,180,224,322, 48,252,510,449,177,414,347,471,515,
     484,148,179,328,477, 89,388,458,510,276,136,346,265, 13,388,320,236,117,117,117,
     117,117,117,117,117,117,117,117,337,117,117,117,117,117,117,117,117,117,117,117,
     117,117,117,117,117,117,117,117,117,119,119,121,121,121,121,121,121,122,122,122,
     122,122,122,122,122,122,122,122,123,123,123,123,123,123,123,123,123,124,124,124,
     124,124,124,124,124,124,124,125,125,125,125,125,125,125,125,125,125,125,144,125,
     125,125,125,125,126,127,127,128,128,128,128),
    TPYIndex_191_list(301,117,108,122,108,395,254,461,349,265,246,141,351, 48,478,474, 18,216,177,487,
     366,172,148,508,220, 71, 33,117,441,229,222,184,139,459,147,481,458,507, 47,414,
     510,526,435,173,124,122,213,487,309,461,337,220,521,315,328,125,420,138,483,175,
     502,161,506,  0,498,509,242,235,354,117,498,136,341,187,515, 33,522, 25,468, 20,
     416,459,333,464,161,477,485, 57,247,456, 89,461,172,178,464,257,108,128,128,128,
     133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,135,135,135,135,135,
     135,135,135,135,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
     136,136,137,137,137,137,137,137,138,138,138,139,139,139,139,139,139,139,139,139,
     139,139,140,140,140,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
     141,142,142,142,143,143,143,143,143,143,144),
    TPYIndex_191_list( 92,112,510,159,346,350,263,341,136,395,487,151,422,485, 50,371,506,295,341,461,
     240,322, 91,517, 51,395,510,342,240,175, 26,166, 18,510, 61,472,491,523,328,330,
     483,513,499,387,143,477,161, 42,208,333,493,172,247,172,292,417, 64, 84,417,224,
     232,461, 25,  0,261,408,422,233, 70,117,175,265,214, 69,177,513,223,461,242,395,
     491,339,315,339,328,122,184,242,242,472, 71,374,511,135,341,231,395,145,145,145,
     145,145,145,145,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
     147,147,147, 16,148,148,149,149,149,149,149,149,149,149,149,151,151,151,151,151,
     151,151,151,151,151,268,151,151,151,151,151,151,151,152,152,154,154,154,154,155,
     155,155,155,155,159,159,159,159,159,159,159,159,159,160,160,160,160,160,160,160,
     161,161,161,161,161,161,161,161,161,161,161),
    TPYIndex_191_list(221,214,483,485,149,505,420,431,295,423,477,339,427,513,509,317,412,509,341,517,
     427,242,242,175,445,479,483,220,240,346,231,221,341,485,508,351,231, 20, 92,523,
     229,395,246,479,485,517,483,108,393,503,393,307,151,291, 66,501,341,499,328, 11,
     456,386,192,  0,365, 18,415,478,503,261,420,161,122,184,268,509,229,413,159,439,
     379,235,514,  8,223,106,351,151,459,117,229,485,242,184,339,  8,501,161,161,161,
     161,161,161,161,162,162,162,162,162,162,162,162,162,163,163,163,163,163,164,164,
     164,145,164,164,164,164,164,164,164,164,164,164,165,165,165,165,165,165,165,165,
     165,165,165,165,165,165,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
     166,166,166,166,166,166,166,167,167,167,167,167,167,168,168,168,168,168,168,168,
     168,168,168,172,172,172,172,172,172,172,172),
    TPYIndex_191_list(162,162,376,422, 20,262,520,175,229,462,117,306, 15,136,466,173,514,422,376,111,
     176,268,376,376,306,457,232,211, 25,164,399,172,459,442,295,229,526, 81,295,433,
     221,408,182,133,506,182,482,172, 40,509,470,485,176,483,178,449,361,452,350,276,
     518,440,298,  0,116,178,399,516,328,505,386,159,507,172,111,487,361, 70,179,109,
     522,182,498,  7,117,507,339,509,159,498,457,117,477,393, 25,510,351,172,172,172,
     172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
     172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
     172,172,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,175,
     175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
     175,175,175,191,175,175,175,175,175,175,175)
     );
BEGIN
  IF (p_Index>0) AND (p_Index<192) THEN
    RETURN v_list06(p_Index1)(p_Index);
  ELSE
    RETURN 0;
  END IF;
end get_py_index_06;


FUNCTION get_py_index_07(p_Index1 NUMBER, p_Index NUMBER)
RETURN NUMBER IS
  v_list07 TPYIndex_list := TPYIndex_list(
     TPYIndex_191_list(236,510,390,122,473,117,445,505, 69, 51,395,508,468,522,181, 11,351,268,399,524,
     213,180,361,148,477,178,510, 50,210,268,186,213,161, 59,164,128,423,462,209,461,
     352,121,246,470,322,459,117,458,439,364,433,478,225,462,185,145, 85,439,408,176,
     460,166,186,  0,175,468,507,452,505,247, 47,350,399, 12,439,461,449,459,128,466,
     431,466,462,159,457,117,435,415, 94,215,117,180,161,507,472,181,112,175,175,175,
     175,175,175,175,175,176,176,176,176,176,176,176,176,176,176,176,176,176,177,177,
     177,177,177,177,177,177,177,177,177,177,177,177,474,177,177,177,177,177,177,177,
     177,177,177,177,177,177,178,178,178,178,178,178,178,178,178,184,178,178,178,178,
     178,178,178,178,178,172,178,178,178,178,178,178,178,179,179,179,179,179,179,179,
     179,179,179,179,179,179,179,179,179,179,179),
    TPYIndex_191_list(172,467,361,520,393, 97,234,247,232,423,352,390,339,516,339,449,506,459,398,477,
     423,449,123,450, 17,515, 28,143,522,245,237,477,500, 18, 58,236,262,339,346,432,
     520,167,521,457,518,464,232,179,110,369,265,483,520,108,247,467,479,389,339,467,
     460,175,194,  0,459,368,262,339, 92,508, 81,265,263,484,475, 13,408,350, 20,164,
     128,520,262,451,117,451,467,135,263,462,231,520,329,487,478,431,137,179,179,180,
     180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
     180,180,180,180,181,181,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
     182,182,182,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
     184,184,184,184,184,184,184,184,185,185,185,185,185,185,185,186,186,186,186,186,
     186,177,186,186,186,187,187,187,187,187,187),
    TPYIndex_191_list(507,487, 47, 42, 69,458,484,520,467,479,451,128,385,479,179,477,515,291, 12,161,
     317,509,175,417,352,403,487,458,415,457,364,423,117,487,505,124,366,161,497,427,
     468,413,505,520,423,165, 28, 18,112, 63,229,417,478,457,520,225,513,341,251,507,
     247,271,330,  0,231,468,520,172,461,415,247, 17,477,493,271,342,167,459,172,386,
     466,357,468,415,345,497,526,507,388,376,235,483,108,359, 58,525,175,187,187,187,
     187,187,188,188,188,125,189,189,189,189,189,191,191,191,191,191,191,192,192,192,
     192,192,192,192,193,193,193,193,194,194,194,194,194,194,194,194,194,194,194,194,
     194,194,194,198,198,198,198,199,199,206,206,206,206,208,208,208,208,209,209,209,
     209,209,209,209,210,210,210,210,210,211,211,211,211,212,212,213,213,213,213,213,
     213,213,213,214,214,214,214,214,214,214,214),
    TPYIndex_191_list(359, 42,369,466,166,162,523,457,342,487, 68,479,166,457,379,175,176,164,493, 61,
     462,517, 18,421,477,299,415,477,387,467,172, 23,341,221,337,470,339,322,474,268,
     225,462,523,213,482,467,225,459, 42,177,242, 42,479,388,460,459,524,523,246,457,
     221,225,231,  0,159,361,510,505, 85,457,479,423,487,459,415,462,116,116,339, 25,
     333,460,502,123,479,139,525,421, 31,339,453,479,225,421,242,408,123,214,214,214,
     215,215,215,215,216,216,216,216,219,219,219,219,219,219,219,220,220,220,221,221,
     221,221,221,221,221,221,221,221,221,221,221,221,221,222,222,222,222,222,222,222,
     223,223,223,223,223,223,223,223,223,224,224,225,225,225,225,225,225,225,225,225,
     225,225,228,228,228,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
     229,229,229,229,229,229,229,229,229,229,229),
    TPYIndex_191_list(355,393,136,510,184,259,265,137,431,185,117,393,138,517,483,  4,107,408,249,237,
     328,107, 44,451, 18,172, 49,237,185,261,502,246,328,172,172,243,261, 68,473,482,
     482,111,  7,473,136,482,492,257,477,510,477,364,354,342,164,477,477,473,342,459,
     483,222,484,  0,108,388,111,388,231,300,342,159, 49,111,159, 48, 65,117,458,321,
     219,334,242,507,483,457,462,457,194,166,166,461,386,159,176,509,386,229,229,229,
     229,229,229,229,229,232,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
     232,232,232,232,232,232,232,232,232,232,232,233,233,233,233,233,233,233,233,224,
     233,233,233,233,234,234,234,234,234,235,235,235,235,235,235,235,235,235,235,235,
     235,236,236,236,236,236,236,236,236,236,236,236,236,236,236,237,237,237,237,237,
     237,237,237,237,237,237,240,240,240,240,240),
    TPYIndex_191_list( 48,468, 48,520,449,166,160,151,330,231,351,  6,235,321,345,  6,166,468, 72,446,
     135,135,135, 85,368,277,513,435,328,477,351,173,184, 51,245,178,498,241,172,223,
     168,482,163,477,347,487, 70,159,507,446,505, 45,506,482,517,433,307,471,503,381,
     149,394,234,  0,180, 18, 81,143,452,467,333, 61, 87,446,435,184, 61,214,231,231,
     453,214,231,231, 61,394,411,435,214,503,507, 70,297,346,291,435,435,240,240,240,
     240,241,241,241,241,241,241,242,242,242,242,242,242,242,242,242,242,242,242,242,
     242,242,242,242,242,242,242,247,247,247,247,247,247,247,247,247,247,247,247,247,
     247,243,243,243,243,243,243,244,244,245,245,245,245,245,245,245,246,246,246,246,
     246,246,246,246,246,246,246,246,249,249,249,249,249,249,249,249,249,250,250,250,
     250,250,250,251,251,251,251,251,251,251,251),
    TPYIndex_191_list(240,502,408,413,502,477,350,198, 32,339, 81,164, 48,361,366,484, 40,347,111,320,
     318,482,357,452,339,328,457,457,198, 85,110,  7, 25,467,432,518,209,507,291,333,
     518,509,459,271,351,194, 48,473,318,507,465,106,155,518,214,506,433, 65,257,462,
     462,250,462,  0,296,452,452,466,199,482,155,319,388,435,257, 57,393,351,425,524,
     172,482,463,445, 47,443, 90,280,328,136,229,501,415,178,232,404, 21,251,252,252,
     252,252,252,252,254,254,254,254,254,254,254,254,254,254,254,254,256,257,257,257,
     257,257,257,257,257,257,257,257,257,257,257,257,257,258,258,258,259,259,259,259,
     259,259,259,259,261,261,261,261,261,261,261,261,261,261,261,261,261,261,262,262,
     262,262,262,262,262,262,262,263,263,263,263,263,263,263,263,264,264,265,265,265,
     265,265,265,266,266,266,266,266,266,267,268),
    TPYIndex_191_list(245,329,225,352,160, 70,282,277,361,393,515,184, 89,328,168,455,257,368,513, 48,
     246,313, 81,  4,280,402,487,508,365,441,451,186,173, 92, 18, 43,472,447,398,422,
     413,515,477,233,172,328,462,247,313, 43,242,168,318, 53,176,242,513,242,177,479,
     247,469, 34,  0,439,291,233, 65,214,461,444,317,507,177,456, 65,476,460,415,111,
     511, 70,211,299,186, 51,185,219,231,444,339, 65, 23,470,366,485,492,268,268,268,
     268,268,268,268,268,268,268,268,268,268,268,268,268,270,270,270,271,271,271,271,
     271,271,271,271,271,271,271,271,271,271,271,276,276,276,276,276,276,276,277,277,
     277,277,277,278,278,278,279,280,280,280,280,280,281,282,282,284,285,291,291,291,
     291,291,291,291,291,291,291,291,292,292,292,292,292,292,292,293,293,294,294,295,
     295,295,295,295,295,295,296,297,297,297,297),
    TPYIndex_191_list(459, 21,464,215,234,472,242,168,488,246,351,492,243,291,491,459,455,181,235,181,
     177,172,149,466,262,295,125,175,507,507,466,420,459, 40,457,483,464,184,182,463,
     391,182,432,395,421,337,337,139,339,432,458, 72,108,314,420,108,108,242,236,458,
     349,318,210,  0,117,493,112,229,483,222,446, 25,341,184,165,520, 20,271, 85, 90,
      12, 40,477, 31,241, 69,469,474, 79, 71,342,242,477,172,175,455,339,297,297,298,
     298,298,298,299,299,299,299,301,301,301,307,302,303,303,306,306,306,306,309,313,
     313,313,313,313,313,313,314,314,314,314,314,314,315,315,315,315,315,315,317,317,
     317,317,317,317,317,317,318,318,318,318,318,319,319,319,319,319,319,319,320,320,
     320,320,320,320,320,320,320,321,321,322,322,322,322,322,322,322,322,322,322,322,
     322,322,322,328,328,328,328,328,328,328,328),
    TPYIndex_191_list(242,242, 42,403,175,333,472,472, 32,224,435,433,177,322,477, 40,262,122,483,458,
     518,166,415,507,444,451,339,452,361,117,510,162,186,172,  6,521,254,362,148,478,
     482,477,346,328,431, 81,229,481, 15,477,510,291,314, 24,466,474,459,159,526, 89,
      85,295,161,  0,257,394,137,261,451,117,518,507,172, 61,446,469,246,229,364,507,
      46,483,466,518,234,456,172,141, 59,135,140,294,483,518,320,271,508,328,328,328,
     328,328,328,328,328,328,329,329,329,329,330,330,330,330,331,331,332,332,332,332,
     332,333,333,333,333,333,333,333,333,333,334,334,334,334,334,334,334,334,335,337,
     337,337,337,337,337,337,337,337,337,337,337,337,337, 13,339,339,339,339,339,339,
     339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,
     339,339,339,339,339,339,339,339,339,339,340)
     );
BEGIN
  IF (p_Index>0) AND (p_Index<192) THEN
    RETURN v_list07(p_Index1)(p_Index);
  ELSE
    RETURN 0;
  END IF;
end get_py_index_07;


FUNCTION get_py_index_08(p_Index1 NUMBER, p_Index NUMBER)
RETURN NUMBER IS
  v_list08 TPYIndex_list := TPYIndex_list(
     TPYIndex_191_list(341,510,164,117,121,418, 54,180,106,  4,345, 48,333,341,223,399,514, 68, 33,483,
      91,451,229, 90,117,361,478,337,487,415, 47,299,456, 22,457,128,510,268,514,526,
     445,350,417, 46,322,457,464,479, 45,187,472, 67,147, 67,173,450,482,365,461,459,
     452,178,278,  0,271,441,286,252, 59, 81,351, 89,521,219,242,451,361,215,337,518,
     124,143,245, 50, 56,500,258,229, 13,347,185,347, 81,386,179,502,507,340,340,341,
     341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,
     341,342,342,342,342,342,342,342,342,345,345,345,345,345,345,345,345,345,345,345,
     345,345,345,345,346,346,346,346,346,347,347,347,347,347,347,347,347,347,347,347,
     348,348,348,348,348,348,348,348,348,348,348,348,348,349,349,350,350,350,350,350,
     350,350,350,351,351,351,351,351,351,351,351),
    TPYIndex_191_list(128,210,347,472,450, 17,509,175,235,421,432, 72,161,151, 57, 43,164,117,220,386,
     472,477,433,339,449, 33,505,494,182, 18,477,259, 14,319, 87,350,194,460,449,483,
     483,117,231,468,278, 33,455, 57,461,329,271,  4,479,216,216,176,262,526,526,522,
     365,457,475,  0,472,351,175,117,247,175,321,159,159,160,472,441,518,348,261,165,
     393,121,509,341,451, 25,451,172, 92,474,417,352,505,470,395,221,520,351,351,351,
     351,351,352,352,352,352,352,352,352,352,352,352,352,353,353,353,353,353,353,353,
     353,354,354,357,357,357,357,358,358,358,358,358,359,359,359,360,360,361,361,361,
     361,361,361,361,361,361,361,362,362,363,364,364,364,364,364,364,364,364,364,364,
     365,365,365,366,366,366,366,366,366,366,366,366,366,368,368,369,369,369,370,370,
     371,371,372,372,372,374,374,374,374,376,376),
    TPYIndex_191_list(474,484,257,487,399,513,139,357,469,446,451,482,412,478,395, 57,395,487,505,366,
     229,353,484,229,184,457, 51,467,441,237,455, 83,341,522,334, 67,484, 51,483,317,
     337,276,457,111,487,371, 31,261,416,266,412,237,457,136,222,125, 67,422,246,468,
     517,141,520,  0,142,526,433, 33,320,446,393,222,236,433,466,254,439,510,  4,231,
     520,333,467,179,442,178,451,443, 32,483,477,518, 18,242, 26,501,225,376,376,377,
     377,377,378,378,378,378,379,379,379,382,383,386,386,386, 40,386,386,386,386,386,
     387,387,388,388,388,388,388,388,388,388,388,388,388,388,388,388,388,388,389,389,
     389,389,389,389,389,389,390,390,390,390,390,390,390,390,390,390,390,391,391,391,
     391,391,391,391,391,391,391,391,391,393,393,393,393,393,393,393,393,393,393,393,
     393,393,393,393,393,394,394,394,394,394,394),
    TPYIndex_191_list(342,251,472,236,457,330,142,147, 81,242,391,389, 81,470, 25, 81,498,393,468,161,
       6,261,247,508,334,176,261, 61,294,166,187,478,388,478,143, 46,161,386,208,341,
     249,492,494,229,451,172,470,394,259,313, 42, 83,369,225,483,345,510,210,175,250,
     487, 13,482,  0,242,474, 98,431,110,186,110,366,111,214,405,471,467,117,422,456,
      89,408,461,457,372,487,390,175,416,236,483,458,408,299,468,487,483,394,394,394,
     394,394,395,395,395,395,395,395,395,395,395,395,395,395,393,395,395,395,395,395,
     395,395,395,395,395,395,395,395,395,395,395,395,395,395,395,395,395,395,395,395,
     395,395,395,395,395,395,395,395,395,398,398,398,398,398,398,398,398,398,398,399,
     399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,
     399,399,399,399,399,399,399,399,399,399,399),
    TPYIndex_191_list(461,149,  3,166,166,172,518,460,449,264,228,176, 30,393,379,231,194,484, 68,507,
     422,500,416,472,108, 87,462,136,510,175,193,372,470,474,  8, 94,332,484,297,509,
     455,330,339,493, 46,505,106,291,479, 61,461,339,107,175,483,214, 20,517,261,221,
     179,349,346,  0,446,459,413,247,477,467,462,477,219,225,177, 81,507, 15,474,268,
     164,319,412,421,443,349,345,451,237,166,313,193,487, 13,229,510,510,399,400,400,
     401,401,401,401,402,402,403,403,403,404,404,404,404,405,405,405,405,406,406,406,
     406,408,408,408,408,408,408,408,408,408,408,408,408,408,395,408,408,411,411,411,
     411,411,411,411,411,412,412,412,412,413,413,413,413,413,413,413,413,413,466,413,
     413,414,414,414,415,415,415,415,415,415,415,415,415,415,415,416,416,416,417,417,
     417,417,417,417,417,417,418,418,418,418,418),
    TPYIndex_191_list(  3,235,468,347,220,494,456,369,369,347,242,413,443,252,487,333,483,470,172,181,
     468,350,413,181,112, 25,460,477,459,483,184,459,459,478,342,479,240,440,162,485,
     236,474,257,221,214,221,172,422,251,225,225,166,411,507,451,214,163,229,172,225,
     163,246,172,  0,214,242,175,375,427,225,352,461,477,243,258, 22,507,461,184,161,
     467, 67,117,467,242,161,149,177,184, 13,472,500,500,214, 23,457,399,418,418,418,
     418,420,420,420,420,420,420,420,420,420,421,421,421,421,421,421,421,421,421,421,
     421,421,421,421,421,421,421,421,422,422,422,422,422,422,422,422,422,422,422,422,
     422,423,423,423,423,423,423,423,423,423,423,423,425,427,427,427,427,431,431,431,
     431,431,431,431,431,431,431,431,431,431,431,431,432,432,432,432,432,432,432,432,
     433,433,433,433,433,434,434,434,435,435,435),
    TPYIndex_191_list( 84,350, 87,446,186,503,475,483,147,518,460,109, 98,  7, 48,341,452,485,485,187,
     339,439,507,484,353,482,347,339,508,271,450,111,111,148,117,357,319,291,425,333,
      81,184,229,117,498,467,328,328,459, 84, 22, 24,500,434,136,479,246, 59,166,252,
     117,234,477,  0,459,229,477,333,346,391,477,450,268,346,141,349,223,464,178,350,
     173,485, 45, 15,147,468,505,337,459,232, 18,484,482,178, 70, 83,166,435,435,435,
     435,435,435,435,439,439,439,439,439,439,439,439,439,439,439,439,439,440,440,440,
     440,441,441,441,441,441,441,441,441,441,441,441,442,442,443,443,443,443,443,443,
     444,444,444,445,445,445,445,445,445,445,445,445,445,445,447,447,447,447,447,447,
     447,448,448,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,
     450,450,450,450,450,450,450,450,450,450,451),
    TPYIndex_191_list(411,184,339,483,187,457,245,229, 85,423,215,147,147, 12,110,451,444,487,417,341,
     451,291,451,232, 89, 98, 11,517,450, 30,261,446,219,178,435,254,467,262,178,395,
     468,472,365,451,117,484,257,451,368,462,458,479,395,508,422,510,520,431,484,259,
     219, 91,350,  0,457,455,487,483,479,176, 11,408, 59,457,453,231,317,364,172,456,
     466,147,477,328,162,477, 91,285,458,161,166,249,477,452,479,427,508,451,451,451,
     451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,
     451,451,451,451,451,451,451,451,451,452,452,452,452,452,452,452,452,452,452,453,
     453,453,455,455,455,455,455,455,455,455,455,456,456,456,456,456,456,456,456,456,
     456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,
     457,457,457,457,457,457,457,457,457,457,457),
    TPYIndex_191_list( 31,409,339,433,389, 81,242,451,507, 46,351,328,483,175,241,347,478,176,452,461,
     251,503,503,249,483,237, 61,229,251,461, 43,268,524,408,350,425,507,322,345,351,
      22,233,141,457,339,513,110,233,186,186,478,431,177,359,461,456,508,470,408, 51,
      47, 71,229,  0,445,477,180, 68,339,172,460,391,347,479, 41,229,495,468,510,494,
     462,252,462,339,364,175,149,517,178, 23,151,108,225,178,219,265,229,457,457,457,
     457,457,457,457,457,457,457,457,457,457,457,457,457,457,457,459,457,457,457,457,
     457,458,458,458,458,458,458,458,458,458,458,386,458,458,459,459,459,459,459,459,
     459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,
     460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
     461,461,461,469,461,461,461,461,461,461,461),
    TPYIndex_191_list(350,295,242, 91,461,510,240,229,240,318,475,328,389,475,479,399,457, 30,351,352,
      30,251,178,510,517,165,307,320,508,250,106,194,264,457,191,484,351,236,468,399,
     439,460,483,161,451, 72, 49,451, 72,516,122,483,477,117,321,178,508, 70,477,508,
     178,507,462,  0,357,507,187, 41,477,357,445,236,319,474,526, 18,390,184,210,469,
     505,477,314,117, 81,117,142,507,507,357,477,445,276,135,468,503,351,461,461,461,
     461,461,461,461,462,462,462,462,462,462,173,462,462,462,462,462,462,462,462,462,
     462,462,462,462,462,463,463,463,463,463,463,463,463,463,463,464,464,464,464,464,
     464,464,464,464,148,464,464,464,464,464,465,465,465,465,465,465,465,466,466,466,
     466,466,466,466,466,466,467,467,467,467,467,467,467,467,467,467,467,467,467, 51,
     467,467,467,467,467,468,468,468,468,468,468)
     );
BEGIN
  IF (p_Index>0) AND (p_Index<192) THEN
    RETURN v_list08(p_Index1)(p_Index);
  ELSE
    RETURN 0;
  END IF;
end get_py_index_08;


FUNCTION get_py_index_09(p_Index1 NUMBER, p_Index NUMBER)
RETURN NUMBER IS
  v_list09 TPYIndex_list := TPYIndex_list(
     TPYIndex_191_list(483,291, 25,446,306,339,209,361,176,525,268,178,106,366,510,141,478,188,464,380,
     215,294,399,462,215,229,185,393,178,505,237,172,477, 26,514,404,354,229,466,421,
     215,423,484,236, 48, 43, 72,232,320,110,484,472, 91,507,477,339,143,198,339,431,
     431,117,508,  0,462, 85,215,442,482,482,484,117,483,442,472,477,319, 70,487,418,
     135,163,364,484,277,181,417,317,377,294,479,178,163,209,231,229,395,468,468,468,
     468,469,469,469,469,469,469,470,470,470,470,470,470,470,470,470,470,470,470,470,
     470,471,471,471,471,471,471,471,471,471,471,471,471,471,471,471,471,472,472,472,
     472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,
     472,472,472,472,472,472,472,472,472,472,473,473,473,473,473,473,473,473,473,473,
     473,473,473,473,473,473,473,474,474,474,474),
    TPYIndex_191_list(247,477, 85,462,459,451, 21, 32,172,388,335, 18,337,175,513,175, 67,172, 70,488,
     108,110,460,470, 22,359,251,221,  6,494,166, 32,415,299, 70,231, 71,399,500, 18,
     221,337,507,419,399,447,395, 15,462, 25, 46,220,240,457,459,221,503, 69,184,491,
     395,175,477,  0,221,471,457,112,117,114,  7,151,172,172,459,139, 20,472,467,186,
     329,254,261,261,331,395,408,172,505,186,261,433,231,474,507,187,457,474,474,474,
     474,474,474,474,474,474,474,474,475,475,475,475,475,475,475,475,475,475,475,475,
     475,475,475,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,
     477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,
     477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,478,478,478,478,
     478,478,478,478,478,478,478,478,478,478,478),
    TPYIndex_191_list(388,451,457,432,483,221, 98, 91,347,318,172,266,479,135,351,500,179,139, 79,175,
     246,351,175,451,186,351,246,221,393,172,139,472,432,350,179, 63,507, 44,172, 70,
     507,462,352,125,395,141,462,167,350,464,291,339,242,498, 18,464,389,133,507,469,
      51,457,477,  0,242,186,457,472,457,472, 87,117,350,350,177,172,108,470, 84,159,
      41,423,467,178,477,361,470,478,388,339,445,172,470,478, 98,111,471,478,479,479,
     479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,480,481,481,481,
     481,481,481,481,481,481,481,481,481,481,481,481,482,482,482,482,482,482,482,482,
     482,482,482,482,482,482,482,482,482,482,482,482,483,483,483,483,483,483,483,483,
     483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,
     483,467,483,483,483,483,483,483,483,483,483),
    TPYIndex_191_list(474,411,393,478,478,186,461,281, 46,482,507,465,109,463,263,391,472,372,516,467,
     477,477,413, 48,151,393,151,467,505,510,506,135,518,500,136,117,175, 85,236,431,
     473,301,317,509,122,477,184,474,498,477,477,351,502,333, 18,465,351, 25, 68,522,
     423,510, 59,  0,503,481,467,470,477,165,151,395,346,461,395,154, 91,160,141,352,
     166,178,162,121,473,451,393,509,439,261,266,246,166,472,465,137,106,483,483,483,
     483,483,483,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,
     484,484,484,485,485,485,485,474,485,485,485,485,485,487,487,487,487,487,487,487,
     487,487,487,487,487,488,488,488,490,490,490,490,490,490,490,491,491,491,491,492,
     492,492,493,493,493,493,493,493,493,493,493,493,493,493,493,493,494,494,494,494,
     495,496,497,497, 35,497,498,498,498,498,498),
    TPYIndex_191_list( 24,433,477,225,510,213,351,456,172,507,361, 63,222, 98,213,477,435, 70, 15, 42,
     482,199,345,347,400,  4,483,461, 47,178,459,456,456,124,411, 26,166,180,485,505,
     485, 91,162, 43,404,178,194,351, 61,461,415,450,459,110,220,418,477,291,478,509,
     328,517, 42,  0, 46,516,172,339,421,515,451,184,348, 89,506,526,521,341,517,232,
     175,172,458,245,393, 21,162,329,483,462,467,329,395,468,395,167,162,498,498,498,
     388,498,488,498,498,498,499,499,499,499,499,499,500,500,500,500,500,500,500,500,
     500,500,500,500,500,500,500,500,500,501,501,501,501,501,501,501,501,501,501,501,
     501,501,501,501,502,502,502,502,502,502,502,502,502,502,503,503,503,503,503,503,
     503,503,503,503,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,
     506,506,506,506,506,506,506,506,506,506,506),
    TPYIndex_191_list( 98,508,431,462,117,337,435,221,339,483,518,513,457,166,478,440,459,278, 46,112,
     510,473,472,165,468,125,306,467,270,475,451,464,427,509,388,334,443,165,168,125,
     479,261,461,261,458,342,505,469,431,413, 12, 48,500,477,176,484,462,461,423,474,
     474,507,483,  0,330, 61,229,268,268,389,503,267,175,494,522,231,247,493,467,142,
     457,517,  6,  6,179,503,477,461,176,251,502,459,447, 70,467,497,379,505,506,506,
     506,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,
     507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,
     507,507,507,507,508,508,508,508,508,508,508,508,508,508,508,509,509,509,509,509,
     509,509,509,509,509,509,509,509,509,510,510,510,510,510,510,510,510,510,510,510,
     510,510,510,510,510,510,510,510,510,510,510),
    TPYIndex_191_list(457,498, 94,506,461,221, 98,479,186,172,525,345, 25,166,513,456,496,498,507,345,
     421,496,337,394,468,493,421, 71,415,459,172,177,500,300,477,  3,500,166,462,477,
     477,388,358,300,341, 94,418,161,509,149,477,479,191,483,175,166, 91,503,468,491,
     225,393,451,  0, 42,229,477, 20,503,472, 98, 50,451, 50,474, 42,358,478,221, 46,
     462,295,164,491,477, 71,500,472, 91,445,361,465,465, 18,509,393,467,510,510,510,
     510,511,502,512,513,513,513,513,523,513,514,514,514,514,514,514,514,515,515,515,
     515,515,515,516,516,517,517,517,517,517,517,517,517,503,517,517,518,518,518,518,
     518,518,518,518,490,518,518,518,518,518,518,520,520,520,520,520,520,520,521,521,
     521,521,522,522,522,522,522,522,522,522,523,523,524,524,524,524,525,525,526,526,
     526,498,526,526,526,526,  0,  0,  0,  0,  0),
    TPYIndex_191_list(341,159,458,172,159,147,240,457,457,233,147, 91,240,339,229, 79, 20,399,459,112,
     507,507,472,472, 51,166,444,477,477,472,  7,160, 98, 51,472,215,121,184,337,457,
     164,510,173,111,457,168,452,164, 81,520,111,477,  4,328,276,328,135,276,482,268,
     408,164,254,  0,268,  4,483,291, 18,483,173,442,254,457,477,483, 51,421,164,186,
      15,505,487,117, 28,133,425,477,148,449,332,168,108,421,449,499,507, 51,172,456,
     121,292,372,328,127, 47,125,280, 98,399,483,331, 18,445,474,474,507, 81,463,478,
     214,483,124,423, 83,172,277,295,172,339,261, 15,379,136,494,391, 67,472,186,408,
     475,472,351,334,141,214, 20,494,137,482, 33,477,452,180,209,141,189,219,172,472,
     449,211,330,186,345,168,477,439,450, 70, 87,501,224,372,477,271,361,483,328,471,
     447,456, 43, 31,192,510,297,188,482,477,135),
    TPYIndex_191_list(106,510,395, 18,518,106,141,329,107,250,425,394,213,117,434,477, 48,254,151,111,
     242,235,166,121,329,518,173,467,495,177,121,492,175,479,470,505,391, 23, 23,350,
     391, 54,492,509,220,491, 59, 46,389,432,320,128,459,250,175,415,117,421, 61, 61,
     507,172,501,  0, 91,179,465, 57,487, 13,490,220,112, 31,172,394,477,523,117,135,
     374,494,233,477,  8, 46,449,507,515, 21,487,497, 70,491,472,337,388,439,445,291,
     119,172,106,482,210,191,510,477,433, 41,177,299,270, 50,472,229,350,229,483,333,
     481,408,112,341,371,315,517,399,246,455, 18,431,139,206,184,111,472,462,172,451,
     520,247,422, 23,306, 48,457,180,175,177,182,439,468, 70,439,444,391,341,522,485,
      64, 81,457,470,159,143, 42,214, 13,337,159,117,117,413,408,452,472, 25,142,254,
     462,243,335, 24,479,246,225,232,161,234,459),
    TPYIndex_191_list(449,479,179,514,459,492, 18, 91,399,472,446,468,240,514,492,487, 18,509,112,487,
     457,465,457, 47, 47,458,422,521,229,388,349,478,459,518,186,347, 81, 59,505,441,
      81,457,500,186,178,351, 51,168,469,433, 97,122,417, 63,457,502,413,478,351,175,
     353,517,451,  0,242, 71,350,518,431,351, 48,165,345,345,177,493,485,106,522,456,
     194,186, 46,318,485,314,339,445,477,292,236,257,209,518,340,510,351,411,333,508,
     266,472,178,159,388,313,184,281,136,151, 81,502,351,477,213,225,137,178,166,393,
     135,352,506,167,467,345,124,213, 99,521,517,451,483,393, 42,415, 46,175,469,475,
      98,483,468,  4, 81,518,329,268, 71,413,395,261,503,175,496,345,186,472,500, 46,
      70,179,526,456,341,180, 11, 83,526, 15,464,121,507,295,521, 56,328,451,165,451,
     457,147,349,213,252,456,109, 24,328, 15,475)
     );
BEGIN
  IF (p_Index>0) AND (p_Index<192) THEN
    RETURN v_list09(p_Index1)(p_Index);
  ELSE
    RETURN 0;
  END IF;
end get_py_index_09;


FUNCTION get_py_index_10(p_Index1 NUMBER, p_Index NUMBER)
RETURN NUMBER IS
  v_list10 TPYIndex_list := TPYIndex_list(
     TPYIndex_191_list(500,317,510,291,477,172, 97, 97,510,525,512,460, 85,329,507,178, 28, 68,351,399,
     441, 63,199,295,461, 26,525,271,399,177,345,260,175,339,455,451,178,353,295,184,
     295,245,242,228,455,352,522,346,477, 81,520,322,506,483, 96, 57,481,507,498, 46,
     445,422,117,  0,522,360,498,443,342,500, 83,431,172,237,491, 18, 49,242,233,422,
     507,413,457,214,172,517,342,507,317,520,231,493,357,443,184,459,508, 81,420,173,
     507,510,211,346,470,487,229,479,124,457,117,328,421,472,185,472,478,501,334,388,
     521,236,112, 51,164,250,351,390,151,125,259,467,462,412,462,186,175,388, 71, 43,
     408, 20, 16,350, 16, 98,107,399,172,481,151,467,456,125,505,213,328,477,229,339,
      11,122,240, 83,242, 45, 81,445,291,271,  6,471, 85, 89,189,388,389,280,121,478,
      47,395,143,470,234,484,507,  4,477,328,292),
    TPYIndex_191_list( 25, 63,186,235,418,345,345,233, 96,139, 68, 18, 18,184,345, 96, 50,172,456,485,
     292,507,485,507, 51, 92,451,240,235,459,451,221,358,462,295,418,351,353, 64,523,
     457,214,339,235, 70,111,431, 97,133,222,361,246,  3,172,184,206,446,472,257,192,
     351,247,223,  0,445,507,472,431, 72,479,483, 45,498,141,187,485,463, 69,468,108,
     361,388,213,399,444,339,420, 98,276,339,254,368,213,341,513,159,161,322,441,378,
      69,209, 85,478,228,160,125,484,251,481,232, 48,463,328,477, 32,177,277, 91,341,
     172,449,465,339,460,117,484,487,110,172,229, 98,184,328,507,369,459, 43, 61,347,
     456,341,339,388, 20,510,208,477,268,122,331,240,  7,271,184,357,348, 48,117,236,
     294,478,254,479,349,265,433,341,477,359, 18, 59,184,439,166,510,435,345,117,361,
     464,352,166,470,266,339,177, 49,176,246,479),
    TPYIndex_191_list(351,213, 81,236, 69,  6,505,108,213,473,322, 15,136,136,319,510,364, 98,  7,509,
     507,474,194,503,507,395,333,106,133,184,461,140,471,189,352,509,518,507,391,232,
     483,390,482,484,478,503,449,117,348,509,477,236,503,500,232,518,166,450, 58,166,
     191,477,322,  0,341,142,292,333,139, 15,245,315,232,368,365,172,473,459, 54, 62,
     405,471,482,159,399,117,518,117,487, 16,500,483,487,423,136,505,458,470,127,179,
     250,416,159,509,191, 18,395,455,482, 98,257,482,229,441,459,117,415,482, 81,393,
     139,232,479, 57,180,339,457,411,179,277,339,  7,399, 43,434,483,164, 18,117,441,
      70, 65,472,522, 71,175,449,479,136,147,340,112,393,460,451, 42,189,339,214,457,
      98, 13,314,435,241,315,468,173,505,395,366,268,100, 15,453,149,172,229, 12,175,
     406,222,479,483,413,259, 90,457,231, 63,235),
    TPYIndex_191_list(484,242,461, 44,513,451,468,469,503,177,500, 26,233,111,108,235,125,379,191,164,
     477,172,515,106,483,175,159,225,320,229,229,242,235, 69,509,232,487, 59,524, 20,
     219, 59,477, 20, 20,446, 11, 59, 20,329,299,299,505, 58,477,362,108,395,366, 42,
     122,483,477,  0,339,498,450,441,516,431,460,431, 98,508, 45,291,507,505,510,423,
     477,351,166, 89,482,277,477,178,234,470, 96,181,482,350, 81,180,477,351,208,467,
     233,166,470,186,369,524,172,259,108,339,159,462,159,451,477,453,412, 18,149,420,
     366,470,459,124,229,168,351,155,108,295,261,299,477,213,231, 68,477,457,492,319,
     482,233,119,122,431,258,442, 46,117,332,298,178,177,488,477,247,187,432,475,  3,
     276,172,143,  8,184,335,234,341,139, 85,498,471,347,483,  4,468, 24,214,484,399,
     100, 53,175,406,500,306,377,246,479,507,147),
    TPYIndex_191_list(472,456,231,417,166,136,220, 16, 67,510,322,482,509,179,483, 58,431,418,484,306,
     422,415,472, 48,431,395,505,482,487, 98,168,418,451,278,474, 50,470,418,395,507,
     484,413,249,139,501,503, 27, 48,413, 96,395,241,507, 67,359,341,468,483,477, 98,
     233,395,250,  0,468,500,427,106, 20, 20,229,484,482,246,229,435,339,388,483,366,
     449,117,192, 23,463,393,484, 66,168, 12,184, 20,447,213,141,395,209,503,462,242,
     525, 64,122,164,328,464,517,168,523,279,477,443, 69,395, 26, 48,172,208, 72,224,
     498,  1,474,117,271,477,420,229, 98, 18, 15,143,347,478,488,188,119,137,236, 89,
     297, 97,280,482,408,213,172,393,166, 68,234,477,461, 18, 59,140,166,466,477,315,
     211, 97,172,264,261,498,299,127,270,250, 48,223,128,100,498,417,493,457,526,172,
     112,494,306,263,235,513,509,423,161, 65,386),
    TPYIndex_191_list(145,458,172,160,464,457,141,306,222,472, 47, 90,247,117,483,222,173,128, 25,457,
     351,461,339,348,509,521,333,225,291,482,335,460,184,481,345,477,257,371, 15,399,
     483,487,160,214,460,460,412,422,266,457,366, 51,518,521,475,456,460,487,345,481,
     254, 44,242,  0,233,513,161,345,449,345,467, 79, 18,470, 18,497,451,506,254,235,
      97,259,475,378,211,112,259,216,231,491, 42,482,339,472, 42,491,352,480, 70, 25,
      87,222,229,400, 58,498, 68,278,229,214,178,481,214,182,412,478, 48,178,241,209,
     455,166,347,  6,413, 91,194,295,151, 46,417,125,  1,100,149, 82,  3,  3,417,152,
     439, 48,320,225, 32,330,339,479, 17,412, 81,261,322,186,233,337, 53,177,309,347,
     242, 35, 79,149,179,469,477,374,328,366, 40,168,279,451,175,278,245,161,236,482,
     483,348,483,164,451,507,320,422, 50,494,143),
    TPYIndex_191_list(457,491,507,483,478,524,254,505, 90,505,484,117,432,340,334, 50,524, 58,482,478,
     337,524,145,515,242,221,472,423,500,421,515,459, 91,421,350, 57,487,107,194,412,
      50, 67,487,481,  5,498,176,330, 46,483,229,493,477,176,421,334,299,477,472,477,
     293,366,398,  0,472,236,261,261,293,463,177,395,261,472, 20,395,477,457,179,350,
     477,233, 72,502,236,334,350,  7,505,507,  7,243,117,277, 84,459,345,451,455,251,
     501,117,108,172,339,341,339,351,471,459,  6, 34,221,  7,161,194, 89,173,466, 69,
     135,254,265,477, 89,345,470,506,223,220,411,472,136,461,143,206,186,364,474,448,
     490,451,483, 67,241,518,257,394,411,172,501,235, 79, 23,477, 83, 48,318, 63,470,
     473,160,220,457, 43,165,474,507,177,351,376,108,350,  4,140,249,298,487,458,319,
     110,364,211,398,416, 18,185,229,483,459,478),
    TPYIndex_191_list(208, 54,518,108,483,456,147,123,339,252,363, 81,408,457,477, 41,477,441,457,307,
     341,350,175,502,475,478,314,109,505,464, 90,485,508,117,328,369,463, 98,186, 96,
     135,478,341, 11,457,361, 44,298,111,487,477,347,328,143,159,478,187, 84,477,508,
     457,121,363,  0,168,420,192,484,242,288,452, 97,518,291,441,395,265,328,194,236,
      24,420,161, 25,328,483,408,526, 26,509,432,173,505,395,522,507,184,414,477,143,
     246,291,391, 63,261,161, 40,451,451,257,280,501,180,186,233,462,470,164, 54,168,
     416,478, 89,395,422,444,457,361,483, 48,477,460, 25,483,167, 40,412,268,466,179,
     376,513,279,328,456,141,319,466,460,445,  4,483, 18,128,  6,179, 42,462,235,479,
     399, 72, 66, 42,456,507,313, 49,456,189, 43, 55,411, 20,298,161, 51,322, 68,473,
     526,291,117, 44,477,477,439,472, 33,189,470),
    TPYIndex_191_list(434,477,477,468,502,319,151,379,394,522,522, 25,510, 48,488,334,439,341,117,499,
     254,472,117,229,485,328,473, 11, 25,178,351,467,506,271,457,457, 81,173,271,421,
     393,477,408,213,188, 15,517,464,159,177, 48,199,246,333,395,270,194,478,187,509,
      49,460,439,  0,268,225,172,483,467,361,525,507,406,229,459,464,352,328,477,510,
     460,266,210,474,459,459,466,187, 40,223,172,328,366,261,477,478,140,194,487, 15,
     411,341,214,215,477,431,352,346,464,110, 43,450, 50,161, 65,487,214, 98,228,515,
     345, 18,413,341,481,180,345, 49, 51,235,259,432,166,402,472,451,159,265,192,418,
     247,215,182,222,483, 43,457,452,167, 98,351,353,151,432,353,191,514,317,342,376,
     339,408, 40,112,484,271,262, 96,261,136, 20,452,148,451,224,122,399,240,242,473,
     408, 97,236,254,246,468,317,445,159,265,180),
    TPYIndex_191_list(  4, 88,482,379,193,341,408,289, 84,147,485,507,199,350,461,503,482,492,431, 67,
     137,159,508,441,247,259,222,449,518,487, 15,413,483, 42,435, 25,147,173,159,185,
     112, 42,449,507,445,468,456,483,433,213,517,244,464,347,393,147,244,475,184,497,
     184,459,434,  0,252,337,229,317,485, 47,124,229,425, 24,510,505,441,237,524,184,
      43,484,175,123, 84,423, 43,245,210,236,328,242,229,342,335,185,265,164,451,234,
     173,505,478,166,510,172,467,166,423,470,176,237,161,470,366,413,456,220,451,517,
     185, 34, 12,457,257,164,510,339,457,411, 91,517,328,262,122,110, 61,393,139,242,
     402,462,472,262,350,412,165,467,321,175,468,455,257,472,347,194,391,252,479,337,
     229,366,418,167, 18,466,117,422,318,266,165,479,461,221, 32,161,246,164,231,510,
     477,242,468,122,399,408,388,390,439, 42,220)
     );
BEGIN
  IF (p_Index>0) AND (p_Index<192) THEN
    RETURN v_list10(p_Index1)(p_Index);
  ELSE
    RETURN 0;
  END IF;
end get_py_index_10;


FUNCTION get_py_index_11(p_Index1 NUMBER, p_Index NUMBER)
RETURN NUMBER IS
  v_list11 TPYIndex_list := TPYIndex_list(
     TPYIndex_191_list(524,322,  4,328,459,471,515,229,194,206,418,215, 91,515, 56,518,506, 16,295,520,
      97,472, 87,477,341,515,172,483,179,139,254, 43,444,457,231,423,136,457,399,505,
     247,259,242,162, 21,119,220,198,109,456,277,449,161, 73,459,446,168,232,107,258,
     189,473,395,  0,231,143,459, 91,441,451,449,117,365,172, 98,187,505,431,498,161,
     473, 92,458,483,199,394,165,451,117,502, 40,346,395,159,214,432,345,415,229, 70,
      42,231,366,337, 18,149,517,147,462,479,485,111,149,  7, 13,141, 71,261,482, 46,
     297,341,341,456,233,341,164,175,175,521,471,456,181,494,477,106,173,180, 69,160,
     318, 26,229,350,461,431,354,214,451,164,242, 54,165,350,458,  6,135,418,237,459,
     235,184,462,263,415,219,470,166,442,507,193,507,172, 98, 42,457,184, 42,180,301,
     261,117, 18,483, 51,406,110,472,456,483, 18),
    TPYIndex_191_list(345,160,440,520,164,475,265,175, 92,175,411,214,161,468,503,178,505, 20,508,518,
     466,475,257,315,  3,121,341,257,417,418,318,458,231,417,189,522,475,300,453,364,
     422,417,342,229,406,515, 25,317,372,328,377,123,518,456,479,165,433,237,189,416,
     395,412,449,  0,149,505,505,246,477,484,422,295,457,173,125,249,185,411,522,417,
     446,112,452,276,242,417,313,522,442,466,139,468,231,412,251,268,246,179,518,141,
     298,483,408, 68,509,388,346,471,359,399,243,177,332, 40,229,333,447,459,417, 81,
     451, 98,180, 21,178, 43, 18, 42,301,  6,484,435,456,135,268,328,  3,332, 48,229,
     472,342,330, 43,225,501,457,388, 18,294,268,403,119,119,117,301,518,178,186, 13,
     492,408,117,521,477,301,420,461,162,329,229,339,194,515, 30,507,456,  6,237,388,
      21, 61, 42,172,460,177,483,509,125,449,213),
    TPYIndex_191_list( 18,451,237, 81,376,520,477,242,199,342, 65,339, 43,422,251,481, 42,112,180, 21,
     399,247,466, 61,240,491,491, 32,229,458,457,192,403, 17,501,341, 47,242,162,172,
     337,415,342,334,235,379,466,459, 47,214,408,237,280,165,331,415,108,345,352,473,
     422,460,483,  0,177,525,233,346,223, 96,463,491,339,175,508, 79,471,479, 96,186,
     300,491,337,434,446,501, 87,388,189,175,110,415,242,185,166,483,231,487,328,399,
     122,462,117,509,117, 51, 69,209,148,176,128,461,431,236,339,110,389,142, 97,398,
     237,352,449,518,194,460,431,263,166,408, 20,135,515,265,179,505,366,124,229,477,
     175, 23,330,251,225,267,378,462,233,497,176,341,345,164,523,474,172, 54,490,481,
      87,172,451, 23,265,186,194,240, 83, 69,334,265,173,106,133,467,471,155,474,246,
     457,166,231,339,479,339,161,215,472, 61,449),
    TPYIndex_191_list(517,378,341,517,225, 18,434,468,475, 97,143,422,351,111, 68,477,  3,520,470, 84,
     510,155,515,172,295,151,168,348, 23,479,214,297,467,175,175,341, 40,507,264,229,
     225,172,523,213,389,322,219, 91,485, 58,247, 21, 13,242,459,212,240, 98,242,175,
     221, 25,341,  0,474, 42,460,175,457,139, 31,295,225, 64,351,317,246,523,243,526,
     477,186,422,510,221,457,473,464,319,464,252,471,507,459,483,477, 43, 46,184,254,
     483,484,458,280,  3,422,179,165,479, 65, 61,468,501,337, 30,351,242, 18,491,452,
     451,487,423,456,390,339, 40,249,229,328,263,474,369,175, 51, 47, 61,461,109,314,
     510,277,507,503,240,182,333,242,458,461,482,507,445,507,236,135, 81,229,445, 47,
     193,223,471,359,507,505,140,339,435,216,182,162,155,141,178,243,185,  4,467,108,
     136,117,186,518,417,236, 51,111, 91,341,502),
    TPYIndex_191_list(507,479,165,518, 25,422,364, 17,237,468,219, 42,501,501,182,  6, 85,186,233,291,
     258,249,402,388,388,258,472, 18,147, 18,388,341,192, 17,159,370,376,459,459,175,
     265,458,404, 90,498,280,500,322,458,236,139, 18,370,151,449,125,125,107, 51,460,
     141,265,384,  0,215,232,247,435,386,184,485,485, 42,351,235,422,387,215,472,452,
     472,483,167,483,452,460, 13,460,351,474,452,317,478,451,478,216,353,246, 56,232,
     143,175, 81,184, 62,393,278,498,231,221,172,332,184,350, 92, 56, 46,247, 40,184,
     468,257,479,505,110,418,416,462,124, 65,124,406, 23,364,510,462,179,342,339, 51,
     422,510,161,122,485,348,445,186,345,347,242,525,457,184,484,225,472,235, 25, 40,
     482,  6,268, 63,389,432,487,231,330, 70,172, 23,477,361, 98,136,194,242,507,477,
     505,161,229,474,395,507,352,242,503,292,450),
    TPYIndex_191_list(221,391,352,325,432,295,418,189,151,353, 55,449, 90,339,214,422,449,330,459,457,
     166, 42,328,422,164,418,452,446,147,189,391,166,418,164,224,463,477,507,478,473,
      90, 98,394,320,199,487,507,328, 47, 98,351, 81,236,507, 24, 97,399,415,106,141,
     483,187,345,  0,464, 57,456,458,388,394,337,505,459, 72,320,477, 94,245,478,184,
     505,242,394,459,478,510,473,362,458, 49,472,478,483, 81,451,295,515, 58,518, 62,
     242,235,451,175,342,173,172,172,191, 79,121,175,492,313,236, 26, 17,497,328,334,
     119,219,122,149,421,124,494,463,487,141,151,491,254,483, 43,291,339,394,475, 44,
     472,166, 26,147,141,468,214,  3,266,444,470,474,457,279, 16,395,213,477,507,518,
     121,179,505,220,350,172, 70,117, 42,172,457, 81,483,135,179,351,175,176,332,254,
     136,456,136,172,184,175,329,193,346,417,  8),
    TPYIndex_191_list(  4,178,339,472,166,487,456,422,172, 72,  6,457,478,372,359,235,443, 79,328,415,
     483,472,111,291,106,172, 72,478,507,240,457,229,229,353,507,477,347,341,164,135,
     524,161,488,483, 50,415,147,455,403,164,184,488,481,172,457,237,229,306,469,488,
     172,172,276,  0,116,457,271,111,318,487, 48,473,  4,456, 83, 71,161, 84,271, 46,
     498,236,339,509,159,500,478,510,444,236, 89,479,456,236,236,159,478,125, 25,254,
     271, 65,175,376,399, 43,242,337,351,331, 72,459, 54, 89,471,478,194,487,108, 48,
     177, 91, 85,482,484,143,485,455,364,165,180,368,420,133,516,276,474,341,240, 89,
     188,242,173,393,509,526,137,505,351,507,180,140, 89,472,211,372,145,329,505,261,
     444,246, 67,319,449,294,180,472,110,483,520, 87,175, 62,278,262,447, 98,399, 47,
     479,125,247, 23,427,507, 53,136,259,378,388),
    TPYIndex_191_list(250,250,487,237,259, 23,456,451,216,457,477, 70,427,483,240, 69,172,318,473,451,
     446,457,172,456,259,225,229,417,  3,110, 69,240,236,477,112,229, 13,151,151,151,
      24,348,432,505, 47,348,232,180,432,110,262, 13,432,166,475, 87, 40,341,361, 81,
      91,456,361,  0,347,298,478,372,276,447,522, 11,477,474,423, 18,178,159,319, 24,
     478,418,423,178,  4,154,133,340,435,479,415,433,468,206, 17,418,501,231,235,483,
     457,477,386,463,457, 21,372,184,412, 21, 21,399,135,136,161,110,172,221,483,320,
     254,500,180,291,237,477,473,451, 96,342,395,161,510,468,420,475,473,456,147,258,
      44,472,161,483,451, 92, 13,468, 20,443,237,251,389,487,477,483,108,415,459,186,
      64,408,423,467,457,229,161,181,161,110,395,408,459,507,351,161,117,526,261,507,
      59,505,433,339, 42,457,517,457,358,425,421),
    TPYIndex_191_list(328,216,219,498, 12,101,350,350,391,390,271,175, 81,312,423,418,462,317,125, 24,
     216,422,241,166,345,469,172,175,176, 42,418,161,459,341, 91,447,175,221,451,361,
     117,447,352,125,451,390,147, 43,216,365,487,391,451,125,117,423,135,487,124, 18,
     469,415, 91,  0,447, 91,117,182,459,462,459,172,488,224,322,479,479,487,322,  4,
     478,460,161,475, 87,348,214,460,405,147,467,477,467,136,411,214,339, 94,173,166,
     307,296,473,518,353,341,265,425,339, 94,254,258,123,483,483,418,469,263,172,122,
      71,162, 45, 96,471,517, 20,112,107,  3,229,240,498,439, 81,219,445,117,464,252,
     458,345,499, 89,280,125,455,339, 94, 15, 87, 46,509,178, 81,468, 20,503,142,377,
     348,351, 96, 79,176, 27,259, 25,191,507,117,117,467,262,208, 96,263, 70,394,484,
     477,415,518, 48,270,220,175, 81,417,471,291),
    TPYIndex_191_list(148,483,449,111, 96, 81, 83,317,334,236, 45,180,225,347,345, 98, 98,451,462,216,
     393,477,477,194, 94,483,333,225,433,173,440,166,214,173,246,435, 47,479,487,161,
     147,180,443,443,332,220,443,518,518, 56, 87,220,421,147,341,212,522,459,347,477,
     374,431, 98,  0, 98,472,452,472,483,513,472,459,463,477,484,377,432,432,176,214,
     225,223,330,512,251, 63,474,149,345,136,470,472,166,388,366,259, 23,415,328,369,
     412,214,254,194,266,330, 47,191,235,136, 87, 18,352,432,108,505,391,449,442,117,
     123,136,229,472,328,221,229,172,497,151,139,185,179,119,477,334,502,233,441, 54,
     388,258, 41,307, 26,420,184, 11,341,109,192,440,168,314,483,506,136,194,334, 26,
      25,485,271,421, 83,406,395,468,418, 18,291,328, 97,193,223,106,482, 47,173,280,
     475, 47, 84,478,189,510, 87, 88,162,352,144)
     );
BEGIN
  IF (p_Index>0) AND (p_Index<192) THEN
    RETURN v_list11(p_Index1)(p_Index);
  ELSE
    RETURN 0;
  END IF;
end get_py_index_11;


FUNCTION get_py_index_12(p_Index1 NUMBER, p_Index NUMBER)
RETURN NUMBER IS
  v_list12 TPYIndex_list := TPYIndex_list(
     TPYIndex_191_list(459,332,242,235,295,352,435,181,335,479,483,225,112, 88,137,117,458,500,319,372,
     117,420,234,172,468,461,184, 21,408,451,473,474,412,189,412,108,237,457,237,330,
     330,237, 21, 21, 21,233, 21,379,112,466,473,500,408,474,237,110,108,110,395, 30,
     172, 87,408,  0,445,500,516,361,483,473,395,478,108,108,416,478,510,477,526, 18,
     178,423, 13, 59,434,408, 13,395, 97,145,361,432,177,173, 24,474,439,386, 84,506,
     379, 49,422,  4,366,223,220,425,199,497,229,124, 98, 67,244,237,189,175,222,347,
     184,  1,342,306, 16, 73,194,215,136,168,320,185,421,518,346,189,408, 98, 40,412,
     164,  3,241,342,110,257,268,125,185,276,237,477,173, 23, 21,422,251,246,481,522,
     468, 81, 42,186,337,242, 96,221,337, 64,342, 79,168,517,477, 40, 21,508,393, 67,
     507, 18,518,268,399,247,172,117,222,194,361),
    TPYIndex_191_list( 59,460,473,185,106,224,457, 25,282, 98, 26,187, 90,413,483,457,474,215,143,395,
     175,515, 24,459, 26,475,421,110,501,451,139, 98,302,487,161,165,166,500,160,151,
     464,111,451,136, 40,411,422, 25,124,457,214,237,412,459,475,452,268,422,251, 18,
     483,466,179,  0,376,443,513,388, 48, 70,477,339,359, 47,451,460,500,111,145,259,
     472,268, 42,460,246,491,279, 87,445, 97,173,224,457, 90,187,143,136,505,172,379,
     292,117,358,141,177,149,457,334, 85,161,481,182,484, 13,505,136, 89,242,351, 48,
     408,106,507,137,466,243, 25,229,161,483,459,431,456,263,  4, 15, 57,161, 98, 59,
     257,456,474,175,479,503,237,233,177,182,483,161,242,139, 24, 87,178,229,388,229,
     482,122,194, 70,498,319,510,468,173,471,477,507,223,456, 67,459,386,510,110,136,
     451,483,483, 70,219,477,160, 67,241,173,378),
    TPYIndex_191_list(475, 25,111, 25,291, 18,334,441,147,110,175,  4,  3,459,487,111,332,463,249,483,
     333,341, 81,445,503, 48,470,510,507,320,463,363,372,487,452,507, 70,247,482, 25,
      13,211,445,477,351,337,351,181,334,502,484,322,509,184,510,301,184,328,522,173,
     236,505,499,  0,117,473,395, 18,445,445,408,237,249,329,423,507,364,427, 89,470,
     352,393,181,106,145, 25,510,478,246,509, 70,145,237,184,411,347,252, 48,268, 11,
     172,165, 21,246,479,499,240,478, 50, 11,220,477, 83,328, 83,351,477,411,457,349,
     516, 20,474,433, 90,194,483,470,184,483,477, 40,276,361,179,257,317, 71,340,125,
     198,231, 47,231,175, 21, 51,431, 18,184, 97, 68, 15, 13,247, 20,221, 48,503,342,
     366,317,399,467,187, 66,179,225,518, 44,408,168,223,422,313,241,176,300,268, 85,
      87, 70,236,297,143,214,  6,421,147,339,148),
    TPYIndex_191_list(232,147,441,468,443,187, 98, 47,464,408,242,515,509,391,329,215,423,220,520,194,
     339,339,472,110,378,472,125,474,456,329, 61,329,341,110,165,341,168,483,431,352,
     458,520,214,365,408,137,445,443,412,341, 47,507,237,322,427,457, 32, 91,472,484,
     521,461,388,  0,339,507,403,242,457,246,501,268,474, 30,330, 61,351, 18,507,483,
     467,162, 25,413,461,235,500, 96,237,445, 35, 83,461,434,472,246,500,178,151,479,
     194,147, 98,513,295,251,377,149,366,332,161,341,350,172, 41,166,125,259,117,328,
     369,459,149,178,133, 90,478, 48,147,136,194,229,482,357,498,350,236, 47,482,349,
     173,280,507,408,351,435,216,339,177,473,270,393,503,390,456,229, 51,117,342,348,
     339,457,483,110,143,143,477,328,433,352,449,222,259, 57,364,278,117,214,194,117,
     412,483,482,241,350, 20,270,347,  6,251,252),
    TPYIndex_191_list(180,477,475,503,332,509,472,492,247,427,460,172,403,184,457,164,229,330,363,478,
     330,464,347,520,413,214,403,451,451,451,483,122,477,192, 13, 15,499,431,461,210,
     443,128,329,483,415,334,461,318,186, 67,268,233,241,461,492,431, 23,212,242,124,
     345,193,345,  0,223,378,215,431,109,466,357, 70,215, 23,107,328,107,431, 13, 18,
     365,117,106,364,351,133,485,322,511,390,417,431,229, 23,431,322,411,249,484,457,
      48,422,318,395,165, 32,330,422,457,460,508,501,401,254,322,166,317,388,168,259,
      42,231,264,229, 91,351,116,479,348,458,395,510,483,172, 91,172,175,502,518,161,
     349,334, 68,394,494,135,229,408,433,173, 20, 48,208, 18,459,472,352,506,187,395,
     123,314,390,461,348,494,346,510,371,341,445, 18, 70,206,484,461,505,214,165,160,
     135,110,229, 18, 48,413,264, 90,242, 92,141),
    TPYIndex_191_list(506,520,405,175, 97,161,219,339,231,505,322,249,376,251,251,383,467,234,341,341,
     279,216,297, 23,358, 90, 90,280,460,457, 90,147, 90, 90,182,483,483,472,229,463,
     141,520,237,462,389,257,339,339,119,467,483,443,339,232,122,330, 18,339,467, 50,
     472,500,483,  0, 72,361,178,  7,159,445, 84,172,483,162,346,417,148,444,268,178,
     393, 11,484,328,247,452,161,242,488,109,111,276,482,329,268,151,458, 83,491, 79,
      25,220,509,483,483, 49,457,295,307, 54,388,477, 18,508, 11,109,125,242,510,494,
     457,390,451,259,398, 32, 49,259,347,294,173,350,386, 18, 81,342,417,178,422,457,
     459,261,  7,229,433,457, 59, 30,235,520,376,160,491, 59,467,365,350,176,127,172,
     477,236,457,510,110,175,329,151,477,261,507,339,339,474, 72,117,351,182,346,234,
     518,491,278,503,176, 48, 87,122,509,477,136),
    TPYIndex_191_list(462,147,328,236,445, 25,350,333,117, 18,172,451,351, 84, 25,482,142,328,292,506,
     420,319,117,498,184,136,395, 89, 69,418,340,399,160,505,106,  4,451,502,510,478,
     234,246,439,477,477, 24,451,177,209,462,459,125,166,223,117,193,466, 97,187,431,
     262,390,498,  0,417,347,483,282,503,142,128,413,456,350,393,337,164,433,229,386,
     386,193,259, 47,229,521,457,481,393,518,339,506,460,282, 57,172, 84,526,445,459,
     266,507,472,387, 47,441,225,215,320,161,431,467,145,422,223, 26,177,457,184,229,
     470,395, 67, 96,349,469, 63, 22, 13,418,175,117,342,507,117,388,229,445,173, 25,
     420,214,345, 18,459,459,172,177,232,172, 58,163, 48,507, 83, 25,507,175, 85, 53,
     508,184, 97, 67,329,365,295,317,339, 51,186,337,108, 63,510,235, 42,234,523,462,
     507, 84,268,466,268,328,161,186,389,136,524),
    TPYIndex_191_list(346,136,509, 89,220,110,291,477,215,242,182, 43,180,245,236,521,229,259,520,507,
     292,161,483, 81,395,393,164,431,160,506,510,219,520,495, 20, 20,164,352,495,451,
     451,483, 57,365,498,165,231,472,350,350,175, 18, 98,473,117,457,459,458,451,161,
     395,371,468,  0,452,341,149,456,318,378,237,249,395,395,215,518,427,418,474,125,
     481,341,339,452,371,393,231,  6,224,166,265,172,433,351,175,393,251,133,413,507,
     518,348,232,483,229,452,435,172,320,110,386,478,  3,459,250, 46,184, 13,433,518,
     478,483, 58,455,265,484,445,515,416,187,184,246,351, 50,349,243,456,491,270,  6,
     237, 15,463,482,109,  7,333,292,242,413,117,160,420,141,178,451,106,172,177,460,
     470,128,229,231,175,395,433,142,386,164,172,348,236,521,110,215, 43,136,291,292,
      84,395,518,111, 85, 98,350,117,165, 20,378),
    TPYIndex_191_list(457,350, 21,172,172,510,176,466,513,481,501,192,469, 22,483,351,460, 25,177,470,
     413,165,525,445,388,108,186,235,470,263,457,497,460,111,139,160,211,495,378,500,
     122,141,479,229, 43,225,399,  3,366,172,483,161,399,229,234,246,264,505,460, 98,
     242,139,229,  0,459, 72,172,444,  7,151,482,498, 25,328,193,439,495,160,211,498,
     187,481,339,393, 18, 43,431,452,451,352,176,318,341,451,457,161,122,  6,339,418,
     139,474,224, 21,469,251,265,481,141,388,525,229, 68,473, 68,345,251,175,184,365,
     135, 15,178,440,209,136, 81,160,125,194, 18,241,340,212, 23, 91,257,  7,472,232,
     461,450, 48,460,472,434,423,481, 19,215,254,357,433,172,518,466,352,182, 23,164,
     234,256,166,261,172,187,510,261,339,  6,391,235, 69, 51,482,458,477,351, 91,229,
     348, 30,  4,111,482,456,472,457,350,147,498),
    TPYIndex_191_list(500,139,353,477,117,229,507, 26,472,117,502,172,112,366,472,395,112,266, 13,484,
     507,161,347,141,111,452,500,395,483,116,474,186,186,328,164,505, 13,472,471,506,
     109,112,452,313, 69,125,366,236,264,117,445,452,229, 20,507,125,484, 59,351,461,
      48, 70,184,  0,474,136,508,483,473,483,471,434,483,432,479, 94,456,106,137,  3,
     507,472,155,461,173,234,510,473,477,159,242,366,270,125,361,461,466,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0)
     );
BEGIN
  IF (p_Index>0) AND (p_Index<192) THEN
    RETURN v_list12(p_Index1)(p_Index);
  ELSE
    RETURN 0;
  END IF;
end get_py_index_12;


FUNCTION get_py_index_13(p_Index1 NUMBER, p_Index NUMBER)
RETURN NUMBER IS
  v_list13 TPYIndex_list := TPYIndex_list(
     TPYIndex_191_list(509, 48,246,155,292, 98,243,173,172,441,185,445,337,456,185,483, 25,187,187, 18,
     457,187,184,441,180,431, 98, 98,213,161,456,393,220,177,317,242,328,399,117,471,
     517,322,350,341, 15, 84,242,353,175,184,441,471,484,339,229,475,515,206, 97,215,
     394,339,180,  0,477,477,348,518,220, 89,339,442,128,184,351,477,525,172,399,446,
      48,263,365,471,350,431,161,431, 98,178,254,117, 57,441,472,151,484,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
    TPYIndex_191_list(329,215,257,161,479,507,456,184, 89,342,109,161,479,484,459,453,395,151, 51,422,
     458,371,237,172,161,341,470,147, 59, 59,477,474,472,172,229,432,208,431,431,477,
     441,249,461,124,432, 46,172,442,503,  6,474,477,313, 48,507,237,481,247, 18,403,
     517,483,456,  0,186,478,431,408,177,477,162, 18,479,413,165,108,177,233,472,124,
     182,459,459,441,250,525,483,479,242,442,459,469,477,328,510,246,457,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
    TPYIndex_191_list(477,172,494,483,500,475,473,328,297,161,261,479,259, 81,485,483,225, 26,242,151,
     240,403,485,479,352,351,229,243,395,342,461,236,469,155,509,456,215,341,128,484,
     413,151,350,477,453,237,172,477,477,164,500,259,403,242,179,236,175,459, 67,175,
     175,472,482,  0, 63,319, 63,319,510,175,261,483,237, 46,354,235,291,182,354,180,
     408,460,472,173,261,229,501,180,339,236,472, 63,250,151, 44,117,262,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
    TPYIndex_191_list(262,117,319,351,351,270,117,472,220,262, 48,112,351,262,268,268,521,304,111,165,
     179,140,432,440,162,213,159, 48,152,477, 70,457,444,268,341,500,472,257,472,485,
     422,472,472,472,505,505,516, 30,477,257,500,472, 91,242,111,265,484, 63,351,502,
     447,510,507,  0,259,  6, 22,445, 18,502,261,505,518,136, 89,111,484, 43,124,339,
     484,422,427,399,110,452,110, 84,445,508,351,394,395,395,435,457,180,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
    TPYIndex_191_list(167,457,472,441,408,459,225,474,456,456,209,462,151,466,453,498,299,279,518,499,
     172,518,172,172, 48, 46, 46,151,471,478,462, 13,494,462,518, 48,472,498,433,236,
     236, 51,352,462,478,295,182,474, 58,487,483, 51,477,291,498,521,351,487,472,483,
      98,455,477,  0, 67,521, 83, 51,179,471,151,478,252,318,455,318,472,252,240,133,
     194, 68,236, 68,350,350, 22, 56,151,186,462,485,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0),
    TPYIndex_191_list(  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0)
     );
BEGIN
  IF (p_Index>0) AND (p_Index<192) THEN
    RETURN v_list13(p_Index1)(p_Index);
  ELSE
    RETURN 0;
  END IF;
end get_py_index_13;


FUNCTION GetHzFullPY(p_String varchar2)
 RETURN VARCHAR2 IS
--declare
 --p_String varchar2(200) := '???????';
 v_char varchar2(2);  --????
 n_loop number;    --??
 n_len number;     --????
 n_ascii number;   --??ASCII?
 n_ord_high number; --n_ascii/156
 n_ord_low number;  --n mod 256
 n_temp number;
 n_temp1 number;
 v_PY varchar2(32767);

BEGIN
  v_PY := '';
  n_len := length(p_String);
  FOR n_loop IN 1..n_len LOOP
    v_char := substr(p_string,n_loop,1);
    IF upper(v_char) IN (
        'A','B','C','D','E','F','G',
        'H','I','J','K','L','M','N',
        'O','P','Q','R','S','T',
        'U','V','W','X','Y','Z',
        '0','1','2','3','4','5','6','7','8','9',
        '(', ')', '[', ']','.', '!', '@', '#', '$',
        '%', '^', '&', '*', '-', '+','<', '>', '?', ':', '"')  THEN
      v_PY := v_PY||v_char;
    ELSE
        n_ascii := ascii(v_char);
        n_ord_high := trunc(n_ascii/256,0);
        n_ord_low := n_ascii-(n_ord_high*256);
        --DBMS_OUTPUT.PUT_LINE('n_ascii = '||to_char(n_ascii,'9999999'));
        --DBMS_OUTPUT.PUT_LINE('n_ord_high = '||to_char(n_ord_high,'9999999'));
        --DBMS_OUTPUT.PUT_LINE('n_ord_low = '||to_char(n_ord_low,'9999999'));
        IF (n_ord_high>128) and (n_ord_low>63) THEN
          CASE n_ord_high
            WHEN 162 THEN     --????
              IF n_ord_low>160 THEN
                v_PY := v_PY||get_roma_num_py(n_ord_low-160);
              END IF;
            WHEN 163 THEN     --??ASCII
              IF n_ord_low>128 THEN
                v_char := chr(n_ord_low-128);
                IF upper(v_char) IN (
                   'A','B','C','D','E','F','G',
                   'H','I','J','K','L','M','N',
                   'O','P','Q','R','S','T',
                   'U','V','W','X','Y','Z',
                   '0','1','2','3','4','5','6','7','8','9',
                   '(', ')', '[', ']') THEN
                  v_PY := v_PY||v_char;
                END IF;
              END IF;
            WHEN 166 THEN     --????
              IF (n_ord_low>160) AND (n_ord_low<185) THEN --A1--B8
                v_PY := v_PY||get_greece_alphabet_py(n_ord_low-160);
              ELSE
                IF (n_ord_low>192) AND (n_ord_low<217) THEN --C1--D8
                  v_PY := v_PY||get_greece_alphabet_py(n_ord_low-192);
                END IF;
              END IF;
            ELSE
            BEGIN
              n_temp := n_ord_high-128;
              n_ord_low := n_ord_low-63;
              n_temp1 := trunc(n_temp/10,0);
              n_temp1 := n_temp-n_temp1*10;
              IF n_temp1=0 THEN
                n_temp1 := 10;
              END IF;
              --DBMS_OUTPUT.PUT_LINE('n_temp = '||to_char(n_temp,'9999999'));
              --DBMS_OUTPUT.PUT_LINE('n_temp1 = '||to_char(n_temp1,'9999999'));
              CASE
              WHEN n_temp<11 THEN
                n_temp1 := get_py_index_01(n_temp1,n_ord_low);
              WHEN n_temp<21 THEN
                n_temp1 := get_py_index_02(n_temp1,n_ord_low);
              WHEN n_temp<31 THEN
                n_temp1 := get_py_index_03(n_temp1,n_ord_low);
              WHEN n_temp<41 THEN
                n_temp1 := get_py_index_04(n_temp1,n_ord_low);
              WHEN n_temp<51 THEN
                n_temp1 := get_py_index_05(n_temp1,n_ord_low);
              WHEN n_temp<61 THEN
                n_temp1 := get_py_index_06(n_temp1,n_ord_low);
              WHEN n_temp<71 THEN
                n_temp1 := get_py_index_07(n_temp1,n_ord_low);
              WHEN n_temp<81 THEN
                n_temp1 := get_py_index_08(n_temp1,n_ord_low);
              WHEN n_temp<91 THEN
                n_temp1 := get_py_index_09(n_temp1,n_ord_low);
              WHEN n_temp<101 THEN
                n_temp1 := get_py_index_10(n_temp1,n_ord_low);
              WHEN n_temp<111 THEN
                n_temp1 := get_py_index_11(n_temp1,n_ord_low);
              WHEN n_temp<121 THEN
                n_temp1 := get_py_index_12(n_temp1,n_ord_low);
              WHEN n_temp<121 THEN
                n_temp1 := get_py_index_13(n_temp1,n_ord_low);
              ELSE
                n_temp1 := 0;
              END CASE;
              v_PY := v_PY||GetHzPY_by_index(n_temp1);
            END;
          END CASE;
        END IF;
    END IF;
  END LOOP;
  RETURN v_PY;
  --DBMS_OUTPUT.PUT_LINE(v_PY);
END;


FUNCTION GetHzFullPYLower(p_String varchar2)
 RETURN VARCHAR2 IS
--declare
 --p_String varchar2(200) := '???????';
 v_char varchar2(2);  --????
 n_loop number;    --??
 n_len number;     --????
 n_ascii number;   --??ASCII?
 n_ord_high number; --n_ascii/156
 n_ord_low number;  --n mod 256
 n_temp number;
 n_temp1 number;
 v_PY varchar2(32767);

BEGIN
  v_PY := '';
  n_len := length(p_String);
  FOR n_loop IN 1..n_len LOOP
    v_char := substr(p_string,n_loop,1);
    IF upper(v_char) IN (
        'A','B','C','D','E','F','G',
        'H','I','J','K','L','M','N',
        'O','P','Q','R','S','T',
        'U','V','W','X','Y','Z',
        '0','1','2','3','4','5','6','7','8','9',
        '(', ')', '[', ']','.', '!', '@', '#', '$',
        '%', '^', '&', '*', '-', '+','<', '>', '?', ':', '"')  THEN
      v_PY := v_PY||v_char;
    ELSE
        n_ascii := ascii(v_char);
        n_ord_high := trunc(n_ascii/256,0);
        n_ord_low := n_ascii-(n_ord_high*256);
        --DBMS_OUTPUT.PUT_LINE('n_ascii = '||to_char(n_ascii,'9999999'));
        --DBMS_OUTPUT.PUT_LINE('n_ord_high = '||to_char(n_ord_high,'9999999'));
        --DBMS_OUTPUT.PUT_LINE('n_ord_low = '||to_char(n_ord_low,'9999999'));
        IF (n_ord_high>128) and (n_ord_low>63) THEN
          CASE n_ord_high
            WHEN 162 THEN     --????
              IF n_ord_low>160 THEN
                v_PY := v_PY||get_roma_num_py(n_ord_low-160);
              END IF;
            WHEN 163 THEN     --??ASCII
              IF n_ord_low>128 THEN
                v_char := chr(n_ord_low-128);
                IF upper(v_char) IN (
                   'A','B','C','D','E','F','G',
                   'H','I','J','K','L','M','N',
                   'O','P','Q','R','S','T',
                   'U','V','W','X','Y','Z',
                   '0','1','2','3','4','5','6','7','8','9',
                   '(', ')', '[', ']') THEN
                  v_PY := v_PY||v_char;
                END IF;
              END IF;
            WHEN 166 THEN     --????
              IF (n_ord_low>160) AND (n_ord_low<185) THEN --A1--B8
                v_PY := v_PY||get_greece_alphabet_py(n_ord_low-160);
              ELSE
                IF (n_ord_low>192) AND (n_ord_low<217) THEN --C1--D8
                  v_PY := v_PY||get_greece_alphabet_py(n_ord_low-192);
                END IF;
              END IF;
            ELSE
            BEGIN
              n_temp := n_ord_high-128;
              n_ord_low := n_ord_low-63;
              n_temp1 := trunc(n_temp/10,0);
              n_temp1 := n_temp-n_temp1*10;
              IF n_temp1=0 THEN
                n_temp1 := 10;
              END IF;
              --DBMS_OUTPUT.PUT_LINE('n_temp = '||to_char(n_temp,'9999999'));
              --DBMS_OUTPUT.PUT_LINE('n_temp1 = '||to_char(n_temp1,'9999999'));
              CASE
              WHEN n_temp<11 THEN
                n_temp1 := get_py_index_01(n_temp1,n_ord_low);
              WHEN n_temp<21 THEN
                n_temp1 := get_py_index_02(n_temp1,n_ord_low);
              WHEN n_temp<31 THEN
                n_temp1 := get_py_index_03(n_temp1,n_ord_low);
              WHEN n_temp<41 THEN
                n_temp1 := get_py_index_04(n_temp1,n_ord_low);
              WHEN n_temp<51 THEN
                n_temp1 := get_py_index_05(n_temp1,n_ord_low);
              WHEN n_temp<61 THEN
                n_temp1 := get_py_index_06(n_temp1,n_ord_low);
              WHEN n_temp<71 THEN
                n_temp1 := get_py_index_07(n_temp1,n_ord_low);
              WHEN n_temp<81 THEN
                n_temp1 := get_py_index_08(n_temp1,n_ord_low);
              WHEN n_temp<91 THEN
                n_temp1 := get_py_index_09(n_temp1,n_ord_low);
              WHEN n_temp<101 THEN
                n_temp1 := get_py_index_10(n_temp1,n_ord_low);
              WHEN n_temp<111 THEN
                n_temp1 := get_py_index_11(n_temp1,n_ord_low);
              WHEN n_temp<121 THEN
                n_temp1 := get_py_index_12(n_temp1,n_ord_low);
              WHEN n_temp<121 THEN
                n_temp1 := get_py_index_13(n_temp1,n_ord_low);
              ELSE
                n_temp1 := 0;
              END CASE;
              v_PY := v_PY||GetHzPY_by_index(n_temp1);
            END;
          END CASE;
        END IF;
    END IF;
  END LOOP;
  RETURN Lower(v_PY);
  --DBMS_OUTPUT.PUT_LINE(v_PY);
END;

FUNCTION GetHzFullPYUpper(p_String varchar2)
 RETURN VARCHAR2 IS
--declare
 --p_String varchar2(200) := '???????';
 v_char varchar2(2);  --????
 n_loop number;    --??
 n_len number;     --????
 n_ascii number;   --??ASCII?
 n_ord_high number; --n_ascii/156
 n_ord_low number;  --n mod 256
 n_temp number;
 n_temp1 number;
 v_PY varchar2(32767);

BEGIN
  v_PY := '';
  n_len := length(p_String);
  FOR n_loop IN 1..n_len LOOP
    v_char := substr(p_string,n_loop,1);
    IF upper(v_char) IN (
        'A','B','C','D','E','F','G',
        'H','I','J','K','L','M','N',
        'O','P','Q','R','S','T',
        'U','V','W','X','Y','Z',
        '0','1','2','3','4','5','6','7','8','9',
        '(', ')', '[', ']','.', '!', '@', '#', '$',
        '%', '^', '&', '*', '-', '+','<', '>', '?', ':', '"')  THEN
      v_PY := v_PY||v_char;
    ELSE
        n_ascii := ascii(v_char);
        n_ord_high := trunc(n_ascii/256,0);
        n_ord_low := n_ascii-(n_ord_high*256);
        --DBMS_OUTPUT.PUT_LINE('n_ascii = '||to_char(n_ascii,'9999999'));
        --DBMS_OUTPUT.PUT_LINE('n_ord_high = '||to_char(n_ord_high,'9999999'));
        --DBMS_OUTPUT.PUT_LINE('n_ord_low = '||to_char(n_ord_low,'9999999'));
        IF (n_ord_high>128) and (n_ord_low>63) THEN
          CASE n_ord_high
            WHEN 162 THEN     --????
              IF n_ord_low>160 THEN
                v_PY := v_PY||get_roma_num_py(n_ord_low-160);
              END IF;
            WHEN 163 THEN     --??ASCII
              IF n_ord_low>128 THEN
                v_char := chr(n_ord_low-128);
                IF upper(v_char) IN (
                   'A','B','C','D','E','F','G',
                   'H','I','J','K','L','M','N',
                   'O','P','Q','R','S','T',
                   'U','V','W','X','Y','Z',
                   '0','1','2','3','4','5','6','7','8','9',
                   '(', ')', '[', ']') THEN
                  v_PY := v_PY||v_char;
                END IF;
              END IF;
            WHEN 166 THEN     --????
              IF (n_ord_low>160) AND (n_ord_low<185) THEN --A1--B8
                v_PY := v_PY||get_greece_alphabet_py(n_ord_low-160);
              ELSE
                IF (n_ord_low>192) AND (n_ord_low<217) THEN --C1--D8
                  v_PY := v_PY||get_greece_alphabet_py(n_ord_low-192);
                END IF;
              END IF;
            ELSE
            BEGIN
              n_temp := n_ord_high-128;
              n_ord_low := n_ord_low-63;
              n_temp1 := trunc(n_temp/10,0);
              n_temp1 := n_temp-n_temp1*10;
              IF n_temp1=0 THEN
                n_temp1 := 10;
              END IF;
              --DBMS_OUTPUT.PUT_LINE('n_temp = '||to_char(n_temp,'9999999'));
              --DBMS_OUTPUT.PUT_LINE('n_temp1 = '||to_char(n_temp1,'9999999'));
              CASE
              WHEN n_temp<11 THEN
                n_temp1 := get_py_index_01(n_temp1,n_ord_low);
              WHEN n_temp<21 THEN
                n_temp1 := get_py_index_02(n_temp1,n_ord_low);
              WHEN n_temp<31 THEN
                n_temp1 := get_py_index_03(n_temp1,n_ord_low);
              WHEN n_temp<41 THEN
                n_temp1 := get_py_index_04(n_temp1,n_ord_low);
              WHEN n_temp<51 THEN
                n_temp1 := get_py_index_05(n_temp1,n_ord_low);
              WHEN n_temp<61 THEN
                n_temp1 := get_py_index_06(n_temp1,n_ord_low);
              WHEN n_temp<71 THEN
                n_temp1 := get_py_index_07(n_temp1,n_ord_low);
              WHEN n_temp<81 THEN
                n_temp1 := get_py_index_08(n_temp1,n_ord_low);
              WHEN n_temp<91 THEN
                n_temp1 := get_py_index_09(n_temp1,n_ord_low);
              WHEN n_temp<101 THEN
                n_temp1 := get_py_index_10(n_temp1,n_ord_low);
              WHEN n_temp<111 THEN
                n_temp1 := get_py_index_11(n_temp1,n_ord_low);
              WHEN n_temp<121 THEN
                n_temp1 := get_py_index_12(n_temp1,n_ord_low);
              WHEN n_temp<121 THEN
                n_temp1 := get_py_index_13(n_temp1,n_ord_low);
              ELSE
                n_temp1 := 0;
              END CASE;
              v_PY := v_PY||GetHzPY_by_index(n_temp1);
            END;
          END CASE;
        END IF;
    END IF;
  END LOOP;
  RETURN Upper(v_PY);
  --DBMS_OUTPUT.PUT_LINE(v_PY);
END GetHzFullPYUpper;

FUNCTION GetHzFullPYsubstr(p_String varchar2,s float, e float)
 RETURN VARCHAR2 IS
--declare
 --p_String varchar2(200) := '???????';
 v_char varchar2(2);  --????
 n_loop number;    --??
 n_len number;     --????
 n_ascii number;   --??ASCII?
 n_ord_high number; --n_ascii/156
 n_ord_low number;  --n mod 256
 n_temp number;
 n_temp1 number;
 v_PY varchar2(32767);

BEGIN
  v_PY := '';
  n_len := length(p_String);
  FOR n_loop IN 1..n_len LOOP
    v_char := substr(p_string,n_loop,1);
    IF upper(v_char) IN (
        'A','B','C','D','E','F','G',
        'H','I','J','K','L','M','N',
        'O','P','Q','R','S','T',
        'U','V','W','X','Y','Z',
        '0','1','2','3','4','5','6','7','8','9',
        '(', ')', '[', ']','.', '!', '@', '#', '$',
        '%', '^', '&', '*', '-', '+','<', '>', '?', ':', '"')  THEN
      v_PY := v_PY||v_char;
    ELSE
        n_ascii := ascii(v_char);
        n_ord_high := trunc(n_ascii/256,0);
        n_ord_low := n_ascii-(n_ord_high*256);
        --DBMS_OUTPUT.PUT_LINE('n_ascii = '||to_char(n_ascii,'9999999'));
        --DBMS_OUTPUT.PUT_LINE('n_ord_high = '||to_char(n_ord_high,'9999999'));
        --DBMS_OUTPUT.PUT_LINE('n_ord_low = '||to_char(n_ord_low,'9999999'));
        IF (n_ord_high>128) and (n_ord_low>63) THEN
          CASE n_ord_high
            WHEN 162 THEN     --????
              IF n_ord_low>160 THEN
                v_PY := v_PY||get_roma_num_py(n_ord_low-160);
              END IF;
            WHEN 163 THEN     --??ASCII
              IF n_ord_low>128 THEN
                v_char := chr(n_ord_low-128);
                IF upper(v_char) IN (
                   'A','B','C','D','E','F','G',
                   'H','I','J','K','L','M','N',
                   'O','P','Q','R','S','T',
                   'U','V','W','X','Y','Z',
                   '0','1','2','3','4','5','6','7','8','9',
                   '(', ')', '[', ']') THEN
                  v_PY := v_PY||v_char;
                END IF;
              END IF;
            WHEN 166 THEN     --????
              IF (n_ord_low>160) AND (n_ord_low<185) THEN --A1--B8
                v_PY := v_PY||get_greece_alphabet_py(n_ord_low-160);
              ELSE
                IF (n_ord_low>192) AND (n_ord_low<217) THEN --C1--D8
                  v_PY := v_PY||get_greece_alphabet_py(n_ord_low-192);
                END IF;
              END IF;
            ELSE
            BEGIN
              n_temp := n_ord_high-128;
              n_ord_low := n_ord_low-63;
              n_temp1 := trunc(n_temp/10,0);
              n_temp1 := n_temp-n_temp1*10;
              IF n_temp1=0 THEN
                n_temp1 := 10;
              END IF;
              --DBMS_OUTPUT.PUT_LINE('n_temp = '||to_char(n_temp,'9999999'));
              --DBMS_OUTPUT.PUT_LINE('n_temp1 = '||to_char(n_temp1,'9999999'));
              CASE
              WHEN n_temp<11 THEN
                n_temp1 := get_py_index_01(n_temp1,n_ord_low);
              WHEN n_temp<21 THEN
                n_temp1 := get_py_index_02(n_temp1,n_ord_low);
              WHEN n_temp<31 THEN
                n_temp1 := get_py_index_03(n_temp1,n_ord_low);
              WHEN n_temp<41 THEN
                n_temp1 := get_py_index_04(n_temp1,n_ord_low);
              WHEN n_temp<51 THEN
                n_temp1 := get_py_index_05(n_temp1,n_ord_low);
              WHEN n_temp<61 THEN
                n_temp1 := get_py_index_06(n_temp1,n_ord_low);
              WHEN n_temp<71 THEN
                n_temp1 := get_py_index_07(n_temp1,n_ord_low);
              WHEN n_temp<81 THEN
                n_temp1 := get_py_index_08(n_temp1,n_ord_low);
              WHEN n_temp<91 THEN
                n_temp1 := get_py_index_09(n_temp1,n_ord_low);
              WHEN n_temp<101 THEN
                n_temp1 := get_py_index_10(n_temp1,n_ord_low);
              WHEN n_temp<111 THEN
                n_temp1 := get_py_index_11(n_temp1,n_ord_low);
              WHEN n_temp<121 THEN
                n_temp1 := get_py_index_12(n_temp1,n_ord_low);
              WHEN n_temp<121 THEN
                n_temp1 := get_py_index_13(n_temp1,n_ord_low);
              ELSE
                n_temp1 := 0;
              END CASE;
              v_PY := v_PY||GetHzPY_by_index(n_temp1);
            END;
          END CASE;
        END IF;
    END IF;
  END LOOP;
  RETURN substr(v_PY,s,e);
  --DBMS_OUTPUT.PUT_LINE(v_PY);
END GetHzFullPYsubstr;

 FUNCTION GetHzPYCAP(p_String varchar2) RETURN VARCHAR2 IS
--declare
 --p_String varchar2(200) := '???????';
 v_char varchar2(2);  --????
 n_loop number;    --??
 n_len number;     --????
 n_ascii number;   --??ASCII?
 n_ord_high number; --n_ascii/156
 n_ord_low number;  --n mod 256
 n_temp number;
 n_temp1 number;
 v_PY varchar2(32767);

BEGIN
  v_PY := '';
  n_len := length(p_String);
  FOR n_loop IN 1..n_len LOOP
    v_char := substr(p_string,n_loop,1);
    IF upper(v_char) IN (
        'A','B','C','D','E','F','G',
        'H','I','J','K','L','M','N',
        'O','P','Q','R','S','T',
        'U','V','W','X','Y','Z',
        '0','1','2','3','4','5','6','7','8','9',
        '(', ')', '[', ']','.', '!', '@', '#', '$',
        '%', '^', '&', '*', '-', '+','<', '>', '?', ':', '"')  THEN
      v_PY := v_PY||v_char;
    ELSE
        n_ascii := ascii(v_char);
        n_ord_high := trunc(n_ascii/256,0);
        n_ord_low := n_ascii-(n_ord_high*256);
        --DBMS_OUTPUT.PUT_LINE('n_ascii = '||to_char(n_ascii,'9999999'));
        --DBMS_OUTPUT.PUT_LINE('n_ord_high = '||to_char(n_ord_high,'9999999'));
        --DBMS_OUTPUT.PUT_LINE('n_ord_low = '||to_char(n_ord_low,'9999999'));
        IF (n_ord_high>128) and (n_ord_low>63) THEN
          CASE n_ord_high
            WHEN 162 THEN     --????
              IF n_ord_low>160 THEN
                v_PY := v_PY||get_roma_num_py(n_ord_low-160);
              END IF;
            WHEN 163 THEN     --??ASCII
              IF n_ord_low>128 THEN
                v_char := chr(n_ord_low-128);
                IF upper(v_char) IN (
                   'A','B','C','D','E','F','G',
                   'H','I','J','K','L','M','N',
                   'O','P','Q','R','S','T',
                   'U','V','W','X','Y','Z',
                   '0','1','2','3','4','5','6','7','8','9',
                   '(', ')', '[', ']') THEN
                  v_PY := v_PY||v_char;
                END IF;
              END IF;
            WHEN 166 THEN     --????
              IF (n_ord_low>160) AND (n_ord_low<185) THEN --A1--B8
                v_PY := v_PY||get_greece_alphabet_py(n_ord_low-160);
              ELSE
                IF (n_ord_low>192) AND (n_ord_low<217) THEN --C1--D8
                  v_PY := v_PY||get_greece_alphabet_py(n_ord_low-192);
                END IF;
              END IF;
            ELSE
            BEGIN
              n_temp := n_ord_high-128;
              n_ord_low := n_ord_low-63;
              n_temp1 := trunc(n_temp/10,0);
              n_temp1 := n_temp-n_temp1*10;
              IF n_temp1=0 THEN
                n_temp1 := 10;
              END IF;
              --DBMS_OUTPUT.PUT_LINE('n_temp = '||to_char(n_temp,'9999999'));
              --DBMS_OUTPUT.PUT_LINE('n_temp1 = '||to_char(n_temp1,'9999999'));
              CASE
              WHEN n_temp<11 THEN
                n_temp1 := get_py_index_01(n_temp1,n_ord_low);
              WHEN n_temp<21 THEN
                n_temp1 := get_py_index_02(n_temp1,n_ord_low);
              WHEN n_temp<31 THEN
                n_temp1 := get_py_index_03(n_temp1,n_ord_low);
              WHEN n_temp<41 THEN
                n_temp1 := get_py_index_04(n_temp1,n_ord_low);
              WHEN n_temp<51 THEN
                n_temp1 := get_py_index_05(n_temp1,n_ord_low);
              WHEN n_temp<61 THEN
                n_temp1 := get_py_index_06(n_temp1,n_ord_low);
              WHEN n_temp<71 THEN
                n_temp1 := get_py_index_07(n_temp1,n_ord_low);
              WHEN n_temp<81 THEN
                n_temp1 := get_py_index_08(n_temp1,n_ord_low);
              WHEN n_temp<91 THEN
                n_temp1 := get_py_index_09(n_temp1,n_ord_low);
              WHEN n_temp<101 THEN
                n_temp1 := get_py_index_10(n_temp1,n_ord_low);
              WHEN n_temp<111 THEN
                n_temp1 := get_py_index_11(n_temp1,n_ord_low);
              WHEN n_temp<121 THEN
                n_temp1 := get_py_index_12(n_temp1,n_ord_low);
              WHEN n_temp<121 THEN
                n_temp1 := get_py_index_13(n_temp1,n_ord_low);
              ELSE
                n_temp1 := 0;
              END CASE;
              v_PY := v_PY||substr(GetHzPY_by_index(n_temp1),1,1);
            END;
          END CASE;
        END IF;
    END IF;
  END LOOP;
  RETURN v_PY;
  --DBMS_OUTPUT.PUT_LINE(v_PY);
END GetHzPYCAP;


FUNCTION GetHzPYCAPLower(p_String varchar2) RETURN VARCHAR2 IS
--declare
 --p_String varchar2(200) := '???????';
 v_char varchar2(2);  --????
 n_loop number;    --??
 n_len number;     --????
 n_ascii number;   --??ASCII?
 n_ord_high number; --n_ascii/156
 n_ord_low number;  --n mod 256
 n_temp number;
 n_temp1 number;
 v_PY varchar2(32767);

BEGIN
  v_PY := '';
  n_len := length(p_String);
  FOR n_loop IN 1..n_len LOOP
    v_char := substr(p_string,n_loop,1);
    IF upper(v_char) IN (
        'A','B','C','D','E','F','G',
        'H','I','J','K','L','M','N',
        'O','P','Q','R','S','T',
        'U','V','W','X','Y','Z',
        '0','1','2','3','4','5','6','7','8','9',
        '(', ')', '[', ']','.', '!', '@', '#', '$',
        '%', '^', '&', '*', '-', '+','<', '>', '?', ':', '"')  THEN
      v_PY := v_PY||v_char;
    ELSE
        n_ascii := ascii(v_char);
        n_ord_high := trunc(n_ascii/256,0);
        n_ord_low := n_ascii-(n_ord_high*256);
        --DBMS_OUTPUT.PUT_LINE('n_ascii = '||to_char(n_ascii,'9999999'));
        --DBMS_OUTPUT.PUT_LINE('n_ord_high = '||to_char(n_ord_high,'9999999'));
        --DBMS_OUTPUT.PUT_LINE('n_ord_low = '||to_char(n_ord_low,'9999999'));
        IF (n_ord_high>128) and (n_ord_low>63) THEN
          CASE n_ord_high
            WHEN 162 THEN     --????
              IF n_ord_low>160 THEN
                v_PY := v_PY||get_roma_num_py(n_ord_low-160);
              END IF;
            WHEN 163 THEN     --??ASCII
              IF n_ord_low>128 THEN
                v_char := chr(n_ord_low-128);
                IF upper(v_char) IN (
                   'A','B','C','D','E','F','G',
                   'H','I','J','K','L','M','N',
                   'O','P','Q','R','S','T',
                   'U','V','W','X','Y','Z',
                   '0','1','2','3','4','5','6','7','8','9',
                   '(', ')', '[', ']') THEN
                  v_PY := v_PY||v_char;
                END IF;
              END IF;
            WHEN 166 THEN     --????
              IF (n_ord_low>160) AND (n_ord_low<185) THEN --A1--B8
                v_PY := v_PY||get_greece_alphabet_py(n_ord_low-160);
              ELSE
                IF (n_ord_low>192) AND (n_ord_low<217) THEN --C1--D8
                  v_PY := v_PY||get_greece_alphabet_py(n_ord_low-192);
                END IF;
              END IF;
            ELSE
            BEGIN
              n_temp := n_ord_high-128;
              n_ord_low := n_ord_low-63;
              n_temp1 := trunc(n_temp/10,0);
              n_temp1 := n_temp-n_temp1*10;
              IF n_temp1=0 THEN
                n_temp1 := 10;
              END IF;
              --DBMS_OUTPUT.PUT_LINE('n_temp = '||to_char(n_temp,'9999999'));
              --DBMS_OUTPUT.PUT_LINE('n_temp1 = '||to_char(n_temp1,'9999999'));
              CASE
              WHEN n_temp<11 THEN
                n_temp1 := get_py_index_01(n_temp1,n_ord_low);
              WHEN n_temp<21 THEN
                n_temp1 := get_py_index_02(n_temp1,n_ord_low);
              WHEN n_temp<31 THEN
                n_temp1 := get_py_index_03(n_temp1,n_ord_low);
              WHEN n_temp<41 THEN
                n_temp1 := get_py_index_04(n_temp1,n_ord_low);
              WHEN n_temp<51 THEN
                n_temp1 := get_py_index_05(n_temp1,n_ord_low);
              WHEN n_temp<61 THEN
                n_temp1 := get_py_index_06(n_temp1,n_ord_low);
              WHEN n_temp<71 THEN
                n_temp1 := get_py_index_07(n_temp1,n_ord_low);
              WHEN n_temp<81 THEN
                n_temp1 := get_py_index_08(n_temp1,n_ord_low);
              WHEN n_temp<91 THEN
                n_temp1 := get_py_index_09(n_temp1,n_ord_low);
              WHEN n_temp<101 THEN
                n_temp1 := get_py_index_10(n_temp1,n_ord_low);
              WHEN n_temp<111 THEN
                n_temp1 := get_py_index_11(n_temp1,n_ord_low);
              WHEN n_temp<121 THEN
                n_temp1 := get_py_index_12(n_temp1,n_ord_low);
              WHEN n_temp<121 THEN
                n_temp1 := get_py_index_13(n_temp1,n_ord_low);
              ELSE
                n_temp1 := 0;
              END CASE;
              v_PY := v_PY||substr(GetHzPY_by_index(n_temp1),1,1);
            END;
          END CASE;
        END IF;
    END IF;
  END LOOP;
  RETURN Lower(v_PY);
  --DBMS_OUTPUT.PUT_LINE(v_PY);
END GetHzPYCAPLower;


FUNCTION GetHzPYCAPsubstr(p_String varchar2,s float, e float)
   RETURN VARCHAR2 IS
--declare
 --p_String varchar2(200) := '???????';
 v_char varchar2(2);  --????
 n_loop number;    --??
 n_len number;     --????
 n_ascii number;   --??ASCII?
 n_ord_high number; --n_ascii/156
 n_ord_low number;  --n mod 256
 n_temp number;
 n_temp1 number;
 v_PY varchar2(32767);

BEGIN
  v_PY := '';
  n_len := length(p_String);
  FOR n_loop IN 1..n_len LOOP
    v_char := substr(p_string,n_loop,1);
    IF upper(v_char) IN (
        'A','B','C','D','E','F','G',
        'H','I','J','K','L','M','N',
        'O','P','Q','R','S','T',
        'U','V','W','X','Y','Z',
        '0','1','2','3','4','5','6','7','8','9',
        '(', ')', '[', ']','.', '!', '@', '#', '$',
        '%', '^', '&', '*', '-', '+','<', '>', '?', ':', '"')  THEN
      v_PY := v_PY||v_char;
    ELSE
        n_ascii := ascii(v_char);
        n_ord_high := trunc(n_ascii/256,0);
        n_ord_low := n_ascii-(n_ord_high*256);
        --DBMS_OUTPUT.PUT_LINE('n_ascii = '||to_char(n_ascii,'9999999'));
        --DBMS_OUTPUT.PUT_LINE('n_ord_high = '||to_char(n_ord_high,'9999999'));
        --DBMS_OUTPUT.PUT_LINE('n_ord_low = '||to_char(n_ord_low,'9999999'));
        IF (n_ord_high>128) and (n_ord_low>63) THEN
          CASE n_ord_high
            WHEN 162 THEN     --????
              IF n_ord_low>160 THEN
                v_PY := v_PY||get_roma_num_py(n_ord_low-160);
              END IF;
            WHEN 163 THEN     --??ASCII
              IF n_ord_low>128 THEN
                v_char := chr(n_ord_low-128);
                IF upper(v_char) IN (
                   'A','B','C','D','E','F','G',
                   'H','I','J','K','L','M','N',
                   'O','P','Q','R','S','T',
                   'U','V','W','X','Y','Z',
                   '0','1','2','3','4','5','6','7','8','9',
                   '(', ')', '[', ']') THEN
                  v_PY := v_PY||v_char;
                END IF;
              END IF;
            WHEN 166 THEN     --????
              IF (n_ord_low>160) AND (n_ord_low<185) THEN --A1--B8
                v_PY := v_PY||get_greece_alphabet_py(n_ord_low-160);
              ELSE
                IF (n_ord_low>192) AND (n_ord_low<217) THEN --C1--D8
                  v_PY := v_PY||get_greece_alphabet_py(n_ord_low-192);
                END IF;
              END IF;
            ELSE
            BEGIN
              n_temp := n_ord_high-128;
              n_ord_low := n_ord_low-63;
              n_temp1 := trunc(n_temp/10,0);
              n_temp1 := n_temp-n_temp1*10;
              IF n_temp1=0 THEN
                n_temp1 := 10;
              END IF;
              --DBMS_OUTPUT.PUT_LINE('n_temp = '||to_char(n_temp,'9999999'));
              --DBMS_OUTPUT.PUT_LINE('n_temp1 = '||to_char(n_temp1,'9999999'));
              CASE
              WHEN n_temp<11 THEN
                n_temp1 := get_py_index_01(n_temp1,n_ord_low);
              WHEN n_temp<21 THEN
                n_temp1 := get_py_index_02(n_temp1,n_ord_low);
              WHEN n_temp<31 THEN
                n_temp1 := get_py_index_03(n_temp1,n_ord_low);
              WHEN n_temp<41 THEN
                n_temp1 := get_py_index_04(n_temp1,n_ord_low);
              WHEN n_temp<51 THEN
                n_temp1 := get_py_index_05(n_temp1,n_ord_low);
              WHEN n_temp<61 THEN
                n_temp1 := get_py_index_06(n_temp1,n_ord_low);
              WHEN n_temp<71 THEN
                n_temp1 := get_py_index_07(n_temp1,n_ord_low);
              WHEN n_temp<81 THEN
                n_temp1 := get_py_index_08(n_temp1,n_ord_low);
              WHEN n_temp<91 THEN
                n_temp1 := get_py_index_09(n_temp1,n_ord_low);
              WHEN n_temp<101 THEN
                n_temp1 := get_py_index_10(n_temp1,n_ord_low);
              WHEN n_temp<111 THEN
                n_temp1 := get_py_index_11(n_temp1,n_ord_low);
              WHEN n_temp<121 THEN
                n_temp1 := get_py_index_12(n_temp1,n_ord_low);
              WHEN n_temp<121 THEN
                n_temp1 := get_py_index_13(n_temp1,n_ord_low);
              ELSE
                n_temp1 := 0;
              END CASE;
              v_PY := v_PY||substr(GetHzPY_by_index(n_temp1),1,1);
            END;
          END CASE;
        END IF;
    END IF;
  END LOOP;
  RETURN substr(v_PY,s,e);
  --DBMS_OUTPUT.PUT_LINE(v_PY);
END GetHzPYCAPsubstr;

FUNCTION F_TRANS_PINYIN_CAPITAL(P_NAME IN VARCHAR2) RETURN VARCHAR2 AS
V_COMPARE VARCHAR2(100);
V_RETURN VARCHAR2(4000);
FUNCTION F_NLSSORT(P_WORD IN VARCHAR2) RETURN VARCHAR2 AS
BEGIN
RETURN NLSSORT(P_WORD, 'NLS_SORT=SCHINESE_PINYIN_M');
END;
BEGIN
V_COMPARE := F_NLSSORT(SUBSTR(P_NAME, 1, 1));
IF V_COMPARE >= F_NLSSORT(' 吖 ') AND V_COMPARE <= F_NLSSORT('驁 ') THEN
V_RETURN := V_RETURN || 'A';
ELSIF V_COMPARE >= F_NLSSORT('八 ') AND V_COMPARE <= F_NLSSORT('簿 ') THEN
V_RETURN := V_RETURN || 'B';
ELSIF V_COMPARE >= F_NLSSORT('嚓 ') AND V_COMPARE <= F_NLSSORT('錯 ') THEN
V_RETURN := V_RETURN || 'C';
ELSIF V_COMPARE >= F_NLSSORT('咑 ') AND V_COMPARE <= F_NLSSORT('鵽 ') THEN
V_RETURN := V_RETURN || 'D';
ELSIF V_COMPARE >= F_NLSSORT('妸 ') AND V_COMPARE <= F_NLSSORT('樲 ') THEN
V_RETURN := V_RETURN || 'E';
ELSIF V_COMPARE >= F_NLSSORT('發 ') AND V_COMPARE <= F_NLSSORT('猤 ') THEN
V_RETURN := V_RETURN || 'F';
ELSIF V_COMPARE >= F_NLSSORT('旮 ') AND V_COMPARE <= F_NLSSORT('腂 ') THEN
V_RETURN := V_RETURN || 'G';
ELSIF V_COMPARE >= F_NLSSORT('妎 ') AND V_COMPARE <= F_NLSSORT('夻 ') THEN
V_RETURN := V_RETURN || 'H';
ELSIF V_COMPARE >= F_NLSSORT('丌 ') AND V_COMPARE <= F_NLSSORT('攈 ') THEN
V_RETURN := V_RETURN || 'J';
ELSIF V_COMPARE >= F_NLSSORT('咔 ') AND V_COMPARE <= F_NLSSORT('穒 ') THEN
V_RETURN := V_RETURN || 'K';
ELSIF V_COMPARE >= F_NLSSORT('垃 ') AND V_COMPARE <= F_NLSSORT('擽 ') THEN
V_RETURN := V_RETURN || 'L';
ELSIF V_COMPARE >= F_NLSSORT('嘸 ') AND V_COMPARE <= F_NLSSORT('椧 ') THEN
V_RETURN := V_RETURN || 'M';
ELSIF V_COMPARE >= F_NLSSORT('拏 ') AND V_COMPARE <= F_NLSSORT('瘧 ') THEN
V_RETURN := V_RETURN || 'N';
ELSIF V_COMPARE >= F_NLSSORT('筽 ') AND V_COMPARE <= F_NLSSORT('漚 ') THEN
V_RETURN := V_RETURN || 'O';
ELSIF V_COMPARE >= F_NLSSORT('妑 ') AND V_COMPARE <= F_NLSSORT('曝 ') THEN
V_RETURN := V_RETURN || 'P';
ELSIF V_COMPARE >= F_NLSSORT('七 ') AND V_COMPARE <= F_NLSSORT('裠 ') THEN
V_RETURN := V_RETURN || 'Q';
ELSIF V_COMPARE >= F_NLSSORT('亽 ') AND V_COMPARE <= F_NLSSORT('鶸 ') THEN
V_RETURN := V_RETURN || 'R';
ELSIF V_COMPARE >= F_NLSSORT('仨 ') AND V_COMPARE <= F_NLSSORT('蜶 ') THEN
V_RETURN := V_RETURN || 'S';
ELSIF V_COMPARE >= F_NLSSORT('侤 ') AND V_COMPARE <= F_NLSSORT('籜 ') THEN
V_RETURN := V_RETURN || 'T';
ELSIF V_COMPARE >= F_NLSSORT('屲 ') AND V_COMPARE <= F_NLSSORT('鶩 ') THEN
V_RETURN := V_RETURN || 'W';
ELSIF V_COMPARE >= F_NLSSORT('夕 ') AND V_COMPARE <= F_NLSSORT('鑂 ') THEN
V_RETURN := V_RETURN || 'X';
ELSIF V_COMPARE >= F_NLSSORT('丫 ') AND V_COMPARE <= F_NLSSORT('韻 ') THEN
V_RETURN := V_RETURN || 'Y';
ELSIF V_COMPARE >= F_NLSSORT('帀 ') AND V_COMPARE <= F_NLSSORT('咗 ') THEN
V_RETURN := V_RETURN || 'Z';
END IF;
RETURN V_RETURN;
END F_TRANS_PINYIN_CAPITAL;

--begin
  -- Initialization
  --<Statement>;
end;
/
create or replace PACKAGE PKG_FUNC AS
--定義1970年1月1日8點時間常量
START_DATE CONSTANT DATE:=TO_DATE('1970-01-01 08:00:00','YYYY-MM-DD HH24:MI:SS');

--表類型
TYPE TYPE_STRLIST IS TABLE OF VARCHAR2(4000);

--功能:將字符串按照指定分割字符分割成記錄集
FUNCTION SPLITSTR(pSTR IN VARCHAR2,pSEP IN VARCHAR2:=',') RETURN TYPE_STRLIST PIPELINED;

--功能:時間日期轉換成距離1970-01-01的秒數
FUNCTION DATE_TO_SECOND(pDATE IN DATE) RETURN INT; 

--功能:距離1970-01-01的秒數轉換成時間日期
FUNCTION SECOND_TO_DATE(pSECOND IN INT) RETURN DATE;

--功能:傳遞字符串參數,返回格式化替換後的時間日期參數
FUNCTION DATE_FORMAT(pDATE IN VARCHAR,pTYPE IN NUMBER) RETURN DATE;

--功能:獲取兩個日期的差值(輸入爲字符串類型)
FUNCTION DATEDIFF( 
  Datepart  In Varchar2,
  StartDate In Varchar2,
  EndDate   In Varchar2
) 
Return VARCHAR2;  

--功能:獲取兩個日期的差值(輸入爲日期類型)
FUNCTION DATEDIFF( 
  Datepart  In Varchar2,
  StartDate In DATE,
  EndDate   In DATE
) 
Return VARCHAR2;  
END;
/
create or replace PACKAGE BODY PKG_FUNC AS 
FUNCTION SPLITSTR
--功能:將字符串按照指定分割字符分割成記錄集
--參數:pSTR-字符串,pSEP-指定分割字符,默認爲','
--調用:SELECT * FROM TABLE(PKG_FUNC.SPLITSTR('1,2,3,4,5,6,7,8,9,10',','))
--日期:2013-03-03
(
  pSTR IN VARCHAR2,
  pSEP IN VARCHAR2:=','
)
RETURN TYPE_STRLIST PIPELINED
IS
L_IDX PLS_INTEGER;
V_LIST VARCHAR2(4000):=pSTR;
BEGIN
  LOOP
    L_IDX := INSTR(V_LIST,pSEP);
    IF L_IDX > 0 THEN
      PIPE ROW(SUBSTR(V_LIST,1,L_IDX-1));
      V_LIST := SUBSTR(V_LIST,L_IDX+LENGTH(pSEP));
    ELSE
      PIPE ROW(V_LIST);
      EXIT;
    END IF;
  END LOOP;
  RETURN;
END;

FUNCTION DATE_TO_SECOND
--功能:時間日期轉換成距離1970-01-01的秒數
--參數:pDATE-日期格式參數
--調用:SELECT PKG_FUNC.DATE_TO_SECOND(SYSDATE) FROM DUAL;
--日期:2013-03-03
(
  pDATE IN DATE
) 
RETURN INT
IS
pSECOND INT;
BEGIN
  SELECT TRUNC((pDATE-START_DATE)*86400) INTO pSECOND FROM DUAL;
  RETURN pSECOND;
END;  

FUNCTION SECOND_TO_DATE
--功能:距離1970-01-01的秒數轉換成時間日期
--參數:pDATE-傳遞日期格式參數
--調用:SELECT PKG_FUNC.SECOND_TO_DATE(1398733775) FROM DUAL;
--日期:2013-02-17
(
  pSECOND IN INT
) 
RETURN DATE
IS
pDATE DATE;
BEGIN
  SELECT START_DATE+pSECOND/86400 INTO pDATE FROM DUAL;
  RETURN pDATE;
END;  

FUNCTION DATE_FORMAT
--功能:傳遞字符串參數,返回格式化替換後的時間日期參數
--參數:pDATE-字符串參數,pTYPE-不一樣類型進行相應處理
--調用:SELECT PKG_FUNC.DATE_FORMAT('',2) FROM DUAL
--日期:2013-02-17
(
  pDATE IN VARCHAR,
  pTYPE IN NUMBER 	--處理類別 0:時間可爲空 1:最小時間,2:最大時間,其它:系統當前時間
)
--------------------------------------------------------------------------------------
--0-返回的日期時間可爲空
--1-返回的日期時間不爲空,若傳入參數爲空,則轉換爲最小時間 
--2-返回的日期時間不爲空,若傳入參數爲空,則轉換爲最大時間
--其它-返回的日期時間不爲空,若傳入參數爲空,則轉換爲系統當前時間
RETURN DATE 
IS
RTN DATE;
BEGIN
	SELECT DECODE(pTYPE,0,TO_DATE(TRIM(pDATE),'YYYY-MM-DD HH24:MI:SS'),
		1,TO_DATE(NVL(TRIM(pDATE),'0001-01-01'),'YYYY-MM-DD HH24:MI:SS'),
		2,TO_DATE(NVL(TRIM(pDATE),'9999-12-31'),'YYYY-MM-DD HH24:MI:SS'),
		NVL(TO_DATE(TRIM(pDATE),'YYYY-MM-DD HH24:MI:SS'),SYSDATE)) 
		INTO RTN FROM DUAL; 
  RETURN RTN;
END;

FUNCTION DATEDIFF
--功能:獲取兩個日期的差值(輸入爲字符串類型)
--參數:Datepart-返回間隔時間類型,StartDate-開始日期,EndDate-結束日期
--調用:SELECT PKG_FUNC.DATEDIFF('','2012-01-01','2010-01-01') FROM DUAL
--日期:2017-03-04
( 
  Datepart  In Varchar2,
  StartDate In Varchar2,
  EndDate   In Varchar2
)  
Return VARCHAR2  
IS 
v_DAY    VARCHAR2(200);
v_HOUR   VARCHAR2(200);
v_MINUTE VARCHAR2(200);
v_SECOND VARCHAR2(200); 
ReallyDo VARCHAR2(200);
Begin 
  SELECT EXTRACT(
    DAY FROM (TO_DATE(StartDate, 'YYYY-MM-DD HH24:MI:SS')-
              TO_DATE(EndDate, 'YYYY-MM-DD HH24:MI:SS'))  
    DAY(9) TO SECOND ) INTO v_DAY FROM DUAL;
  SELECT EXTRACT(
    HOUR FROM (TO_DATE(StartDate, 'YYYY-MM-DD HH24:MI:SS')-
              TO_DATE(EndDate, 'YYYY-MM-DD HH24:MI:SS'))  
    DAY(9) TO SECOND ) INTO v_HOUR FROM DUAL;
  SELECT EXTRACT(
    MINUTE FROM (TO_DATE(StartDate, 'YYYY-MM-DD HH24:MI:SS')-
              TO_DATE(EndDate, 'YYYY-MM-DD HH24:MI:SS'))  
    DAY(9) TO SECOND ) INTO v_MINUTE FROM DUAL;
  SELECT EXTRACT(
    SECOND FROM (TO_DATE(StartDate, 'YYYY-MM-DD HH24:MI:SS')-
              TO_DATE(EndDate, 'YYYY-MM-DD HH24:MI:SS'))  
    DAY(9) TO SECOND ) INTO v_SECOND FROM DUAL;  
  ReallyDo:=v_DAY||'天'||v_HOUR||'小時'||v_MINUTE||'分'||v_SECOND||'秒'; 
  SELECT DECODE(Datepart,'DAY',v_DAY,'D',v_DAY,'HOUR',v_HOUR,'H',v_HOUR,'MINUTE',v_MINUTE,'M',v_MINUTE,'SECOND',v_SECOND,'S',v_SECOND,ReallyDo) INTO ReallyDo FROM DUAL;
  Return ReallyDo;
End;

FUNCTION DATEDIFF
--功能:獲取兩個日期的差值(輸入爲日期類型)
--參數:Datepart-返回間隔時間類型,StartDate-開始日期,EndDate-結束日期
--調用:SELECT PKG_FUNC.DATEDIFF('','2012-01-01','2010-01-01') FROM DUAL
--日期:2017-03-04
( 
  Datepart  In Varchar2,
  StartDate In DATE,
  EndDate   In DATE
)  
Return VARCHAR2  
IS 
v_DAY    VARCHAR2(200);
v_HOUR   VARCHAR2(200);
v_MINUTE VARCHAR2(200);
v_SECOND VARCHAR2(200); 
ReallyDo VARCHAR2(200);
Begin 
  SELECT EXTRACT(
    DAY FROM (StartDate-EndDate)  
    DAY(9) TO SECOND ) INTO v_DAY FROM DUAL;
  SELECT EXTRACT(
    HOUR FROM (StartDate-EndDate)  
    DAY(9) TO SECOND ) INTO v_HOUR FROM DUAL;
  SELECT EXTRACT(
    MINUTE FROM (StartDate-EndDate)  
    DAY(9) TO SECOND ) INTO v_MINUTE FROM DUAL;
  SELECT EXTRACT(
    SECOND FROM (StartDate-EndDate)  
    DAY(9) TO SECOND ) INTO v_SECOND FROM DUAL;  
  ReallyDo:=v_DAY||'天'||v_HOUR||'小時'||v_MINUTE||'分'||v_SECOND||'秒'; 
  SELECT DECODE(Datepart,'DAY',v_DAY,'D',v_DAY,'HOUR',v_HOUR,'H',v_HOUR,'MINUTE',v_MINUTE,'M',v_MINUTE,'SECOND',v_SECOND,'S',v_SECOND,ReallyDo) INTO ReallyDo FROM DUAL;
  Return ReallyDo;
End;
END;
/
CREATE OR REPLACE PACKAGE PKG_ANALYZE
AS 
----定義過濾的表差別數量的對象
TYPE CHETABLECOUNT IS RECORD
(
  TABLE_NAME  VARCHAR2(40),
  DELETECOUNT NUMBER(10),
  INSERTCOUNT NUMBER(10),
  UPDATECOUNT NUMBER(10)
);

--定義過濾的表差別數量集合類型
TYPE CHETABLECOUNTLIST IS TABLE OF CHETABLECOUNT;

--獲取差別的表記錄數量集合
FUNCTION GET_TABLE_COUNT(
	pLINKNAME 	    IN VARCHAR, 				--連接名
	pCHECKTABLELIST IN CHECKTABLELIST 	--源過濾的表類型 
)
RETURN CHETABLECOUNTLIST PIPELINED;

--獲取差別的表記錄數量集合
PROCEDURE CHECK_MERGE_COUNT(
	pLINKNAME 	    IN VARCHAR, 				--連接名
	pCHECKTABLELIST IN CHECKTABLELIST,	--源過濾的表類型 
  pCURSOR         OUT SYS_REFCURSOR
);

--功能:獲取當前的redo size日誌大小
FUNCTION NOW_REDO_SIZE RETURN NUMBER;

--功能:開啓日誌分析,計算初始redo size大小
PROCEDURE START_REDO;

--功能:計算生成的日誌大小
FUNCTION GET_REDO_SIZE RETURN NUMBER;

--功能:查詢當前數據庫誰在運行什麼SQL語句
PROCEDURE SESSION_RUN_SQL(pCURSOR OUT SYS_REFCURSOR);

--功能:查詢使用CPU多的用戶SESSION
PROCEDURE SESSION_CPU_COST(pCURSOR OUT SYS_REFCURSOR);

--功能:查詢影響性能的SQL語句
PROCEDURE SQL_IO_COST(pCURSOR OUT SYS_REFCURSOR);

--功能:分析存儲過程、函數(或者包中的存儲過程、函數)參數信息
PROCEDURE GET_ARGUMENTS(
  DBUSER 				IN VARCHAR2:=USER,
  pPACKAGENAME 	IN VARCHAR2:=NULL,
  pOBJNAME 			IN VARCHAR2:=NULL,
  pCURSOR 			OUT SYS_REFCURSOR
);

--功能:統計分析用戶下的單表/索引或者全庫表/索引,爲NULL則分析全庫表/索引,多個對象以','分隔
PROCEDURE ANALYZE_TABLEANDINDEX(DBUSER IN VARCHAR2:=USER,pOBJNAME IN VARCHAR2:=NULL);

--功能:分析數據庫中單表或全部表產生行遷移和行鏈接的記錄,爲NULL則分析全庫表,多個表以','分隔
PROCEDURE ANALYZE_CHAINED_ROWS(DBUSER IN VARCHAR2:=USER,pOBJNAME IN VARCHAR2:=NULL);

--功能:查詢錶行數、索引塊大小、數據塊大小佔用狀況,爲NULL則查詢全庫表,多個表以','分隔,數據塊包含表、分區表、LOB段空間,索引塊包含普通索引、分區索引、LOB段索引
PROCEDURE TABLE_ROWSANDSPACE(
	DBUSER 		IN VARCHAR2:=USER,
	pOBJNAME 	IN VARCHAR2:=NULL,
	pCURSOR 	OUT SYS_REFCURSOR
);

PROCEDURE VIEW_COUNT(
  DBUSER  IN VARCHAR2:=USER,
  pTBNAME IN VARCHAR2:=NULL,
  pCURSOR OUT SYS_REFCURSOR
);

--功能:檢測設計後的錶行總長度是否超過當前所在的表空間最小單元數據塊大小(若超過,可能產生行鏈接),爲NULL則查詢全庫表,多個表以','分隔
PROCEDURE ROW_CHARLENGTH(
	DBUSER 		IN VARCHAR2:=USER,
	pOBJNAME 	IN VARCHAR2:=NULL,
	pCURSOR 	OUT SYS_REFCURSOR
);

--功能:檢測哪些表中的列名稱採用系統關鍵字(可能引發沒必要要的錯誤,如Ora-01747:user.table.column,tabel.coulmn或列說明無效)
PROCEDURE CHECK_COLNAMEISKEYWORD(DBUSER IN VARCHAR2:=USER,pCURSOR OUT SYS_REFCURSOR);

--功能:檢測數據庫中外鍵上未創建索引的狀況
PROCEDURE CHECK_FOREIGNINDEX(DBUSER IN VARCHAR2:=USER,pCURSOR OUT SYS_REFCURSOR);

--功能:檢測數據庫中外鍵依賴列的類型、長度、小數位與主鍵列不一致的狀況,這可能在其餘數據庫(如SQL SERVER)中因爲嚴格限制沒法創建外鍵關聯
PROCEDURE CHECK_KEYRELATIONTYPE(DBUSER IN VARCHAR2:=USER,pCURSOR OUT SYS_REFCURSOR);

--功能:檢測數據庫中未創建主鍵或者惟一約束的狀況
PROCEDURE CHECK_NOPRIMARY(DBUSER IN VARCHAR:=USER,pCURSOR OUT SYS_REFCURSOR);

--功能:返回查詢目標庫與連接源庫表的差別或相同部分的SQL語句
PROCEDURE GET_COMPARETEXT(
	pTAG        IN NUMBER,          --查詢模式:1-求同(交集),2-求異(補集)
	pLINKNAME 	IN VARCHAR, 				--連接名
	pTABLENAME 	IN VARCHAR2:=NULL,	--源表,能夠爲一張或多張表,多個表以','分隔,爲空則選擇全部表
	pMODE 			IN NUMBER:=1, 			--匹配模式
	pSELTEXT    OUT VARCHAR2
);

--功能:查詢目標庫與源庫表的差別部分(若是目標表中存在主鍵相同記錄,則同步類型爲'UPDATE',不存在則同步類型爲'INSERT',目標表中存在而源表中不存在則同步類型爲'DELETE')
PROCEDURE CHECK_MERGE_MINUS(
	pSOURCETB 	IN  VARCHAR, 				--源表名,若是爲遠程連接表,相似爲LINKNAME@TABLENAME的格式,如:DATABASE_LINK1@USR_INFOTAB
	pTARGETTB 	IN  VARCHAR2,	      --目標表名
  pFILTER     IN  VARCHAR2:=NULL, --條件過濾
  pCURSOR     OUT SYS_REFCURSOR
);

--功能:查詢目標庫與連接源庫表的差別部分(求補集)
PROCEDURE CHECK_MINUS(
	pLINKNAME 	IN VARCHAR, 				--連接名
	pTABLENAME 	IN VARCHAR2:=NULL,	--源表,能夠爲一張或多張表,多個表以','分隔,爲空則選擇全部表
	pMODE 			IN NUMBER:=1, 			--匹配模式
	pCURSOR 		OUT SYS_REFCURSOR  	--返回連接庫中有而目標庫中沒有的部分
);

--功能:查詢目標庫與連接源庫表的相同部分(求交集)
PROCEDURE CHECK_INTERSECT(
	pLINKNAME 	IN VARCHAR, 				--連接名
	pTABLENAME 	IN VARCHAR2:=NULL,	--源表,能夠爲一張或多張表,多個表以','分隔,爲空則選擇全部表
	pMODE 			IN NUMBER:=1, 			--匹配模式
	pCURSOR 		OUT SYS_REFCURSOR  	--返回連接庫、目標庫中共有的部分
);

--功能:查詢對比目標庫與連接源庫表數據對比具備相同列數據的部分(如查詢重複列數據)
PROCEDURE CHECK_DISTINCT(
	pLINKNAME 	IN VARCHAR, 				--連接名
	pTABLENAME 	IN VARCHAR2,				--表名
	pCOLNAME 		IN VARCHAR2,        --匹配列名,多個列以逗號分隔
	pCURSOR 		OUT SYS_REFCURSOR  	--返回連接庫、目標庫中共有的部分
);
END;
/
create or replace PACKAGE BODY PKG_ANALYZE
AS
LAST_REDOSIZE NUMBER:=NULL;

FUNCTION NOW_REDO_SIZE
--功能:獲取當前的redo size日誌大小
--參數:
--調用:
--日期:2014-07-10
RETURN NUMBER
IS
  REDOSIZE NUMBER;
BEGIN
  SELECT "VALUE" INTO REDOSIZE FROM V$STATNAME A,V$MYSTAT B WHERE A.STATISTIC#=B.STATISTIC# AND A.NAME='redo size';
  RETURN REDOSIZE;
END;

PROCEDURE START_REDO
--功能:開啓日誌分析,計算初始redo size大小
--參數:
--調用:
--日期:2014-07-10
AS
BEGIN
  SELECT NOW_REDO_SIZE INTO LAST_REDOSIZE FROM DUAL;
END;

FUNCTION GET_REDO_SIZE
--功能:計算生成的日誌大小
--參數:
--調用:
--日期:2014-07-10
RETURN NUMBER
IS
  END_REDOSIZE NUMBER;
BEGIN
  SELECT NOW_REDO_SIZE INTO END_REDOSIZE FROM DUAL;
  RETURN END_REDOSIZE-LAST_REDOSIZE;
END;

PROCEDURE SESSION_RUN_SQL
--功能:查詢當前數據庫誰在運行什麼SQL語句
--參數:pCURSOR-返回數據集
--調用:
/*
DECLARE pCURSOR SYS_REFCURSOR;
BEGIN
	PKG_ANALYZE.SESSION_RUN_SQL(pCURSOR);
END;
*/
--日期:2013-03-11
(
  pCURSOR OUT SYS_REFCURSOR
)
AS
BEGIN
  OPEN pCURSOR FOR SELECT DISTINCT SID,SERIAL#,USERNAME,machine,TERMINAL,module,PROGRAM,PROCESS,STATUS,
		EVENT,SERVICE_NAME,logon_time,SQL_EXEC_START,PREV_EXEC_START,SQL_TEXT FROM(
			SELECT SID,SERIAL#,USERNAME,a.machine,TERMINAL,a.module,PROGRAM,PROCESS,STATUS,EVENT,SERVICE_NAME,a.logon_time,
				SQL_EXEC_START,PREV_EXEC_START,LISTAGG(SQL_TEXT,'') WITHIN GROUP(ORDER BY PIECE) OVER(PARTITION BY SID) AS SQL_TEXT
				FROM v$session a, v$sqltext b
				WHERE a.sql_address =b.address
				ORDER BY address, piece
    );
END;

PROCEDURE SESSION_CPU_COST
--功能:查詢使用CPU多的用戶SESSION
--參數:pCURSOR-返回數據集
--調用:
/*
DECLARE pCURSOR SYS_REFCURSOR;
BEGIN
	PKG_ANALYZE.SESSION_CPU_COST(pCURSOR);
END;
*/
--日期:2013-03-11
(
  pCURSOR OUT SYS_REFCURSOR
)
AS
BEGIN
  OPEN pCURSOR FOR SELECT a.sid,spid,status,substr(a.program,1,40) prog,a.terminal,osuser,value/60/100 VALUE
    FROM v$session a,v$process b,v$sesstat c
    WHERE c.statistic#=11 AND c.sid=a.sid AND a.paddr=b.addr
    ORDER BY VALUE DESC;
END;

PROCEDURE SQL_IO_COST
--功能:查詢影響性能的SQL語句
--參數:pCURSOR-返回數據集
--調用:
/*
DECLARE pCURSOR SYS_REFCURSOR;
BEGIN
	PKG_ANALYZE.SQL_IO_COST(pCURSOR);
END;
*/
--日期:2013-03-11
(
  pCURSOR OUT SYS_REFCURSOR
)
AS
BEGIN
  OPEN pCURSOR FOR SELECT SQL_ID,MODULE,SORTS,LOADS,FIRST_LOAD_TIME,LAST_LOAD_TIME,DISK_READS,CPU_TIME,BUFFER_GETS,executions,
		CASE executions WHEN 0 THEN 0 ELSE buffer_gets/executions END AS "GETS/EXEC",hash_value,address,SQL_TEXT,SQL_FULLTEXT
    FROM V$SQLAREA ORDER BY BUFFER_GETS DESC;
END;

PROCEDURE GET_ARGUMENTS
--功能:分析存儲過程、函數(或者包中的存儲過程、函數)參數信息
--參數:DBUSER-數據庫用戶,pOBJNAME-表/索引名稱,爲NULL則分析全庫表/索引,多個對象以','分隔
--調用:
/*
DECLARE pCURSOR SYS_REFCURSOR;
BEGIN
	PKG_ANALYZE.GET_ARGUMENTS('DKGLL','','USR_INFOTAB',pCURSOR);
END;
*/
--日期:2013-03-5
(
  DBUSER 				IN VARCHAR2:=USER,
  pPACKAGENAME 	IN VARCHAR2:=NULL,
  pOBJNAME 			IN VARCHAR2:=NULL,
  pCURSOR 			OUT SYS_REFCURSOR
)
AS
BEGIN
	OPEN pCURSOR FOR SELECT OWNER,PACKAGE_NAME,
		CASE MIN(POSITION) OVER(PARTITION BY OBJECT_NAME) WHEN 0 THEN	'FUNCTION' ELSE 'PROCEDURE' END OBJECT_TYPE,
		OBJECT_NAME,ARGUMENT_NAME,OVERLOAD,IN_OUT,DATA_TYPE FROM DBA_ARGUMENTS
		WHERE OWNER=NVL(DBUSER,OWNER) AND	PACKAGE_NAME=NVL(pPACKAGENAME,PACKAGE_NAME) AND OBJECT_NAME=NVL(pOBJNAME,OBJECT_NAME)
		ORDER BY OWNER,SUBPROGRAM_ID,POSITION;
END;

PROCEDURE ANALYZE_TABLEANDINDEX
--功能:統計分析用戶下的單表/索引或者全庫表/索引
--參數:DBUSER-數據庫用戶,pOBJNAME-表/索引名稱,爲NULL則分析全庫表/索引,多個對象以','分隔
--調用:EXECUTE PKG_ANALYZE.ANALYZE_TABLEANDINDEX('DKGLL','USR_INFOTAB');
--日期:2013-03-5
(
  DBUSER 		IN VARCHAR2:=USER,
  pOBJNAME 	IN VARCHAR2:=NULL
)
AS
	pUSER VARCHAR2(200):=COALESCE(UPPER(DBUSER),USER);
BEGIN
  --分析全部表
	FOR CUR_ITEM IN
	(
		SELECT TABLE_NAME FROM SYS.DBA_TABLES
			WHERE OWNER=pUSER AND(INSTR(','||pOBJNAME||',',','||TABLE_NAME||',',1)>0 OR pOBJNAME IS NULL)
	)
	LOOP
  BEGIN
    EXECUTE IMMEDIATE 'ANALYZE TABLE "'||pUSER||'"."'||CUR_ITEM.TABLE_NAME||'" COMPUTE STATISTICS';
    EXCEPTION
		WHEN OTHERS THEN
			SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'分析表異常:' ||SQLERRM);
  END;
  END LOOP;
  --分析全部索引
  FOR CUR_ITEM IN
	(
		SELECT INDEX_NAME FROM SYS.DBA_INDEXES
			WHERE OWNER=pUSER AND(INSTR(','||pOBJNAME||',',','||TABLE_NAME||',',1)>0 OR pOBJNAME IS NULL)
	)
	LOOP
  BEGIN
    EXECUTE IMMEDIATE 'ANALYZE INDEX "'||pUSER||'"."'||CUR_ITEM.INDEX_NAME||'" ESTIMATE STATISTICS';
    EXCEPTION
		WHEN OTHERS THEN
			SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'分析索引異常:' ||SQLERRM);
  END;
  END LOOP;
  COMMIT;
END;

PROCEDURE ANALYZE_CHAINED_ROWS
--功能:分析數據庫中單表或全部表產生行遷移和行鏈接的記錄,用戶需具有在存儲過程當中動態建表的權限
--參數:DBUSER-數據庫用戶,pOBJNAME-表名稱,爲NULL則分析全庫表,多個表以','分隔
--調用:EXECUTE PKG_ANALYZE.ANALYZE_CHAINED_ROWS('DKGLL','USR_INFOTAB');
--日期:2013-03-5
(
  DBUSER 		IN VARCHAR2:=USER,
  pOBJNAME 	IN VARCHAR2:=NULL
)
AS
	pUSER 	VARCHAR2(200):=COALESCE(UPPER(DBUSER),USER);
	pCOUNT 	NUMBER;
	pSQL 		VARCHAR2(300);
BEGIN
  SELECT COUNT(1) INTO pCOUNT FROM SYS.DBA_TABLES WHERE OWNER=pUSER AND TABLE_NAME='CHAINED_ROWS';
  IF pCOUNT=0 THEN                                         --行遷移分析表不存在則建立行遷移分析表
		pSQL:='CREATE TABLE "'||pUSER||'"."CHAINED_ROWS" ('||CHR(10)||
            'owner_name         VARCHAR2(30),'||CHR(10)||
            'table_name         VARCHAR2(30),'||CHR(10)||
            'cluster_name       VARCHAR2(30),'||CHR(10)||
            'partition_name     VARCHAR2(30),'||CHR(10)||
            'subpartition_name  VARCHAR2(30),'||CHR(10)||
            'head_rowid         ROWID,'||CHR(10)||
            'analyze_timestamp  DATE'||CHR(10)||
          ')';
	ELSE
		pSQL:='DELETE FROM "'||pUSER||'"."CHAINED_ROWS"';
  END IF;
	EXECUTE IMMEDIATE pSQL; 	--刪除上次分析後的數據
  --分析全部表
  FOR CUR_ITEM IN
	(
		SELECT TABLE_NAME FROM SYS.DBA_TABLES
			WHERE OWNER=pUSER AND (INSTR(','||pOBJNAME||',',','||TABLE_NAME||',',1)>0 OR pOBJNAME IS NULL)
	)
	LOOP
    EXECUTE IMMEDIATE 'ANALYZE TABLE "'||pUSER||'"."'||CUR_ITEM.TABLE_NAME||'" LIST CHAINED ROWS INTO CHAINED_ROWS';
  END LOOP;
  COMMIT;
  EXCEPTION
    WHEN OTHERS THEN
      SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'執行錯誤:' ||SQLERRM);
END;

PROCEDURE TABLE_ROWSANDSPACE
--功能:查詢錶行數、索引塊大小、數據塊大小佔用狀況,數據塊包含表、分區表、LOB段空間,索引塊包含普通索引、分區索引、LOB段索引
--參數:DBUSER-數據庫用戶,pOBJNAME-表名稱,爲NULL則查詢全庫表,多個表以','分隔,pCURSOR-返回數據集
--調用:
/*
DECLARE pCURSOR SYS_REFCURSOR;
BEGIN
	PKG_ANALYZE.TABLE_ROWSANDSPACE('DKGLL','USR_INFOTAB',pCURSOR);
END;
*/
--日期:2013-03-8
(
  DBUSER 		IN VARCHAR2:=USER,
  pOBJNAME 	IN VARCHAR2:=NULL,
  pCURSOR 	OUT SYS_REFCURSOR
)
AS
	pUSER VARCHAR2(200):=COALESCE(UPPER(DBUSER),USER);
BEGIN
 OPEN pCURSOR FOR	SELECT DISTINCT TA.TABLE_NAME AS "表名",TA.NUM_ROWS AS "行數",
		CASE
			WHEN TB.INDEXUSE IS NULL THEN TA.TABLEUSE/1048576
			ELSE(TB.INDEXUSE+TA.TABLEUSE)/1048576
		END AS "總佔用(MB)", TA.TABLEUSE/1048576 AS "數據塊佔用(MB)",
		CASE
			WHEN TB.INDEXUSE IS NULL THEN 0
			ELSE TB.INDEXUSE/1048576
		END AS "索引塊佔用(MB)"
	FROM
		(
			SELECT  OWNER,TABLE_NAME,SEGMENT_TYPE,NUM_ROWS,SUM(BYTES) OVER(PARTITION BY OWNER,TABLE_NAME,SEGMENT_TYPE) AS TABLEUSE
				FROM
					(
						SELECT  A.OWNER,A.TABLE_NAME,'TABLE' AS SEGMENT_TYPE,A.NUM_ROWS,
								CASE
									WHEN B.BYTES IS NULL THEN 0
									ELSE B.BYTES
								END AS BYTES
							FROM SYS.DBA_TABLES A
							LEFT JOIN SYS.DBA_SEGMENTS B ON(A.OWNER=B.OWNER AND A.TABLE_NAME=B.SEGMENT_NAME)
							WHERE A.OWNER=pUSER
					)
		)
		TA
	LEFT JOIN
		(SELECT  OWNER,TABLE_NAME,SEGMENT_TYPE,SUM(BYTES) OVER(PARTITION BY OWNER,TABLE_NAME,SEGMENT_TYPE) AS INDEXUSE FROM
					(SELECT  C.OWNER,C.TABLE_NAME,'INDEX' AS SEGMENT_TYPE,CASE WHEN D.BYTES IS NULL THEN 0 ELSE D.BYTES END AS BYTES
						FROM SYS.DBA_INDEXES C
						LEFT JOIN SYS.DBA_SEGMENTS D ON(C.OWNER=D.OWNER AND C.INDEX_NAME=D.SEGMENT_NAME)
						WHERE C.OWNER=pUSER
					)
		)
		TB ON(TA.OWNER=TB.OWNER AND TA.TABLE_NAME=TB.TABLE_NAME)
	WHERE(INSTR(','||pOBJNAME||',',','||TA.TABLE_NAME||',',1)>0 OR pOBJNAME IS NULL)
	ORDER BY "行數" DESC,"總佔用(MB)" DESC,"數據塊佔用(MB)" DESC,"索引塊佔用(MB)" DESC;
END;

PROCEDURE VIEW_COUNT
--功能:檢測系統視圖、如DBA,ALL,USER,動態性能視圖數據行數
--參數:DBUSER-數據庫用戶,pTBNAME-視圖名稱,模糊匹配,爲NULL則分析全部視圖,pCURSOR-返回數據集
--調用:
/*
DECLARE pCURSOR SYS_REFCURSOR;
BEGIN
	PKG_ANALYZE.VIEW_COUNT('DKGLL',NULL,pCURSOR);
END;
*/
--日期:2014-12-9
(
  DBUSER  IN VARCHAR2:=USER,
  pTBNAME IN VARCHAR2:=NULL,
  pCURSOR OUT SYS_REFCURSOR
)
AS
	pUSER   VARCHAR2(200):=COALESCE(UPPER(DBUSER),USER);
  pSQL    VARCHAR2(200);
  pCOUNT  NUMBER;
  PROCEDURE ADD_TB_COUNT
  (
    pOWNER  IN VARCHAR2,
    pTBNAME IN VARCHAR2
  )
  AS
  pSQL1 VARCHAR2(200);
  BEGIN
    pSQL1:='INSERT INTO V$TABLE_COUNT SELECT '''||pOWNER||''','''||pTBNAME||''',COUNT(1) FROM '||pTBNAME;
    EXECUTE IMMEDIATE pSQL1;
    EXCEPTION WHEN OTHERS THEN
      SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'獲取視圖'||pTBNAME||'行數出錯:' ||SQLERRM);
  END;
BEGIN
  SELECT COUNT(1) INTO pCOUNT FROM SYS.DBA_TABLES WHERE OWNER=pUSER AND TABLE_NAME='V$TABLE_COUNT';
  IF pCOUNT=0 THEN
		pSQL:='CREATE TABLE "'||pUSER||'"."V$TABLE_COUNT" ('||CHR(10)||
            'owner_name VARCHAR2(30),'||CHR(10)||
            'table_name VARCHAR2(30),'||CHR(10)||
            'rowcount   number'||CHR(10)||
          ')';
	ELSE
		pSQL:='DELETE FROM "'||pUSER||'"."V$TABLE_COUNT"';
  END IF;
	EXECUTE IMMEDIATE pSQL; 	--刪除上次分析後的數據
  FOR X IN
  (
    SELECT OWNER,SYNONYM_NAME FROM DBA_SYNONYMS WHERE SYNONYM_NAME LIKE pTBNAME||'%' OR pTBNAME IS NULL
  )
  LOOP
    ADD_TB_COUNT(X.OWNER,X.SYNONYM_NAME);
  END LOOP;
  COMMIT;
  EXCEPTION WHEN OTHERS THEN
    SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'查詢動態視圖出錯:' ||SQLERRM);
END;

PROCEDURE ROW_CHARLENGTH
--功能:檢測設計後的錶行總長度是否超過當前所在的表空間最小單元數據塊大小(若超過,可能產生行鏈接)
--參數:DBUSER-數據庫用戶,pOBJNAME-表名稱,爲NULL則分析全庫表,pCURSOR-返回數據集
--調用:
/*
DECLARE pCURSOR SYS_REFCURSOR;
BEGIN
	PKG_ANALYZE.ROW_CHARLENGTH('DKGLL','USR_INFOTAB',pCURSOR);
END;
*/
--日期:2013-03-8
(
  DBUSER 		IN VARCHAR2:=USER,
  pOBJNAME 	IN VARCHAR2:=NULL,
  pCURSOR 	OUT SYS_REFCURSOR
)
AS
	pUSER VARCHAR2(200):=COALESCE(UPPER(DBUSER),USER);
BEGIN
  OPEN pCURSOR FOR SELECT TA.TABLESPACE_NAME AS "表空間名稱",TABLE_NAME AS "表名",TOTALLENGTH AS "行總長度(字節)",
		CASE WHEN TB.BLOCK_SIZE IS NULL THEN 8191 ELSE TB.BLOCK_SIZE END AS "單元數據塊大小(字節)",
    CASE WHEN TOTALLENGTH-(CASE WHEN TB.BLOCK_SIZE IS NULL THEN 8191 ELSE TB.BLOCK_SIZE END)>0 THEN 'YES' ELSE 'NO' END AS "是否超出數據塊大小"
    FROM(
			SELECT TABLESPACE_NAME,TABLE_NAME,SUM(DECODE(CHAR_LENGTH,0,NVL(DATA_PRECISION,MAXCHARLEN),CHAR_LENGTH)) AS TOTALLENGTH FROM(
        SELECT A.TABLESPACE_NAME,A.TABLE_NAME,CASE DATA_TYPE
          WHEN 'NUMBER' THEN 38
          WHEN 'DECIMAL' THEN 38
          WHEN 'NUMERIC' THEN 38
          WHEN 'FLOAT' THEN 126
          WHEN 'INT' THEN 11
          WHEN 'INTEGER' THEN 11
          WHEN 'PLS_INTEGER' THEN 11
          WHEN 'SMALLINT' THEN 5
          WHEN 'BIGINT' THEN 20
          WHEN 'TINYINT' THEN 3
          WHEN 'DATE' THEN 7
          WHEN 'TIMESTAMP(6)' THEN 11
          ELSE 0
          END AS MAXCHARLEN,
          B.DATA_PRECISION,
          B.CHAR_LENGTH FROM SYS.DBA_TABLES A
          JOIN SYS.DBA_TAB_COLUMNS B ON A.OWNER=B.OWNER AND A.OWNER=pUSER AND A.TABLE_NAME=B.TABLE_NAME
      ) GROUP BY TABLESPACE_NAME,TABLE_NAME
    ) TA LEFT JOIN SYS.DBA_TABLESPACES TB ON TA.TABLESPACE_NAME=TB.TABLESPACE_NAME
    WHERE (INSTR(','||pOBJNAME||',',','||TABLE_NAME||',',1)>0 OR pOBJNAME IS NULL)
    ORDER BY TOTALLENGTH DESC,TABLE_NAME;
END;

PROCEDURE CHECK_COLNAMEISKEYWORD
--功能:檢測哪些表中的列名稱採用系統關鍵字(可能引發沒必要要的錯誤)
--參數:DBUSER-數據庫用戶,pCURSOR-返回採用關鍵字的表、列
--調用:
/*
DECLARE pCURSOR SYS_REFCURSOR;
BEGIN
	PKG_ANALYZE.CHECK_COLNAMEISKEYWORD('DKGLL',pCURSOR);
END;
*/
--日期:2013-03-11
(
  DBUSER 	IN VARCHAR2:=USER,
  pCURSOR OUT SYS_REFCURSOR
)
AS
	pUSER VARCHAR2(200):=COALESCE(UPPER(DBUSER),USER);
BEGIN
  OPEN pCURSOR FOR SELECT A.OWNER,A.TABLE_NAME,B.COLUMN_NAME FROM SYS.DBA_TABLES A
    JOIN SYS.DBA_TAB_COLUMNS B ON (A.TABLE_NAME=B.TABLE_NAME AND A.OWNER=B.OWNER)
    JOIN v$reserved_words C ON B.COLUMN_NAME=C.KEYWORD
    WHERE A.OWNER=pUSER ORDER BY A.TABLE_NAME,B.COLUMN_ID;
END;

PROCEDURE CHECK_FOREIGNINDEX
--功能:檢測數據庫中外鍵上未創建索引的狀況
--參數:DBUSER-數據庫用戶,pCURSOR-返回數據庫中外鍵上未創建索引的表、列記錄
--調用:
/*
DECLARE pCURSOR SYS_REFCURSOR;
BEGIN
	PKG_ANALYZE.CHECK_FOREIGNINDEX('DKGLL',pCURSOR);
END;
*/
--日期:2013-03-8
(
  DBUSER 	IN VARCHAR2:=USER,
  pCURSOR OUT SYS_REFCURSOR
)
AS
	pUSER VARCHAR2(200):=COALESCE(UPPER(DBUSER),USER);
BEGIN
  OPEN pCURSOR FOR SELECT TABLE_NAME,COLUMNLIST FROM(
    SELECT A.TABLE_NAME,A.CONSTRAINT_NAME,
			LISTAGG(B.COLUMN_NAME,',') WITHIN GROUP(ORDER BY B.COLUMN_NAME) OVER(PARTITION BY A.TABLE_NAME,A.CONSTRAINT_NAME) AS COLUMNLIST
			FROM SYS.DBA_CONSTRAINTS A
			JOIN SYS.DBA_CONS_COLUMNS B ON (A.OWNER=B.OWNER AND A.TABLE_NAME=B.TABLE_NAME
				AND A.CONSTRAINT_NAME=B.CONSTRAINT_NAME AND A.CONSTRAINT_TYPE='R' AND A.OWNER=pUSER
			)
  ) TA MINUS
  SELECT TABLE_NAME,COLUMNLIST FROM(
		SELECT DISTINCT A.TABLE_NAME,A.INDEX_NAME,
			LISTAGG(B.COLUMN_NAME,',') WITHIN GROUP(ORDER BY B.COLUMN_POSITION) OVER(PARTITION BY A.TABLE_NAME,A.INDEX_NAME) AS COLUMNLIST
			FROM SYS.DBA_INDEXES A
			JOIN SYS.DBA_IND_COLUMNS B ON (A.TABLE_OWNER=B.TABLE_OWNER AND A.TABLE_NAME=B.TABLE_NAME
				AND A.INDEX_NAME=B.INDEX_NAME AND A.INDEX_TYPE='NORMAL' AND A.TABLE_OWNER=pUSER
			)
  );
END;

PROCEDURE CHECK_KEYRELATIONTYPE
--功能:檢測數據庫中外鍵依賴列的類型、長度、小數位與主鍵列不一致的狀況,這可能在其餘數據庫(如SQL SERVER)中因爲嚴格限制沒法創建外鍵關聯
--參數:DBUSER-數據庫用戶,pCURSOR-返回數據庫中未創建主鍵或者惟一約束的表
--調用:
/*
DECLARE pCURSOR SYS_REFCURSOR;
BEGIN
	PKG_ANALYZE.CHECK_KEYRELATIONTYPE('DKGLL',pCURSOR);
END;
*/
--日期:2013-02-10
(
	DBUSER 	IN 	VARCHAR2:=USER,
	pCURSOR OUT SYS_REFCURSOR
)
AS
	pUSER VARCHAR2(200):=COALESCE(UPPER(DBUSER),USER);
BEGIN
	OPEN pCURSOR FOR SELECT * FROM(
		SELECT DISTINCT A.CONSTRAINT_NAME,A.TABLE_NAME,B.COLUMN_NAME,
			CASE B1.DATA_TYPE
				WHEN 'NUMBER' THEN REPLACE(B1.DATA_TYPE||'('||NVL(TO_CHAR(B1.DATA_PRECISION),'*') ||','||NVL(TO_CHAR(B1.DATA_SCALE),'*') ||')','(*,*)','')
				WHEN 'VARCHAR2' THEN B1.DATA_TYPE||'('||B1.CHAR_LENGTH||')'
				ELSE B1.DATA_TYPE END AS DATA_TYPE,
			C.TABLE_NAME AS R_TABLE_NAME,D.COLUMN_NAME AS R_COLUMN_NAME,
			CASE D1.DATA_TYPE
				WHEN 'NUMBER' THEN REPLACE(D1.DATA_TYPE||'('||NVL(TO_CHAR(D1.DATA_PRECISION),'*') ||','||NVL(TO_CHAR(D1.DATA_SCALE),'*') ||')','(*,*)','')
				WHEN 'VARCHAR2' THEN D1.DATA_TYPE||'('||D1.CHAR_LENGTH||')'
				ELSE D1.DATA_TYPE END AS R_DATA_TYPE,
			A.DELETE_RULE
			FROM SYS.DBA_CONSTRAINTS A
			JOIN SYS.DBA_CONS_COLUMNS B ON(A.OWNER=B.OWNER AND A.CONSTRAINT_NAME=B.CONSTRAINT_NAME AND A.TABLE_NAME=B.TABLE_NAME)
			JOIN SYS.DBA_TAB_COLUMNS B1 ON(B1.OWNER=B.OWNER AND B1.TABLE_NAME=B.TABLE_NAME AND B1.COLUMN_NAME=B.COLUMN_NAME)
			JOIN SYS.DBA_CONSTRAINTS C  ON(A.R_OWNER=C.OWNER AND A.R_CONSTRAINT_NAME=C.CONSTRAINT_NAME)
			JOIN SYS.DBA_CONS_COLUMNS D ON(D.OWNER=C.OWNER AND D.CONSTRAINT_NAME=C.CONSTRAINT_NAME AND D.TABLE_NAME=C.TABLE_NAME AND D.POSITION=B.POSITION)
			JOIN SYS.DBA_TAB_COLUMNS D1 ON(D1.OWNER=D.OWNER AND D1.TABLE_NAME=D.TABLE_NAME AND D1.COLUMN_NAME=D.COLUMN_NAME)
			WHERE A.OWNER=pUSER AND A.TABLE_NAME NOT LIKE 'BIN$%' AND C.TABLE_NAME NOT LIKE 'BIN$%' AND A.CONSTRAINT_TYPE='R' AND C.CONSTRAINT_TYPE='P'
	)	WHERE DATA_TYPE<>R_DATA_TYPE;
END;

PROCEDURE CHECK_NOPRIMARY
--功能:檢測數據庫中未創建主鍵或者惟一約束的狀況
--參數:DBUSER-數據庫用戶,pCURSOR-返回數據庫中未創建主鍵或者惟一約束的表
--調用:
/*
DECLARE pCURSOR SYS_REFCURSOR;
BEGIN
	PKG_ANALYZE.CHECK_NOPRIMARY('DKGLL',pCURSOR);
END;
*/
--日期:2013-02-10
(
	DBUSER 	IN VARCHAR:=USER,
	pCURSOR OUT SYS_REFCURSOR
)
AS
	pUSER VARCHAR2(200):=COALESCE(UPPER(DBUSER),USER);
BEGIN
  OPEN pCURSOR FOR SELECT * FROM SYS.DBA_TABLES A WHERE A.OWNER=pUSER AND NOT EXISTS(
		SELECT * FROM SYS.DBA_CONSTRAINTS B
			WHERE B.OWNER=pUSER AND B.CONSTRAINT_TYPE IN('P','U') AND B.TABLE_NAME=A.TABLE_NAME
		)
		AND A.TEMPORARY='N' ORDER BY A.TABLE_NAME;
END;

PROCEDURE GET_COMPARETEXT
--功能:返回查詢目標庫與連接源庫表的差別或相同部分的SQL語句
--參數:見下方說明
--調用:
/*
DECLARE pSELTEXT VARCHAR2(4000);
BEGIN
	PKG_ANALYZE.GET_COMPARETEXT(1,'DATABASE_LINK1','DEV_INFOEXTAB',3,pSELTEXT);
  SYS.DBMS_OUTPUT.PUT_LINE('--SQL語句:'||CHR(10)||pSELTEXT);
END;
*/
--日期:2013-04-1
(
	pTAG        IN NUMBER,          --查詢模式:1-求同(交集),2-求異(補集)
	pLINKNAME 	IN VARCHAR, 				--連接名
	pTABLENAME 	IN VARCHAR2:=NULL,	--源表,能夠爲一張或多張表,多個表以','分隔,爲空則選擇全部表
	pMODE 			IN NUMBER:=1, 			--匹配模式
	pSELTEXT    OUT VARCHAR2
)
--匹配模式:
--1-只比較基礎數據類型,如VARCHAR二、NUMBER、DATE等,
--2-在1基礎上比較數據類型的長度和精度,
--3-在2基礎上比較列可否爲空
AS
	pUSER     VARCHAR2(200):=USER;
	pSELECT   VARCHAR2(1000);
	pFROM     VARCHAR2(1000);
	pLINKFROM VARCHAR2(1000);
	pOUTCOL   VARCHAR2(100);
	pSELTYPE	VARCHAR2(50);
BEGIN
	pSELECT:=Q'{SELECT A.TABLE_NAME AS TABLENAME,B.COLUMN_NAME AS COLUMNNAME,DATA_TYPE,
		CASE DATA_TYPE
		WHEN 'NUMBER' THEN
		CASE NVL(TO_CHAR(B.DATA_SCALE),'0')
		WHEN '0' THEN 'INT'
		ELSE 'DECIMAL('||NVL(TO_CHAR(B.DATA_PRECISION),'18')||','||B.DATA_SCALE||')'
		END
		WHEN 'VARCHAR2' THEN 'VARCHAR('||B.CHAR_LENGTH||')'
		WHEN 'DATE' THEN 'DATETIME'
		WHEN 'BLOB' THEN 'VARBINARY(4000)'
		WHEN 'LONG' THEN 'VARCHAR(4000)'
		ELSE B.DATA_TYPE
		END AS SQLTYPE,
		CASE DATA_TYPE
		WHEN 'NUMBER' THEN REPLACE(B.DATA_TYPE||'('||NVL(TO_CHAR(B.DATA_PRECISION),'*')||','||NVL(TO_CHAR(B.DATA_SCALE),'*')||')','(*,*)','')
		WHEN 'VARCHAR2' THEN B.DATA_TYPE||'('||B.CHAR_LENGTH||')'
		ELSE B.DATA_TYPE
		END AS ORACLETYPE,
		CASE B.NULLABLE WHEN 'Y' THEN 'NULL' ELSE 'NOT NULL' END AS ISNULLABLE,
		COLUMN_ID AS COLUMN_ID
		FROM }';
	pFROM:='SYS.DBA_TABLES A JOIN SYS.DBA_TAB_COLUMNS B ON (A.TABLE_NAME=B.TABLE_NAME AND A.OWNER=B.OWNER) WHERE A.OWNER='''||pUSER
		||''' AND (INSTR('',''||'''|| pTABLENAME||'''||'','','',''||A.TABLE_NAME||'','',1)>0 OR '''||pTABLENAME||
		''' IS NULL) AND A.TEMPORARY=''N'' ORDER BY TABLENAME,COLUMN_ID'; 						--查詢本地表
	pLINKFROM:='SYS.USER_TABLES@'||pLINKNAME||' A JOIN SYS.USER_TAB_COLUMNS@'||pLINKNAME||
		' B ON (A.TABLE_NAME=B.TABLE_NAME) WHERE (INSTR('',''||'''|| pTABLENAME||'''||'','','',''||A.TABLE_NAME||'','',1)>0 OR '''||pTABLENAME||
		''' IS NULL) AND A.TEMPORARY=''N''';																					--查詢連接庫表
	SELECT 'SELECT TABLENAME,COLUMNNAME,DATA_TYPE'||DECODE(pMODE,2,',ORACLETYPE',3,',ORACLETYPE,ISNULLABLE','')||' FROM(' INTO pOUTCOL	FROM DUAL;
	SELECT DECODE(pTAG,1,'INTERSECT','MINUS') INTO pSELTYPE FROM DUAL;              --查詢模式
	pSELTEXT:=pOUTCOL||chr(10)||' '||pSELECT||pLINKFROM||CHR(10)||') LINKDB'||CHR(10)||pSELTYPE||' '||pOUTCOL||CHR(10)||' '||
		pSELECT||pFROM||CHR(10)||') SELFDB';
END;

PROCEDURE CHECK_MERGE_MINUS
--功能:查詢目標庫與源庫表的差別部分(若是目標表中存在主鍵相同記錄,則同步類型爲'UPDATE',不存在則同步類型爲'INSERT',目標表中存在而源表中不存在則同步類型爲'DELETE')
--參數:
--調用:
/*
DECLARE pCURSOR SYS_REFCURSOR;
BEGIN
	PKG_ANALYZE.CHECK_MERGE_MINUS('USR_INFOTAB@DBLINK','USR_INFOTAB',pCURSOR);
END;
*/
--日期:2014-05-8
(
	pSOURCETB 	IN  VARCHAR, 				--源表名,若是爲遠程連接表,相似爲TABLENAME@LINKNAME的格式,如:USR_INFOTAB@DATABASE_LINK1
	pTARGETTB 	IN  VARCHAR2,	      --目標表名
  pFILTER     IN  VARCHAR2:=NULL, --條件過濾
  pCURSOR     OUT SYS_REFCURSOR
)
AS
  pON         VARCHAR2(4000);     --鏈接查詢條件列
	pWHERE			VARCHAR2(4000);     --WHERE條件列
	pMINUSSQL		VARCHAR2(4000);     --查詢差別記錄的SQL語句
	pSQL 				VARCHAR2(4000);		  --拼接完整的查詢SQL語句
BEGIN
  pMINUSSQL:= 'SELECT * FROM  '||pSOURCETB||''||' '||pFILTER||' MINUS SELECT * FROM '||pTARGETTB||' '||pFILTER;
--  --條件爲主鍵、全部惟一約束、全部惟一索引共同匹配,防止出現違反惟一約束或主鍵衝突
--  SELECT DISTINCT LISTAGG('TA."'||COLUMN_NAME||'"=TB."'||COLUMN_NAME||'"',' AND ') WITHIN GROUP(ORDER BY 1) OVER(),
--  LISTAGG('TB."'||COLUMN_NAME||'"','||') WITHIN GROUP(ORDER BY 1) OVER() INTO pON,pWHERE FROM(
--    SELECT  DISTINCT B.COLUMN_NAME
--      FROM SYS.USER_INDEXES A
--      JOIN SYS.USER_IND_COLUMNS B ON (A.TABLE_NAME=B.TABLE_NAME AND A.INDEX_NAME=B.INDEX_NAME)
--      WHERE A.TABLE_NAME=pTARGETTB AND A.TABLE_TYPE='TABLE' AND A.UNIQUENESS='UNIQUE');
 
  --2016-02-20修改:當主鍵字段已存在,惟一約束字段值不一樣時不會進行同步,故去掉惟一約束、惟一索引條件    
  SELECT DISTINCT LISTAGG('TA."'||TB.COLUMN_NAME||'"=TB."'||TB.COLUMN_NAME||'"',' AND ')
    WITHIN GROUP(ORDER BY TB.POSITION) OVER(PARTITION BY TA.INDEX_NAME),
    LISTAGG('TB."'||TB.COLUMN_NAME||'"','||') WITHIN GROUP(ORDER BY TB.POSITION) OVER() INTO pON,pWHERE FROM SYS.USER_CONSTRAINTS TA 
    JOIN SYS.USER_CONS_COLUMNS TB ON (TA.owner=TB.owner AND TA.table_name=TB.table_name AND TA.constraint_name=TB.constraint_name)
    WHERE TA.TABLE_NAME=pTARGETTB AND TA.CONSTRAINT_TYPE='P';
    
  pSQL:='SELECT CASE WHEN '||pWHERE||' IS NOT NULL THEN ''UPDATE'' ELSE ''INSERT'' END AS MERGE_DATA_TYPE,TA.* FROM('||CHR(10)||
        ' SELECT * FROM  '||pSOURCETB||''||' '||pFILTER||CHR(10)||
        ' MINUS'||CHR(10)||
        ' SELECT * FROM '||pTARGETTB||' '||pFILTER||CHR(10)||
        ') TA'||CHR(10)||
        '  LEFT JOIN '||pTARGETTB||' TB ON ('||pON||')'||CHR(10)||
        'UNION ALL'||CHR(10)||
        'SELECT ''DELETE'' AS MERGE_DATA_TYPE,TB.* FROM '||pTARGETTB||' TB WHERE NOT EXISTS('||CHR(10)||
        ' SELECT * FROM '||pSOURCETB||' TA WHERE '||pON||CHR(10)||
        ')';
  SYS.DBMS_OUTPUT.PUT_LINE('/*SQL語句*/'||CHR(10)||pSQL);
  OPEN pCURSOR FOR pSQL;
  EXCEPTION
	WHEN NO_DATA_FOUND THEN
    OPEN pCURSOR FOR 'SELECT ''INSERT'' AS MERGE_DATA_TYPE,TB.* FROM(' ||pMINUSSQL||') TB';
		--SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'表'||pTABLENAME||'中無主鍵和惟一約束,沒法進行對比!');
	WHEN OTHERS THEN
		SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'對比表數據異常:' ||SQLERRM);
END;

FUNCTION GET_TABLE_COUNT
(
  pLINKNAME 	    IN VARCHAR, 				--連接名
	pCHECKTABLELIST IN CHECKTABLELIST 	--源過濾的表類型 
)
RETURN  CHETABLECOUNTLIST PIPELINED
AS
  pSOURCETB   VARCHAR2(200);       --源表名
  pTARGETTB   VARCHAR2(200);       --目的表名
  pFILTER     VARCHAR2(2000);     --過濾條件
  pON         VARCHAR2(4000);     --鏈接查詢條件列
  pWHERE			VARCHAR2(4000);     --WHERE條件列
  pMINUSSQL		VARCHAR2(4000);     --查詢差別記錄的SQL語句
  pSQL 				VARCHAR2(4000);		  --拼接完整的查詢SQL語句
  CN CHETABLECOUNT;
BEGIN
  FOR X IN
  (
    SELECT * FROM TABLE(pCHECKTABLELIST) 
  )
  LOOP 
    pSOURCETB:=X.TABLENAME||'@'||pLINKNAME;
    pTARGETTB:=X.TABLENAME;
    pFILTER:=X.WHERESTR;
    pMINUSSQL:= 'SELECT * FROM  '||pSOURCETB||''||' '||pFILTER||' MINUS SELECT * FROM '||pTARGETTB||' '||pFILTER; 
    --2016-02-20修改:當主鍵字段已存在,惟一約束字段值不一樣時不會進行同步,故去掉惟一約束、惟一索引條件    
    SELECT DISTINCT LISTAGG('TA."'||TB.COLUMN_NAME||'"=TB."'||TB.COLUMN_NAME||'"',' AND ')
      WITHIN GROUP(ORDER BY TB.POSITION) OVER(PARTITION BY TA.INDEX_NAME),
      LISTAGG('TB."'||TB.COLUMN_NAME||'"','||') WITHIN GROUP(ORDER BY TB.POSITION) OVER() INTO pON,pWHERE FROM SYS.USER_CONSTRAINTS TA 
      JOIN SYS.USER_CONS_COLUMNS TB ON (TA.owner=TB.owner AND TA.table_name=TB.table_name AND TA.constraint_name=TB.constraint_name)
      WHERE TA.TABLE_NAME=pTARGETTB AND TA.CONSTRAINT_TYPE='P';
    
    pSQL:='SELECT '''||pTARGETTB||''' AS "表名",SUM(CASE MERGE_DATA_TYPE WHEN ''DELETE'' THEN MERGE_COUNT ELSE 0 END) AS "DELETE",'||CHR(10)||
          'SUM(CASE MERGE_DATA_TYPE WHEN ''INSERT'' THEN MERGE_COUNT ELSE 0 END) AS "INSERT",'||CHR(10)||
          'SUM(CASE MERGE_DATA_TYPE WHEN ''UPDATE'' THEN MERGE_COUNT ELSE 0 END) AS "UPDATE" FROM ('||CHR(10)||
          '  SELECT DISTINCT MERGE_DATA_TYPE,COUNT(MERGE_DATA_TYPE) OVER(PARTITION BY MERGE_DATA_TYPE)  AS "MERGE_COUNT" FROM ('||CHR(10)||
          '    SELECT CASE WHEN '||pWHERE||' IS NOT NULL THEN ''UPDATE'' ELSE ''INSERT'' END AS MERGE_DATA_TYPE,TA.* FROM('||CHR(10)||
          '      SELECT * FROM  '||pSOURCETB||''||' '||pFILTER||CHR(10)||
          '      MINUS'||CHR(10)||
          '      SELECT * FROM '||pTARGETTB||' '||pFILTER||CHR(10)||
          '    ) TA'||CHR(10)||
          '    LEFT JOIN '||pTARGETTB||' TB ON ('||pON||')'||CHR(10)||
          '    UNION ALL'||CHR(10)||
          '    SELECT ''DELETE'' AS MERGE_DATA_TYPE,TB.* FROM '||pTARGETTB||' TB WHERE NOT EXISTS('||CHR(10)||
          '     SELECT * FROM '||pSOURCETB||' TA WHERE '||pON||CHR(10)||
          '    )'||CHR(10)||
          '  )'||CHR(10)||
          ')'; 
    EXECUTE IMMEDIATE pSQL INTO CN;
    PIPE ROW(CN);
  END LOOP;
  RETURN;
END;

PROCEDURE CHECK_MERGE_COUNT
--功能:查詢目標庫與源庫表的差別記錄數量(若是目標表中存在主鍵相同記錄,則同步類型爲'UPDATE',不存在則同步類型爲'INSERT',目標表中存在而源表中不存在則同步類型爲'DELETE')
--參數:
--調用:
/*
DECLARE pCURSOR SYS_REFCURSOR; 
pCB CHECKTABLELIST;
BEGIN
  --pCB:=CHECKTABLELIST();
  --PCB.EXTEND(1);
  pCB(1):=CHECKTABLE('USR_INFOTAB','');
	--PKG_ANALYZE.CHECK_MERGE_COUNT('DLINK_160222094700882',pCB,pCURSOR);
END;
*/
--日期:2014-05-8
(
	pLINKNAME 	    IN VARCHAR, 				--連接名 
	pCHECKTABLELIST IN CHECKTABLELIST,	--源過濾的表類型 
  pCURSOR         OUT SYS_REFCURSOR
)
AS  
BEGIN    
  OPEN pCURSOR FOR SELECT TABLE_NAME AS "表名",INSERTCOUNT AS "INSER數量",UPDATECOUNT AS "修改數量",DELETECOUNT AS "刪除數量" FROM TABLE(PKG_ANALYZE.GET_TABLE_COUNT(pLINKNAME,pCHECKTABLELIST)) WHERE (DELETECOUNT+INSERTCOUNT+UPDATECOUNT)>0;  
END;

PROCEDURE CHECK_MINUS
--功能:查詢目標庫與連接源庫表的差別部分(求補集)
--參數:
--調用:
/*
DECLARE pCURSOR SYS_REFCURSOR;
BEGIN
	PKG_ANALYZE.CHECK_MINUS('DATABASE_LINK1','DEV_INFOEXTAB',3,pCURSOR);
END;
*/
--日期:2013-04-1
(
	pLINKNAME 	IN VARCHAR, 				--連接名
	pTABLENAME 	IN VARCHAR2:=NULL,	--源表,能夠爲一張或多張表,多個表以','分隔,爲空則選擇全部表
	pMODE 			IN NUMBER:=1, 			--匹配模式
	pCURSOR 		OUT SYS_REFCURSOR  	--返回連接庫中有而目標庫中沒有的部分
)
--匹配模式:
--1-只比較基礎數據類型,如VARCHAR二、NUMBER、DATE等,
--2-在1基礎上比較數據類型的長度和精度,
--3-在2基礎上比較列可否爲空
AS
	pSQLTEXT  VARCHAR2(4000);
BEGIN
	GET_COMPARETEXT(2,pLINKNAME,pTABLENAME,pMODE,pSQLTEXT);
	OPEN pCURSOR FOR pSQLTEXT;
END;

PROCEDURE CHECK_INTERSECT
--功能:查詢目標庫與連接源庫表的相同部分(求交集)
--參數:
--調用:
/*
DECLARE pCURSOR SYS_REFCURSOR;
BEGIN
	PKG_ANALYZE.CHECK_INTERSECT('DATABASE_LINK1','DEV_INFOEXTAB',3,pCURSOR);
END;
*/
--日期:2013-04-1
(
	pLINKNAME 	IN VARCHAR, 				--連接名
	pTABLENAME 	IN VARCHAR2:=NULL,	--源表,能夠爲一張或多張表,多個表以','分隔,爲空則選擇全部表
	pMODE 			IN NUMBER:=1, 			--匹配模式
	pCURSOR 		OUT SYS_REFCURSOR  	--返回連接庫、目標庫中共有的部分
)
--匹配模式:
--1-只比較基礎數據類型,如VARCHAR二、NUMBER、DATE等,
--2-在1基礎上比較數據類型的長度和精度,
--3-在2基礎上比較列可否爲空
AS
	pSQLTEXT  VARCHAR2(4000);
BEGIN
	GET_COMPARETEXT(1,pLINKNAME,pTABLENAME,pMODE,pSQLTEXT);
	OPEN pCURSOR FOR pSQLTEXT;
END;

PROCEDURE CHECK_DISTINCT
--功能:查詢對比目標庫與連接源庫表數據對比具備相同列數據的部分(如查詢重複列數據)
--參數:
--調用:
/*
DECLARE pCURSOR SYS_REFCURSOR;
BEGIN
	PKG_ANALYZE.CHECK_DISTINCT('DATABASE_LINK1','DEV_INFOEXTAB','DEVICENAME,DEVICETYPE,DEVICEMODEL,DEVICESN,DEVICEVER,PRODUCTCOMPANY,PRODUCTLINKPERSON,PRODUCTLINKTEL,
		BUILDCOMPANY,BUILDTEL,BUILDLINKPERSON,DEVICEAREA,DEVICEPLACE,LINKPERSON,LINKTEL,LINKMOBILE,LINKEMAIL',pCURSOR);
END;
*/
--日期:2013-04-9
(
	pLINKNAME 	IN VARCHAR, 				--連接名
	pTABLENAME 	IN VARCHAR2,				--表名
	pCOLNAME 		IN VARCHAR2,        --匹配列名,多個列以逗號分隔
	pCURSOR 		OUT SYS_REFCURSOR  	--返回連接庫、目標庫中共有的部分
)
AS
pCOLLIST VARCHAR2(2000);
pSQLTEXT VARCHAR2(2000);
BEGIN
  SELECT LISTAGG('LOWER(A.'||A.COL||')=LOWER(B.'||A.COL||')',' AND ') WITHIN GROUP(ORDER BY A.ROWN) INTO pCOLLIST FROM (
		SELECT ROWNUM AS ROWN,UPPER(regexp_substr(pCOLNAME,'[^,]+',1,LEVEL)) AS COL FROM DUAL
			CONNECT BY LEVEL<=LENGTH(pCOLNAME)-LENGTH(REPLACE(pCOLNAME,',',''))+1
	) A;
	pSQLTEXT:='SELECT * FROM '||pTABLENAME||' A WHERE EXISTS ('||CHR(10)||
		'SELECT * FROM '||pTABLENAME||'@'||pLINKNAME||' b WHERE '||pCOLLIST||')';
	--SYS.DBMS_OUTPUT.PUT_LINE('/*SQL語句:*/'||pSQLTEXT);
	OPEN pCURSOR FOR pSQLTEXT;
	EXCEPTION
	WHEN OTHERS THEN
		NULL;
END;
END;
/
create or replace PACKAGE PKG_MERGE
AS 
--功能:同步目標表和源表數據一致
PROCEDURE MERGE_TABLE( 
	pTARGETTB    IN VARCHAR2,   --表示目標表,只能爲單表名稱
	pSOURCETB    IN VARCHAR2,   --表示源表,可爲單表、單視圖、多表、多視圖鏈接查詢的結果集
	pTARGETWHERE IN VARCHAR2,   --目標表條件列,多個列以','分隔.列數和順序與源表條件列一致
	pSOURCEWHERE IN VARCHAR2,   --源表條件列,多個列以','分隔.列數和順序與目標表條件列一致
	pTARGETCOL   IN VARCHAR2,   --目標表記錄操做列,多個列以','分隔.列數和順序與源表記錄操做列一致
	pSOURCECOL   IN VARCHAR2    --源表記錄操做列,多個列以','分隔.列數和順序與目標表記錄操做條件列一致;
);

--功能:同步表,條件爲主鍵和惟一約束進行匹配
PROCEDURE MERGE_TABLE(
  pTARGETTB    IN VARCHAR2,       --表示目標表,只能爲單表名稱
  pSOURCETB    IN VARCHAR2,       --表示源表,只能爲單表名稱,源表和目標表結構和類型保持一致
  pKEY          IN VARCHAR2:=NULL,  --匹配條件,多列以逗號分隔
	pMODE				 IN	NUMBER:=1,			--若是記錄在目的數據庫上存在而在源數據庫表中不存在,處理方式:1-刪除目的數據庫中的記錄、其餘-不予操做
  pMSG         OUT NUMBER         --返回消息,1-同步成功,-1:失敗,-2:無主鍵和惟一約束
);

--功能:同步表,條件爲主鍵和惟一約束進行匹配,源數據庫來自遠程連接
PROCEDURE MERGE_LINK_TABLE(
	pLINKNAME		IN	VARCHAR2,				--連接名
	pTBLIST 		IN 	VARCHAR2:=NULL,	--表示目標表,能夠爲一張或多張表,多個表以','分隔
	pMODE				IN	NUMBER:=1,			--若是記錄在目的數據庫上存在而在源數據庫表中不存在,處理方式:1-刪除目的數據庫中的記錄、其餘-不予操做
  pMSG        OUT NUMBER,         --返回消息,1-同步成功,-1:失敗,-2:無主鍵和惟一約束
  pFILTER     IN  VARCHAR2:=NULL  --條件過濾
);

--功能:同步表,條件爲主鍵和惟一約束進行匹配,源數據庫來自遠程連接,目標數據庫也來自遠程連接
PROCEDURE MERGE_TWOLINK(
	pSOURCELINK		IN	VARCHAR2,				--連接源數據庫的連接名
	pTARGETLINK		IN	VARCHAR2,				--連接目的數據庫的連接名
	pTBLIST 		  IN 	VARCHAR2:=NULL,	--表示目標表,能夠爲一張或多張表,多個表以','分隔
	pMODE				  IN	NUMBER:=1,			--若是記錄在目的數據庫上存在而在源數據庫表中不存在,處理方式:1-刪除目的數據庫中的記錄、其餘-不予操做
  pMSG          OUT NUMBER          --返回消息,1-同步成功,-1:失敗,-2:無主鍵和惟一約束
);

--功能:同步表數據(支持低版本數據源往同版本或高版本目標庫同步,同時也支持高版本數據源往低版本目標庫同步)
PROCEDURE MERGE_INTERSECT(
	pLINKNAME 	IN VARCHAR2, 				--連接名
	pTABLENAME 	IN VARCHAR2:=NULL,	--源表,能夠爲一張或多張表,多個表以','分隔,爲空則選擇結構類型一致的全部表
	pMODE 			IN NUMBER:=1 				--匹配模式
);

--功能:同步本地數據庫表,根據列名相同原則來匹配,pTABLENAME爲NULL則同步全部表的記錄,不爲NULL則同步一個或多個表的記錄,多個表以','分隔
PROCEDURE MERGE_FROM_DB(
	pLINKNAME			IN VARCHAR2,						--連接名
	pTABLENAME 		IN VARCHAR2:=NULL,			--連接數據庫同步表,多個表以','分隔
	pTABLEEXIXTS 	IN VARCHAR2:='DELETE'   --本地表存在的處理方式
);

--功能:同步連接數據庫表,根據列名相同原則來匹配,pTABLENAME爲NULL則同步全部表的記錄,不爲NULL則同步一個或多個表的記錄,多個表以','分隔
PROCEDURE MERGE_TO_DB(
	pLINKNAME			IN VARCHAR2,						--連接名
	pTABLENAME 		IN VARCHAR2:=NULL, 			--本地數據庫同步表,多個表以','分隔
	pTABLEEXIXTS 	IN VARCHAR2:='DELETE'   --連接表存在的處理方式:'DELETE'-直接刪除表數據再添加、'APPEND'-追加
);
END;
/
create or replace PACKAGE BODY PKG_MERGE 
AS 
PROCEDURE MERGE_TABLE
--功能:同步表
--參數:見下方說明
--調用:EXECUTE PKG_MERGE.MERGE_TABLE('DEV_INFOEXTAB','DEV_INFOTAB','DEVICENAME','DEVICENAME','DEVICEID','DEVICEID');
--日期:2013-02-10
(
  pTARGETTB    IN VARCHAR2,   --表示目標表,只能爲單表名稱
  pSOURCETB    IN VARCHAR2,   --表示源表,可爲單表、單視圖、多表、多視圖鏈接查詢的結果集
  pTARGETWHERE IN VARCHAR2,   --目標表條件列,多個列以','分隔.列數和順序與源表條件列一致
  pSOURCEWHERE IN VARCHAR2,   --源表條件列,多個列以','分隔.列數和順序與目標表條件列一致
  pTARGETCOL   IN VARCHAR2,   --目標表記錄操做列,多個列以','分隔.列數和順序與源表記錄操做列一致
  pSOURCECOL   IN VARCHAR2    --源表記錄操做列,多個列以','分隔.列數和順序與目標表記錄操做條件列一致
)
AS
	pUSESOURCE 	VARCHAR2(4000);   --拼接源表結果集,若是是單表能夠直接爲表名,不然必須用'()'進行包裝查詢語句
	pWHERE 			VARCHAR2(4000);   --拼接MERGER同步源表與目標表的匹配WHERE條件
	pUPDATECOL 	VARCHAR2(4000);   --拼接MERGER同步源表與目標表的修改列
	pINSERTCOL 	VARCHAR2(4000);   --拼接MERGER同步源表與目標表的添加列
	pSQL 				VARCHAR2(4000);		--拼接MERGER同步的完整SQL語句
BEGIN 
  SELECT DECODE(INSTR(TRIM(UPPER(pSOURCETB)),'SELECT'),1,'('||pSOURCETB||')',pSOURCETB) INTO pUSESOURCE FROM DUAL;--拼接源表結果集  
  SELECT LISTAGG('S.'||A.COL||'=T.'||B.COL,' AND ') WITHIN GROUP(ORDER BY A.ROWN) INTO pWHERE
    FROM (SELECT ROWNUM AS ROWN,UPPER(regexp_substr(pSOURCEWHERE,'[^,]+',1,LEVEL)) AS COL FROM DUAL 
      CONNECT BY LEVEL<=LENGTH(pSOURCEWHERE)-LENGTH(REPLACE(pSOURCEWHERE,',',''))+1) A 
    JOIN (SELECT ROWNUM AS ROWN,UPPER(regexp_substr(pTARGETWHERE,'[^,]+',1,LEVEL)) AS COL FROM DUAL 
      CONNECT BY LEVEL<=LENGTH(pTARGETWHERE)-LENGTH(REPLACE(pTARGETWHERE,',',''))+1) B ON A.ROWN=B.ROWN; --拼接MERGER同步源表與目標表的匹配WHERE條件
  SELECT LISTAGG(A.COL||'=T.'||B.COL,',') WITHIN GROUP(ORDER BY A.ROWN) INTO pUPDATECOL
    FROM (SELECT ROWNUM AS ROWN,UPPER(regexp_substr(pSOURCECOL,'[^,]+',1,LEVEL)) AS COL FROM DUAL 
      CONNECT BY LEVEL<=LENGTH(pSOURCECOL)-LENGTH(REPLACE(pSOURCECOL,',',''))+1) A 
    JOIN (SELECT ROWNUM AS ROWN,UPPER(regexp_substr(pTARGETCOL,'[^,]+',1,LEVEL)) AS COL FROM DUAL 
      CONNECT BY LEVEL<=LENGTH(pTARGETCOL)-LENGTH(REPLACE(pTARGETCOL,',',''))+1) B ON A.ROWN=B.ROWN;     --拼接MERGER同步源表與目標表的修改列
  SELECT 'T.'||REPLACE(pSOURCEWHERE||','||pSOURCECOL,',',',T.') INTO pINSERTCOL FROM DUAL;               --拼接MERGER同步源表與目標表的添加列    
  pSQL:='MERGE INTO '||pTARGETTB||' S'||CHR(10)||
        'USING '||pUSESOURCE||' T'||CHR(10)||
        'ON('||pWHERE||')'||CHR(10)||
        '  WHEN MATCHED THEN'||CHR(10)||
        '    UPDATE SET '||pUPDATECOL||CHR(10)|| 
        '  WHEN NOT MATCHED THEN'||CHR(10)||
        '    INSERT ('||pTARGETWHERE||','||pTARGETCOL||')'||' VALUES('||pINSERTCOL||')';                 --拼接MERGER同步的完整SQL語句
	--SYS.DBMS_OUTPUT.PUT_LINE('/*SQL語句:*/'||pSQL);
  EXECUTE IMMEDIATE pSQL;
  COMMIT;
  EXCEPTION 
	WHEN OTHERS THEN
		SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'同步表數據異常:' ||SQLERRM);
END;

PROCEDURE MERGE_TABLE
--功能:同步表,條件爲主鍵和惟一約束進行匹配
--參數:見下方說明
--調用:
/*
DECLARE pMSG NUMBER(2);
BEGIN
  PKG_MERGE.MERGE_TABLE('DATABASE_LINK1','USR_ROLETAB',1,pMSG);
  DBMS_OUTPUT.PUT_LINE('同步消息:'||pMSG);
END;
*/
--日期:2014-05-13
(
  pTARGETTB    IN VARCHAR2,       --表示目標表,只能爲單表名稱
  pSOURCETB    IN VARCHAR2,       --表示源表,只能爲單表名稱,源表和目標表結構和類型保持一致
  pKEY          IN VARCHAR2:=NULL,  --匹配條件,多列以逗號分隔
	pMODE				IN	NUMBER:=1,			--若是記錄在目的數據庫上存在而在源數據庫表中不存在,處理方式:1-刪除目的數據庫中的記錄、其餘-不予操做
  pMSG        OUT NUMBER          --返回消息,1-同步成功,-1:失敗,-2:無主鍵和惟一約束
)
AS
	pWHERE				VARCHAR2(4000);   --拼接MERGER同步源表與目標表的匹配WHERE條件
	pUPDATECOL 		VARCHAR2(4000);   --拼接MERGER同步源表與目標表的修改列
	pINSERTCOL 		VARCHAR2(4000);   --拼接MERGER同步源表與目標表的添加列
	pSQL 					VARCHAR2(4000);		--拼接MERGER同步的完整SQL語句
  PROCEDURE MERGE_NOCONSTRA
  AS
  BEGIN    
    IF pKEY IS NOT NULL THEN 
      SELECT DISTINCT LISTAGG('S."'||COLUMN_VALUE||'"=T."'||COLUMN_VALUE||'"',' AND ') 
        WITHIN GROUP(ORDER BY 1) OVER() INTO pWHERE FROM (
          SELECT * FROM TABLE(PKG_FUNC.SPLITSTR(pKEY))
        );
    ELSE
      SELECT DISTINCT LISTAGG('S."'||B.COLUMN_NAME||'"=T."'||B.COLUMN_NAME||'"',' AND ')
        WITHIN GROUP(ORDER BY B.POSITION) OVER(PARTITION BY A.INDEX_NAME) INTO pWHERE FROM SYS.USER_CONSTRAINTS A
        JOIN SYS.USER_CONS_COLUMNS B ON (A.owner=b.owner AND A.table_name=b.table_name AND A.constraint_name=B.constraint_name)
        WHERE A.TABLE_NAME=pTARGETTB AND A.CONSTRAINT_TYPE='P';
    END IF;
    EXCEPTION
    WHEN NO_DATA_FOUND THEN
      pMSG:=1;              --無主鍵和惟一約束則直接添加,2014-08-02修改成去掉惟一約束斷定
      pSQL:='INSERT INTO '||pTARGETTB||' SELECT * FROM '||pSOURCETB;
      --SYS.DBMS_OUTPUT.PUT_LINE(pSQL);
      EXECUTE IMMEDIATE pSQL;
      --SYS.DBMS_OUTPUT.PUT_LINE('同步無主鍵和惟一約束的表'||pTARGETTB||'數據成功!');
    WHEN OTHERS THEN
      pMSG:=-1;             --同步失敗
      --SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'同步無主鍵和惟一約束的表'||pTARGETTB||'數據異常:' ||SQLERRM);
  END;
BEGIN
		pWHERE:='';
		pUPDATECOL:='';
		pINSERTCOL:='';
    MERGE_NOCONSTRA;   --判斷表中是否有主鍵、惟一約束,若是不存在則直接添加表數據,不然跳過直接進行下一步操做,2014-08-02修改成去掉惟一約束斷定
    IF pWHERE IS NOT NULL THEN
      FOR Y IN
      (
        SELECT DISTINCT * FROM ( SELECT TA.COLUMN_NAME,TB.COLUMN_NAME AS CONS_COL FROM SYS.USER_TAB_COLUMNS TA
         LEFT JOIN(
          SELECT A.TABLE_NAME,B.COLUMN_NAME FROM SYS.USER_CONSTRAINTS A 
            JOIN SYS.USER_CONS_COLUMNS B ON (A.owner=b.owner AND A.table_name=b.table_name AND A.constraint_name=B.constraint_name)
            WHERE A.TABLE_NAME=pTARGETTB AND A.CONSTRAINT_TYPE='P'
         ) TB ON (TA.TABLE_NAME=TB.TABLE_NAME AND TA.COLUMN_NAME=TB.COLUMN_NAME)
         WHERE TA.TABLE_NAME=pTARGETTB ORDER BY TA.COLUMN_ID)
      )                   --2014-08-02修改成條件爲主鍵匹配
      LOOP
        IF Y.CONS_COL IS NULL THEN
          pUPDATECOL:=pUPDATECOL||'"'||Y.COLUMN_NAME||'"=T."'||Y.COLUMN_NAME||'",';
        END IF;
        pINSERTCOL:=pINSERTCOL||',"'||Y.COLUMN_NAME||'"';
      END LOOP;
      pUPDATECOL:=RTRIM(pUPDATECOL,',');
      pSQL:='MERGE INTO '||pTARGETTB||' S'||CHR(10)||
            'USING '||pSOURCETB||' T'||CHR(10)||
            'ON('||pWHERE||')'||CHR(10);    
      IF pUPDATECOL IS NOT NULL THEN
      pSQL:=pSQL||'  WHEN MATCHED THEN'||CHR(10)||
        '    UPDATE SET '||RTRIM(pUPDATECOL,',')||CHR(10);
      END IF;
      pSQL:=pSQL||'  WHEN NOT MATCHED THEN'||CHR(10)||
        '    INSERT ('||LTRIM(REPLACE(pINSERTCOL,',',',S.'),',')||')'||' VALUES('||LTRIM(REPLACE(pINSERTCOL,',',',T.'),',')||')';
        --SYS.DBMS_OUTPUT.PUT_LINE(pSQL);
      EXECUTE IMMEDIATE pSQL;
      --SYS.DBMS_OUTPUT.PUT_LINE(pSQL);
      IF pMODE=1 THEN 		  --若是記錄在目的數據庫上存在而在源數據庫表中不存在,刪除目的數據庫中的記錄      
        pSQL:='DELETE FROM '||pTARGETTB||' T WHERE NOT EXISTS(SELECT * FROM '||pSOURCETB||' S WHERE '||pWHERE||')';--刪除在目標表中存在而在源表不存在的數據
        EXECUTE IMMEDIATE pSQL;
        --SYS.DBMS_OUTPUT.PUT_LINE(pSQL);
      END IF;
    END IF;
  pMSG:=1;                --同步成功
  COMMIT;
  EXCEPTION
	WHEN OTHERS THEN
    pMSG:=-1;             --同步失敗
		SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'同步表數據異常:' ||SQLERRM);
END;

PROCEDURE MERGE_LINK_TABLE
--功能:同步表,條件爲主鍵和惟一約束進行匹配,源數據庫來自遠程連接,2014-08-02修改成去掉惟一約束斷定
--參數:見下方說明
--調用:
/*
DECLARE pMSG NUMBER(2);
BEGIN
  PKG_MERGE.MERGE_LINK_TABLE('DATABASE_LINK1','USR_ROLETAB',1,pMSG,null);
  DBMS_OUTPUT.PUT_LINE('同步消息:'||pMSG);
END;
*/
--日期:2014-05-13
(
	pLINKNAME		IN	VARCHAR2,				--連接名
	pTBLIST 		IN 	VARCHAR2:=NULL,	--表示目標表,能夠爲一張或多張表,多個表以','分隔
	pMODE				IN	NUMBER:=1,			--若是記錄在目的數據庫上存在而在源數據庫表中不存在,處理方式:1-刪除目的數據庫中的記錄、其餘-不予操做
  pMSG        OUT NUMBER,         --返回消息,1-同步成功,-1:失敗,-2:無主鍵和惟一約束
  pFILTER     IN  VARCHAR2:=NULL  --條件過濾
)
AS
	pSINGLETBNAME	VARCHAR2(50);			--保存當前表名
  pCLONETBNAME  VARCHAR2(50);			--中間表名稱
	pWHERE				VARCHAR2(4000);   --拼接MERGER同步源表與目標表的匹配WHERE條件
	pUPDATECOL 		VARCHAR2(4000);   --拼接MERGER同步源表與目標表的修改列
	pINSERTCOL 		VARCHAR2(4000);   --拼接MERGER同步源表與目標表的添加列
	pSQL 					VARCHAR2(4000);		--拼接MERGER同步的完整SQL語句
  PROCEDURE MERGE_NOCONSTRA
  AS
  BEGIN    
    --條件爲主鍵、全部惟一約束、全部惟一索引共同匹配,防止出現違反惟一約束或主鍵衝突
--    SELECT DISTINCT LISTAGG('('||WHERELIST||')',' OR ') WITHIN GROUP(ORDER BY INDEX_NAME) OVER() INTO pWHERE FROM(
--      SELECT DISTINCT A.INDEX_NAME,
--        LISTAGG('S."'||B.COLUMN_NAME||'"=T."'||B.COLUMN_NAME||'"',' AND ')
--          WITHIN GROUP(ORDER BY B.COLUMN_POSITION) OVER(PARTITION BY A.INDEX_NAME) AS WHERELIST  FROM SYS.USER_INDEXES A
--        JOIN SYS.USER_IND_COLUMNS B ON (A.TABLE_NAME=B.TABLE_NAME AND A.INDEX_NAME=B.INDEX_NAME)
--        WHERE A.TABLE_NAME=pSINGLETBNAME AND A.TABLE_TYPE='TABLE' AND A.UNIQUENESS='UNIQUE'); 
    --2014-08-02修改:當主鍵字段已存在,惟一約束字段值不一樣時不會進行同步,故去掉惟一約束、惟一索引條件    
    SELECT DISTINCT LISTAGG('S."'||B.COLUMN_NAME||'"=T."'||B.COLUMN_NAME||'"',' AND ')
        WITHIN GROUP(ORDER BY B.POSITION) OVER(PARTITION BY A.INDEX_NAME) INTO pWHERE FROM SYS.USER_CONSTRAINTS A 
      JOIN SYS.USER_CONS_COLUMNS B ON (A.owner=b.owner AND A.table_name=b.table_name AND A.constraint_name=B.constraint_name)
      WHERE A.TABLE_NAME=pSINGLETBNAME AND A.CONSTRAINT_TYPE='P';
    EXCEPTION
    WHEN NO_DATA_FOUND THEN
      pMSG:=1;              --無主鍵和惟一約束則直接添加,2014-08-02修改成去掉惟一約束斷定
      pSQL:='INSERT INTO '||pSINGLETBNAME||' SELECT * FROM '||pSINGLETBNAME||'@'||pLINKNAME||' '||pFILTER;
      EXECUTE IMMEDIATE pSQL;
      --SYS.DBMS_OUTPUT.PUT_LINE('同步無主鍵和惟一約束的表'||pSINGLETBNAME||'數據成功!');
    WHEN OTHERS THEN
      pMSG:=-1;             --同步失敗
      --SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'同步無主鍵和惟一約束的表'||pSINGLETBNAME||'數據異常:' ||SQLERRM);
  END;
BEGIN
 	FOR X IN
	(
		SELECT LEVEL AS RN,REGEXP_SUBSTR(UPPER(pTBLIST),'[^,]+',1,LEVEL) AS TBNAME FROM DUAL
			CONNECT BY LEVEL<LENGTH(pTBLIST)-LENGTH(REPLACE(pTBLIST,','))+2
	)
	LOOP
		pSINGLETBNAME:=X.TBNAME;
		pWHERE:='';
		pUPDATECOL:='';
		pINSERTCOL:='';
    MERGE_NOCONSTRA;   --判斷表中是否有主鍵、惟一約束,若是不存在則直接添加表數據,不然跳過直接進行下一步操做,2014-08-02修改成去掉惟一約束斷定
    IF pWHERE IS NOT NULL THEN
--      FOR Y IN
--      (
--       SELECT DISTINCT * FROM ( SELECT TA.COLUMN_NAME,TB.COLUMN_NAME AS CONS_COL FROM SYS.USER_TAB_COLUMNS TA
--         LEFT JOIN(
--          SELECT A.TABLE_NAME,B.COLUMN_NAME FROM SYS.USER_INDEXES A
--            JOIN SYS.USER_IND_COLUMNS B ON (A.TABLE_NAME=B.TABLE_NAME AND A.INDEX_NAME=B.INDEX_NAME)
--            WHERE A.TABLE_TYPE='TABLE' AND A.UNIQUENESS='UNIQUE'
--         ) TB ON (TA.TABLE_NAME=TB.TABLE_NAME AND TA.COLUMN_NAME=TB.COLUMN_NAME)
--         WHERE TA.TABLE_NAME=pSINGLETBNAME  ORDER BY TA.COLUMN_ID)
--      )                 --條件爲主鍵、全部惟一約束、全部惟一索引共同匹配,防止出現違反惟一約束或主鍵衝突,2014-08-02修改成去掉惟一約束斷定
      FOR Y IN
      (
        SELECT DISTINCT * FROM ( SELECT TA.COLUMN_NAME,TB.COLUMN_NAME AS CONS_COL FROM SYS.USER_TAB_COLUMNS TA
         LEFT JOIN(
          SELECT A.TABLE_NAME,B.COLUMN_NAME FROM SYS.USER_CONSTRAINTS A 
            JOIN SYS.USER_CONS_COLUMNS B ON (A.owner=b.owner AND A.table_name=b.table_name AND A.constraint_name=B.constraint_name)
            WHERE A.TABLE_NAME=pSINGLETBNAME AND A.CONSTRAINT_TYPE='P'
         ) TB ON (TA.TABLE_NAME=TB.TABLE_NAME AND TA.COLUMN_NAME=TB.COLUMN_NAME)
         WHERE TA.TABLE_NAME=pSINGLETBNAME ORDER BY TA.COLUMN_ID)
      )                   --2014-08-02修改成條件爲主鍵匹配
      LOOP
        IF Y.CONS_COL IS NULL THEN
          pUPDATECOL:=pUPDATECOL||Y.COLUMN_NAME||'=T.'||Y.COLUMN_NAME||',';
        END IF;
        pINSERTCOL:=pINSERTCOL||','||Y.COLUMN_NAME;
      END LOOP;
      pUPDATECOL:=RTRIM(pUPDATECOL,',');
      pSQL:='MERGE INTO '||pSINGLETBNAME||' S'||CHR(10)|| 
            'USING (SELECT * FROM '||pSINGLETBNAME||'@'||pLINKNAME||' '||pFILTER||') T'||CHR(10)||
            'ON('||pWHERE||')'||CHR(10);    
      IF pUPDATECOL IS NOT NULL THEN
      pSQL:=pSQL||'  WHEN MATCHED THEN'||CHR(10)||
        '    UPDATE SET '||RTRIM(pUPDATECOL,',')||CHR(10);
      END IF;
      pSQL:=pSQL||'  WHEN NOT MATCHED THEN'||CHR(10)||
        '    INSERT ('||LTRIM(REPLACE(pINSERTCOL,',',',S.'),',')||')'||' VALUES('||LTRIM(REPLACE(pINSERTCOL,',',',T.'),',')||')';
      EXECUTE IMMEDIATE pSQL;
      --SYS.DBMS_OUTPUT.PUT_LINE(pSQL);
      --SYS.DBMS_OUTPUT.PUT_LINE('同步'||pSINGLETBNAME||'表數據成功!');
      IF pMODE=1 THEN 		  --若是記錄在目的數據庫上存在而在源數據庫表中不存在,刪除目的數據庫中的記錄,採用傳輸數據到中間表的方式進行優化處理
        pCLONETBNAME:='TMP_'||pSINGLETBNAME;            
        PKG_DBMANAGE.CLONE_TEMP_TB(pSINGLETBNAME,pCLONETBNAME);                                                           --克隆生成中間臨時表
        EXECUTE IMMEDIATE 'INSERT INTO '||pCLONETBNAME||' SELECT * FROM '||pSINGLETBNAME||'@'||pLINKNAME;                 --轉儲數據到中間表中
        pSQL:='DELETE FROM '||pSINGLETBNAME||' T WHERE NOT EXISTS(SELECT * FROM '||pCLONETBNAME||' S WHERE '||pWHERE||')';--刪除在目標表中存在而在中間表不存在的數據
        EXECUTE IMMEDIATE pSQL;
      END IF;
    END IF;
  END LOOP;
  pMSG:=1;                --同步成功
  COMMIT;
  EXCEPTION
	WHEN OTHERS THEN
    pMSG:=-1;             --同步失敗
		--SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'同步表數據異常:' ||SQLERRM);
END;

PROCEDURE MERGE_TWOLINK
--功能:同步表,條件爲主鍵和惟一約束進行匹配,源數據庫來自遠程連接,目標數據庫也來自遠程連接
--參數:見下方說明
--調用:
/*
DECLARE pMSG NUMBER(2);
BEGIN
  PKG_MERGE.MERGE_TWOLINK('DLIN11','DLINK2','USR_ROLETAB',1,pMSG);
  DBMS_OUTPUT.PUT_LINE('同步消息:'||pMSG);
END;
*/
--日期:2014-10-30
(
	pSOURCELINK		IN	VARCHAR2,				--連接源數據庫的連接名
	pTARGETLINK		IN	VARCHAR2,				--連接目的數據庫的連接名
	pTBLIST 		  IN 	VARCHAR2:=NULL,	--表示目標表,能夠爲一張或多張表,多個表以','分隔
	pMODE				  IN	NUMBER:=1,			--若是記錄在目的數據庫上存在而在源數據庫表中不存在,處理方式:1-刪除目的數據庫中的記錄、其餘-不予操做
  pMSG          OUT NUMBER          --返回消息,1-同步成功,-1:失敗,-2:無主鍵和惟一約束
)
AS
	pSINGLETBNAME	VARCHAR2(50);			--保存當前表名
  pCLONETBNAME  VARCHAR2(50);			--中間表名稱
	pTBSQL		    VARCHAR2(4000);	  --表記錄查詢SQL語句
	pTBCURSOR		  SYS_REFCURSOR;	  --表記錄遊標
	pCONSNAME			VARCHAR2(100);		--主鍵或者惟一約束名稱
	pCOLNAME			VARCHAR2(100);		--列名
	pWHERE				VARCHAR2(4000);   --拼接MERGER同步源表與目標表的匹配WHERE條件
	pUPDATECOL 		VARCHAR2(4000);   --拼接MERGER同步源表與目標表的修改列
	pINSERTCOL 		VARCHAR2(4000);   --拼接MERGER同步源表與目標表的添加列
	pSQL 					VARCHAR2(4000);		--拼接MERGER同步的完整SQL語句
  PROCEDURE MERGE_NOCONSTRA
  AS
    pSELTXT VARCHAR2(4000);
  BEGIN    
    --條件爲主鍵、全部惟一約束、全部惟一索引共同匹配,防止出現違反惟一約束或主鍵衝突
--    SELECT DISTINCT LISTAGG('('||WHERELIST||')',' OR ') WITHIN GROUP(ORDER BY INDEX_NAME) OVER() INTO pWHERE FROM(
--      SELECT DISTINCT A.INDEX_NAME,
--        LISTAGG('S."'||B.COLUMN_NAME||'"=T."'||B.COLUMN_NAME||'"',' AND ')
--          WITHIN GROUP(ORDER BY B.COLUMN_POSITION) OVER(PARTITION BY A.INDEX_NAME) AS WHERELIST  FROM SYS.USER_INDEXES A
--        JOIN SYS.USER_IND_COLUMNS B ON (A.TABLE_NAME=B.TABLE_NAME AND A.INDEX_NAME=B.INDEX_NAME)
--        WHERE A.TABLE_NAME=pSINGLETBNAME AND A.TABLE_TYPE='TABLE' AND A.UNIQUENESS='UNIQUE'); 
    --2014-08-02修改:當主鍵字段已存在,惟一約束字段值不一樣時不會進行同步,故去掉惟一約束、惟一索引條件    
    pSELTXT:='SELECT DISTINCT LISTAGG(''S."''||B.COLUMN_NAME||''"=T."''||B.COLUMN_NAME||''"'','' AND '')'||CHR(10)||
             '  WITHIN GROUP(ORDER BY B.POSITION) OVER(PARTITION BY A.INDEX_NAME) FROM SYS.USER_CONSTRAINTS@'||pTARGETLINK||' A '||CHR(10)||
             '  JOIN SYS.USER_CONS_COLUMNS@'||pTARGETLINK||' B ON (A.owner=b.owner AND A.table_name=b.table_name AND A.constraint_name=B.constraint_name)'||CHR(10)||
             '    WHERE A.TABLE_NAME='''||pSINGLETBNAME||''' AND A.CONSTRAINT_TYPE=''P''';
    EXECUTE IMMEDIATE pSELTXT INTO pWHERE;
    EXCEPTION
    WHEN NO_DATA_FOUND THEN
      pMSG:=1;              --無主鍵和惟一約束則直接添加,2014-08-02修改成去掉惟一約束斷定
      pSQL:='INSERT INTO '||pSINGLETBNAME||'@'||pTARGETLINK||' SELECT * FROM '||pSINGLETBNAME||'@'||pSOURCELINK;
      EXECUTE IMMEDIATE pSQL;
      --SYS.DBMS_OUTPUT.PUT_LINE('同步無主鍵和惟一約束的表'||pSINGLETBNAME||'數據成功!');
    WHEN OTHERS THEN
      pMSG:=-1;             --同步失敗
      SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'同步無主鍵和惟一約束的表'||pSINGLETBNAME||'數據異常:' ||SQLERRM);
  END;
BEGIN
 	FOR X IN
	(
		SELECT LEVEL AS RN,REGEXP_SUBSTR(UPPER(pTBLIST),'[^,]+',1,LEVEL) AS TBNAME FROM DUAL
			CONNECT BY LEVEL<LENGTH(pTBLIST)-LENGTH(REPLACE(pTBLIST,','))+2
	)
	LOOP
		pSINGLETBNAME:=X.TBNAME;
		pWHERE:='';
		pUPDATECOL:='';
		pINSERTCOL:='';
    MERGE_NOCONSTRA;   --判斷表中是否有主鍵、惟一約束,若是不存在則直接添加表數據,不然跳過直接進行下一步操做,2014-08-02修改成去掉惟一約束斷定
    IF pWHERE IS NOT NULL THEN
    pTBSQL:='SELECT DISTINCT * FROM ( SELECT TA.COLUMN_NAME,TB.COLUMN_NAME AS CONS_COL FROM SYS.USER_TAB_COLUMNS TA'||CHR(10)||
            ' LEFT JOIN('||CHR(10)||
            '   SELECT A.TABLE_NAME,B.COLUMN_NAME FROM SYS.USER_CONSTRAINTS@'||pTARGETLINK||' A '||CHR(10)||
            '     JOIN SYS.USER_CONS_COLUMNS@'||pTARGETLINK||' B ON (A.owner=b.owner AND A.table_name=b.table_name AND A.constraint_name=B.constraint_name)'||CHR(10)||
            '     WHERE A.TABLE_NAME='''||pSINGLETBNAME||''' AND A.CONSTRAINT_TYPE=''P'''||CHR(10)||
            ' ) TB ON (TA.TABLE_NAME=TB.TABLE_NAME AND TA.COLUMN_NAME=TB.COLUMN_NAME)'||CHR(10)||
            ' WHERE TA.TABLE_NAME='''||pSINGLETBNAME||''' ORDER BY TA.COLUMN_ID)';
      OPEN pTBCURSOR FOR pTBSQL;
      LOOP
        FETCH pTBCURSOR INTO pCOLNAME,pCONSNAME;
				EXIT WHEN pTBCURSOR%NOTFOUND; 
        IF pCONSNAME IS NULL THEN
          pUPDATECOL:=pUPDATECOL||pCOLNAME||'=T.'||pCOLNAME||',';
        END IF;
        pINSERTCOL:=pINSERTCOL||','||pCOLNAME;
      END LOOP;
      pUPDATECOL:=RTRIM(pUPDATECOL,',');
      pSQL:='MERGE INTO (SELECT * FROM '||pSINGLETBNAME||'@'||pTARGETLINK||') S'||CHR(10)||
            'USING (SELECT * FROM '||pSINGLETBNAME||'@'||pSOURCELINK||') T'||CHR(10)||
            'ON('||pWHERE||')'||CHR(10);    
      IF pUPDATECOL IS NOT NULL THEN
      pSQL:=pSQL||'  WHEN MATCHED THEN'||CHR(10)||
        '    UPDATE SET '||RTRIM(pUPDATECOL,',')||CHR(10);
      END IF;
      pSQL:=pSQL||'  WHEN NOT MATCHED THEN'||CHR(10)||
        '    INSERT ('||LTRIM(REPLACE(pINSERTCOL,',',',S.'),',')||')'||' VALUES('||LTRIM(REPLACE(pINSERTCOL,',',',T.'),',')||')';
      EXECUTE IMMEDIATE pSQL;
      --SYS.DBMS_OUTPUT.PUT_LINE(pSQL);
      SYS.DBMS_OUTPUT.PUT_LINE('同步'||pSINGLETBNAME||'表數據成功!');
      IF pMODE=1 THEN 		  --若是記錄在目的數據庫上存在而在源數據庫表中不存在,刪除目的數據庫中的記錄,採用傳輸數據到中間表的方式進行優化處理
        pCLONETBNAME:='TMP_'||pSINGLETBNAME;            
        PKG_DBMANAGE.CLONE_TEMP_TB(pSINGLETBNAME,pCLONETBNAME);                                               --克隆生成中間臨時表,該臨時表保存在當前操做的數據
        EXECUTE IMMEDIATE 'INSERT INTO '||pCLONETBNAME||' SELECT * FROM '||pSINGLETBNAME||'@'||pSOURCELINK;   --轉儲數據到中間表中
        pSQL:='DELETE FROM '||pSINGLETBNAME||'@'||pTARGETLINK||' T WHERE NOT EXISTS(SELECT * FROM '||pCLONETBNAME||' S WHERE '||pWHERE||')';--刪除在目標表中存在而在中間表不存在的數據
        EXECUTE IMMEDIATE pSQL;
        --DBMS_OUTPUT.PUT_LINE(pSQL);
      END IF;
    END IF;
  END LOOP;
  pMSG:=1;                --同步成功
  COMMIT;
  EXCEPTION
	WHEN OTHERS THEN
    pMSG:=-1;             --同步失敗
		SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'同步表數據異常:' ||SQLERRM);
END;
 
PROCEDURE MERGE_INTERSECT
--功能:同步表數據(支持低版本數據源往同版本或高版本目標庫同步,同時也支持高版本數據源往低版本目標庫同步),只同步具備相同列名稱和類型的表列,
--    同時目標庫中不能存在不爲空的新列,以保證能夠兼容添加數據到目標庫中,不然可能同步出錯)
--參數:見下方說明
--調用:EXEC PKG_MERGE.MERGE_INTERSECT('DBLINK',NULL)
--日期:2013-03-28
(
	pLINKNAME 	IN VARCHAR2, 				--連接名
	pTABLENAME 	IN VARCHAR2:=NULL,	--源表,能夠爲一張或多張表,多個表以','分隔,爲空則選擇結構類型一致的全部表
	pMODE 			IN NUMBER:=1 				--匹配模式
)
--匹配模式:
--1-只比較基礎數據類型,如VARCHAR二、NUMBER、DATE等,
--2-在1基礎上比較數據類型的長度和精度,
--3-在2基礎上比較列可否爲空
AS
	pUSER     VARCHAR2(200):=USER; 
	pSQLTEXT  VARCHAR2(4000);
	TYPE pOBJTYPE IS RECORD
	(
		TABLENAME SYS.DBA_TABLES.TABLE_NAME%TYPE,
		COLLIST VARCHAR2(4000)
	) ;
	TYPE pOBJTYPELIST IS TABLE OF pOBJTYPE INDEX BY PLS_INTEGER;
	pTABCOLLIST pOBJTYPELIST;
	pINSERTTEXT VARCHAR2(4000) ;
	pRFECUR 		SYS_REFCURSOR;
	pSINGLETBNAME SYS.DBA_TABLES.TABLE_NAME%TYPE;
BEGIN
	PKG_ANALYZE.GET_COMPARETEXT(1,pLINKNAME,pTABLENAME,pMODE,pSQLTEXT);	--建議使用非嚴格模式進行匹配
	pSQLTEXT:='SELECT DISTINCT TABLENAME,LISTAGG(''"''||COLUMNNAME||''"'','','')'|| 
		'WITHIN GROUP(ORDER BY 1) OVER(PARTITION BY TABLENAME) AS COLLIST FROM ('||pSQLTEXT||')';
	OPEN pRFECUR FOR pSQLTEXT;
	FETCH pRFECUR BULK COLLECT INTO pTABCOLLIST;
	FOR L_ROW IN pTABCOLLIST.FIRST..pTABCOLLIST.LAST
	LOOP
		pSINGLETBNAME:=pTABCOLLIST(L_ROW).TABLENAME;
		pINSERTTEXT:='INSERT INTO '||pSINGLETBNAME||'('||pTABCOLLIST(L_ROW).COLLIST||') SELECT '||pTABCOLLIST(L_ROW).COLLIST||
		' FROM '||pSINGLETBNAME||'@'||pLINKNAME;
		PKG_DBMANAGE.DELETE_TABLE(pUSER,pSINGLETBNAME) ; 									--清空本地數據庫表記錄
		EXECUTE IMMEDIATE pINSERTTEXT;                   									--同步連接庫表數據到本地庫表中
		SYS.DBMS_OUTPUT.PUT_LINE('同步表:'||pSINGLETBNAME||'數據成功!') ;
	END LOOP;
	CLOSE pRFECUR;
	EXCEPTION
	WHEN OTHERS THEN
		SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'同步表數據出錯:'||SQLERRM||',發生在表:'||pSINGLETBNAME) ;
		ROLLBACK;
END;

PROCEDURE MERGE_FROM_DB
--功能:同步本地數據庫表,根據列名相同原則來匹配,pTABLENAME爲NULL則同步全部表的記錄,不爲NULL則同步一個或多個表的記錄,多個表以','分隔
--    注意:只能從低版本數據源往同版本或高版本目標庫同步(即目標庫中的表同名列數、類型大於或等於源表列數,同時目標庫中不能存在不爲空的新列,
--    以保證能夠兼容添加數據到目標庫中,不然則可能同步出錯)
--參數:見下方說明
--調用:EXECUTE PKG_MERGE.MERGE_FROM_DB('DBLINK');
--日期:2013-03-28
(
	pLINKNAME			IN VARCHAR2,					--連接名
	pTABLENAME 		IN VARCHAR2:=NULL,		--本地數據庫同步表,多個表以','分隔
	pTABLEEXIXTS 	IN VARCHAR2:='DELETE' --本地表存在的處理方式
)
--本地表存在的處理方式:
--'RECOVER'-全部表全覆蓋、
--'DROP'-先刪除本地表再建立新表,表結構和數據與連接庫表保持一致、
--'DELETE'-直接刪除表數據再添加、'APPEND'-追加
AS
	pCOLLIST  		VARCHAR2(32767);
	pCOUNT1 			PLS_INTEGER;
	pCOUNT2 			PLS_INTEGER; 
	pUSER 				VARCHAR2(200):=USER;
	pSQLTEXT 			VARCHAR2(2000);
	pRFECUR				SYS_REFCURSOR;
	pSINGLETBNAME SYS.DBA_TABLES.TABLE_NAME%TYPE;
BEGIN 
	IF pTABLEEXIXTS='RECOVER' THEN           														--模式選擇爲全覆蓋
		PKG_DBMANAGE.DROP_ALL_OBJECT(pUSER,8);			                      --刪除全部表
	END IF;
	pSQLTEXT:='SELECT TABLE_NAME FROM SYS.DBA_TABLES@'||pLINKNAME||' TA WHERE (INSTR('',''||'''||
		pTABLENAME||'''||'','','',''||TABLE_NAME||'','',1)>0 OR '''||pTABLENAME||
		''' IS NULL) AND TA.TEMPORARY=''N'' AND OWNER='''||pUSER||''''; 	--查詢過濾連接表
	OPEN pRFECUR FOR pSQLTEXT; 																					--臨時表不作處理
  LOOP
		FETCH pRFECUR INTO pSINGLETBNAME; 
		EXIT WHEN pRFECUR%NOTFOUND;
		EXECUTE IMMEDIATE 'SELECT COUNT(1) FROM '||pSINGLETBNAME||'@'||pLINKNAME INTO pCOUNT1;		
		EXECUTE IMMEDIATE 'SELECT LISTAGG(''"''||COLUMN_NAME||''"'','','') WITHIN GROUP(ORDER BY COLUMN_ID) FROM SYS.DBA_TAB_COLUMNS@'||
			pLINKNAME||'WHERE OWNER=USER AND TABLE_NAME='''||pSINGLETBNAME||''' AND DATA_TYPE<>''LONG''' INTO pCOLLIST;	--'LONG'類型沒法進行處理				
		IF pCOUNT1>0 THEN																									--連接數據庫表數據不爲空
			EXECUTE IMMEDIATE 'SELECT COUNT(TABLE_NAME) FROM SYS.USER_TABLES WHERE TABLE_NAME=:v1' INTO pCOUNT2 using pSINGLETBNAME;	
			IF pCOUNT2=1 THEN                                             	--本地表存在
				IF UPPER(pTABLEEXIXTS)='DROP' THEN                          	--模式選擇刪除本地表再建立新表
					EXECUTE IMMEDIATE 'DROP TABLE '||pSINGLETBNAME||' CASCADE CONSTRAINTS';	
				ELSIF UPPER(pTABLEEXIXTS)='DELETE' THEN                     	--模式選擇直接刪除表數據再添加
					PKG_DBMANAGE.DELETE_TABLE(pUSER,pSINGLETBNAME); 						--清空本地數據庫表記錄
				END IF;				
			END IF;
			IF pCOUNT2=0 OR UPPER(pTABLEEXIXTS) IN ('DROP','RECOVER') THEN	--本地數據庫表不存在	或者模式選擇刪除本地表再建立新表,此種方式不能創建表約束和索引	
				EXECUTE IMMEDIATE 'CREATE TABLE '||pSINGLETBNAME||' AS SELECT '||pCOLLIST||' FROM '||pSINGLETBNAME||'@'||pLINKNAME;
			END IF;			
			IF UPPER(pTABLEEXIXTS) NOT IN ('DROP','REVOVER') THEN           --添加連接數據庫表數據到本地表中
				EXECUTE IMMEDIATE 'INSERT INTO '||pSINGLETBNAME||'('||pCOLLIST||') SELECT '||pCOLLIST||' FROM '||pSINGLETBNAME||'@'||pLINKNAME; 	
			END IF;
		END IF;
	END LOOP;
	CLOSE pRFECUR;
	COMMIT;	
	IF UPPER(pTABLEEXIXTS) IN ('DROP','REVOVER') THEN
		PKG_DBMANAGE.RECOMPILE_ALL_PROJECT(pUSER); 												--表被刪除,須要從新編譯全部結構
	END IF;
	EXCEPTION 
	WHEN OTHERS THEN 
		SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'同步本地表出錯:'||SQLERRM||',發生在表:'||pSINGLETBNAME);
		ROLLBACK;
END;

PROCEDURE MERGE_TO_DB
--功能:同步連接數據庫表,根據列名相同原則來匹配,pTABLENAME爲NULL則同步全部表的記錄,不爲NULL則同步一個或多個表的記錄,多個表以','分隔
--    注意:只能從低版本數據源往同版本或高版本目標庫同步(即目標庫中的表同名列數、類型大於或等於源表列數,同時目標庫中不能存在不爲空的新列,
--    以保證能夠兼容添加數據到目標庫中,不然則可能同步出錯)
--參數:見下方說明
--調用:EXECUTE PKG_MERGE.MERGE_TO_DB('DBLINK');
--日期:2013-03-28
(
	pLINKNAME			IN VARCHAR2,						--連接名
	pTABLENAME 		IN VARCHAR2:=NULL,			--連接數據庫同步表,多個表以','分隔	
	pTABLEEXIXTS 	IN VARCHAR2:='DELETE'   --連接表存在的處理方式:'DELETE'-直接刪除表數據再添加、'APPEND'-追加
)
AS
	pSINGLETBNAME VARCHAR2(100);
	pCOLLIST  		VARCHAR2(32767);
	pCOUNT1 			PLS_INTEGER;
	pCOUNT2 			PLS_INTEGER; 
	pUSER 				VARCHAR2(200):=USER;
BEGIN 
	FOR X IN
	(
		SELECT TABLE_NAME	FROM SYS.DBA_TABLES
			WHERE OWNER=pUSER AND(INSTR(','||pTABLENAME||',',','||TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL) AND TEMPORARY='N'
	)	
	LOOP
		pSINGLETBNAME:=X.TABLE_NAME;
		EXECUTE IMMEDIATE 'SELECT COUNT(1) FROM '||pUSER||'.'||pSINGLETBNAME INTO pCOUNT1;
		SELECT  LISTAGG('"'||COLUMN_NAME||'"',',') WITHIN GROUP(ORDER BY COLUMN_ID) INTO pCOLLIST	FROM SYS.DBA_TAB_COLUMNS
			WHERE OWNER=pUSER AND TABLE_NAME=pSINGLETBNAME AND DATA_TYPE<>'LONG';
		IF pCOUNT1>0 THEN 																										--本地數據庫表數據不爲空
			EXECUTE IMMEDIATE 'SELECT COUNT(TABLE_NAME) FROM SYS.USER_TABLES@'||pLINKNAME||' WHERE TABLE_NAME=:v1' INTO pCOUNT2 USING	pSINGLETBNAME;
			IF pCOUNT2=1 THEN
				IF UPPER(pTABLEEXIXTS)='DELETE' THEN
					EXECUTE IMMEDIATE 'DELETE FROM '||X.TABLE_NAME||'@'||pLINKNAME; --先清空連接數據庫表記錄在進行添加
				END IF;
				EXECUTE IMMEDIATE 'INSERT INTO '||pSINGLETBNAME||'@'||pLINKNAME||'('||pCOLLIST||') SELECT '||pCOLLIST||' FROM '||pUSER||'.'||pSINGLETBNAME;
			END IF;
		END IF;
	END LOOP;
	COMMIT;
	EXCEPTION
	WHEN OTHERS THEN
		SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'同步遠程表出錯:'||SQLERRM||',發生在表:'||pSINGLETBNAME) ;
		ROLLBACK;
END;
END;
/
create or replace PACKAGE PKG_GET_INSERT
AS
--功能:獲取用戶下表記錄的INSERT語句的的查詢SQL語句
PROCEDURE GET_INSERT_SQL(
	DBUSER 			  IN 	VARCHAR2:=USER, --用戶名
	pTBLIST 		  IN 	VARCHAR2:=NULL,	--表和where條件的鏈接,多個鏈接用','分隔,注意:where條件中不能有','不然將出現分割錯誤,表名按照在字符串中前後位置排序
	pMERGER			  IN	NUMBER:=0, 			--Insert語句的操做模式
	pENDSTR			  IN	VARCHAR2:=';',	--每條Inser語句的結束符,默認以';'結束,這樣能夠進行批量執行
  pDELQLTEXT    OUT CLOB,           --獲取刪除表記錄的SQL語句字符串
	pINSERSQLTEXT OUT CLOB						--獲取添加表記錄的SQL語句字符串
);

--功能:獲取用戶下遠程連接表記錄的INSERT語句的的查詢SQL語句
PROCEDURE GET_REMOTEINSERT_SQL(
	pLINKNAME		IN	VARCHAR2,				--遠程連接名稱
	DBUSER 			IN 	VARCHAR2:=NULL, --遠程連接用戶名,爲空則採用連接用戶名,默認爲空
	pTBLIST 		IN 	VARCHAR2:=NULL,	--表和where條件的鏈接,多個鏈接用','分隔,注意:where條件中不能有','不然將出現分割錯誤,表名按照在字符串中前後位置排序
	pMERGER			IN	NUMBER:=0, 			--Insert語句的操做模式
	pENDSTR			IN	VARCHAR2:=';',	--每條Inser語句的結束符,默認以';'結束,這樣能夠進行批量執行
	pSQLTEXT 		OUT CLOB						--SQL語句字符串
);

--功能:獲取用戶下表記錄的INSERT語句
PROCEDURE GET_ALL_INSERT(
	DBUSER 			IN 	VARCHAR2:=USER, --用戶名
	pTBLIST 		IN 	VARCHAR2:=NULL,	--表和where條件的鏈接,多個鏈接用','分隔,注意:where條件中不能有','不然將出現分割錯誤,表名按照在字符串中前後位置排序
	pMERGER			IN	NUMBER:=0, 			--Insert語句的操做模式
	pENDSTR			IN	VARCHAR2:=';',	--每條Inser語句的結束符,默認以';'結束,這樣能夠進行批量執行
	pCURSOR 		OUT SYS_REFCURSOR
);

--功能:獲取用戶下遠程連接表記錄的INSERT語句
PROCEDURE GET_ALL_REMOTEINSERT(
	pLINKNAME		IN	VARCHAR2,				--遠程連接名稱
	DBUSER 			IN 	VARCHAR2:=USER, --用戶名
	pTBLIST 		IN 	VARCHAR2:=NULL,	--表和where條件的鏈接,多個鏈接用','分隔,注意:where條件中不能有','不然將出現分割錯誤,表名按照在字符串中前後位置排序
	pMERGER			IN	NUMBER:=0, 			--Insert語句的操做模式
	pENDSTR			IN	VARCHAR2:=';',	--每條Inser語句的結束符,默認以';'結束,這樣能夠進行批量執行
	pCURSOR 		OUT SYS_REFCURSOR
);

--功能:保存用戶下表記錄的INSERT語句到文件中
PROCEDURE SAVE_ALL_INSERT(
	pLINKNAME		IN	VARCHAR2:=NULL,						--遠程連接名稱,爲空則使用本地表,默認採用本地表
	DBUSER 			IN 	VARCHAR2:=USER, 					--用戶名
	pTBLIST 		IN 	VARCHAR2:=NULL,						--表和where條件的鏈接
	pMERGER			IN	NUMBER:=0, 								--Insert語句的操做模式
	DIR 				IN  VARCHAR2:='DATA_PUMP_DIR',--目錄名稱(若是不填,則使用當前數據庫目錄)
  FILENAME 		IN  VARCHAR:=NULL							--保存文件名稱
);

--功能:獲取表數據進行Loader格式輸出
PROCEDURE GET_LOADER_SQL(
	DBUSER 			IN 	VARCHAR2:=USER, --用戶名
	pTBNAME 		IN 	VARCHAR2:=NULL,	--表和where條件的鏈接
  pSEP        IN  VARCHAR2:='|',  --分隔符
	pSQLTEXT 		OUT CLOB						--SQL語句字符串
);
END;
/
create or replace PACKAGE BODY PKG_GET_INSERT
AS
PROCEDURE GET_INSERT_SQL
--功能:獲取用戶下表記錄的INSERT語句的的查詢SQL語句
--參數:
--調用:
/*
DECLARE
  pSQLTEXT1 CLOB;
  pSQLTEXT2 CLOB;
BEGIN
  PKG_GET_INSERT.GET_INSERT_SQL('DKGLL','DEV_INFOEXTAB',0,';',pSQLTEXT,pSQLTEXT2);
	dbms_output.put_line(pSQLTEXT2);
END;
*/
--日期:2013-04-11
(
	DBUSER 			  IN 	VARCHAR2:=USER, --用戶名
	pTBLIST 		  IN 	VARCHAR2:=NULL,	--表和where條件的鏈接,多個鏈接用','分隔,注意:where條件中不能有','不然將出現分割錯誤,表名按照在字符串中前後位置排序
	pMERGER			  IN	NUMBER:=0, 			--Insert語句的操做模式
	pENDSTR			  IN	VARCHAR2:=';',	--每條Inser語句的結束符,默認以';'結束,這樣能夠進行批量執行
  pDELQLTEXT    OUT CLOB,           --獲取刪除表記錄的SQL語句字符串
	pINSERSQLTEXT OUT CLOB						--獲取添加表記錄的SQL語句字符串
)
------------------------------------------------------------------------------------------------------------------
--Insert語句的操做模式(pMERGER參數)值詳細說明:
--0:默認值,非嚴格模式.不判斷Insert語句的每一行在表中是否存在-Insert Into TableName(Col1,Col2,Col3..) Values(Value1,Value2,Value3..)
--1:中間模式.若是表中有主鍵或者惟一約束不判斷Insert語句的每一行在表中是否存在,這樣在執行Insert記錄的時候可能會報主鍵衝突或者違反惟一約束的錯誤,但會添加失敗,格式同0
--  若是表中既無主鍵也無惟一約束,則要進行判斷Insert語句的每一行在表中是否存在(經過每一列字段的值進行判斷),拼接格式以下:
--  Insert Into TableName(Col1,Col2,Col3..) Select Value1,Value2,Value3.. From Dual
--		Where Not Exists(
--			Select * From TableName Where Col1=Value1 And Col2=Value2 And Col3=Value3 And..
--		)
--其餘值:嚴格模式.不管表中是否存在主鍵或者惟一約束,均需判斷Insert語句的每一行在表中是否存在,這樣在執行Insert記錄的時候就不會報主鍵衝突或者違反惟一約束的錯誤,格式如上
------------------------------------------------------------------------------------------------------------------
--獲取INSERT語句的的查詢SQL語句格式以下:
--說明:經過UNION ALL鏈接多個表的查詢;LONG列和LOB列沒法處理被過濾掉;列拼接長度大於4000字節時會報鏈接字符串長度過長的錯誤,經過TO_CLOB函數強制轉換成CLOB類型
--SELECT 'TABLENAME' AS TABLENAME,
--	TO_CLOB('INSERT INTO TABLENAME("COLUMN1","COLUMN2","COLUMN3") SELECT ')||
--	CASE WHEN "COLUMN1" IS NULL THEN TO_CLOB('NULL') ELSE TO_CLOB('''')||"COLUMN1"||'''' END||','||
--	CASE WHEN "COLUMN2" IS NULL THEN TO_CLOB('NULL') ELSE TO_CLOB('''')||"COLUMN2"||'''' END||','||
--	CASE WHEN "COLUMN3" IS NULL THEN 'NULL' ELSE 'TO_DATE('''||TO_CHAR("COLUMN3",'YYYY-MM-DD HH24:MI:SS')||''',''YYYY-MM-DD HH24:MI:SS'')' END||'
--  FROM DUAL
--		WHERE NOT EXISTS(
--			SELECT * FROM TABLENAME WHERE	"COLUMN1"'||
--			CASE WHEN "COLUMN1" IS NULL THEN TO_CLOB('IS NULL') ELSE TO_CLOB('=''')||"COLUMN1"||'''' END||' AND "COLUMN1"'||
--			CASE WHEN "COLUMN2" IS NULL THEN TO_CLOB('IS NULL') ELSE TO_CLOB('=''')||"COLUMN2"||'''' END||' AND "COLUMN2"'||
--			CASE WHEN "COLUMN3" IS NULL THEN 'IS NULL' ELSE '=TO_DATE('''||TO_CHAR("COLUMN3",'YYYY-MM-DD HH24:MI:SS')||''',''YYYY-MM-DD HH24:MI:SS'')' END||'
--		);' AS CONTEN FROM TABLENAME
-- UNION ALL
-- SELECT ...
------------------------------------------------------------------------------------------------------------------
AS
	pUSER 			VARCHAR2(200):=COALESCE(UPPER(DBUSER),USER);
	SINGLECOL		VARCHAR2(4000);	      --單列值
	COL 				CLOB;									--Insert列名
	VAL 				CLOB;                 --Insert列值
	CONSCOL			CLOB;                 --重複條件判斷列值
	CONSTR			CLOB;                 --重複條件判斷拼接字符串,格式如Col1=Value1 And Col2=Value2 And Col3=Value3 And..
	SINGLETXT1		CLOB;								--保存單表的完整Delete語句
	SINGLETXT2		CLOB;								--保存單表的完整Inser語句
	REPLACENAME VARCHAR2(30);
	pSINGLENAME VARCHAR2(30);
BEGIN
	FOR X IN
	(
		SELECT DISTINCT MIN(RN) OVER(PARTITION BY TBNAME) AS MINRN,TBNAME,WHERESTR,HASCONSTRAINT FROM(
			SELECT RN,TBNAME,WHERESTR,CASE WHEN TC.TABLE_NAME IS NULL THEN 'NO' ELSE 'YES' END AS HASCONSTRAINT FROM(
				SELECT RN,DECODE(ISWHERE,0,TBNAME,SUBSTR(TBNAME,1,INSTR(TBNAME,'WHERE')-2)) AS TBNAME,
					DECODE(ISWHERE,0,'',SUBSTR(TBNAME,INSTR(TBNAME,'WHERE'))) AS WHERESTR
					FROM
					(
						SELECT RN,TBNAME,INSTR(TBNAME,'WHERE') AS ISWHERE
							FROM
								(
									SELECT LEVEL AS RN,REGEXP_SUBSTR(UPPER(pTBLIST),'[^,]+',1,LEVEL) AS TBNAME
										FROM DUAL
											CONNECT BY LEVEL<LENGTH(pTBLIST)-LENGTH(REPLACE(pTBLIST,','))+2
								)
							UNION
							SELECT 0 AS RN,TABLE_NAME AS TBNAME,INSTR(TABLE_NAME,'WHERE') AS ISWHERE
								FROM SYS.DBA_TABLES
								WHERE OWNER=pUSER AND pTBLIST IS NULL AND TEMPORARY='N'
					)
			) TB LEFT JOIN SYS.DBA_CONSTRAINTS TC ON (TB.TBNAME=TC.TABLE_NAME AND TC.OWNER=pUSER AND TC.CONSTRAINT_TYPE IN('P','U'))
			WHERE TBNAME IS NOT NULL
		) ORDER BY MINRN		--表名按照在字符串中前後位置進行排序,注意:若是表名在字符串中重複出現,若where條件相同則只取該表一次,若條件不一樣則仍然讀取屢次
	)
	LOOP
		BEGIN
			pSINGLENAME:=X.TBNAME;
			COL:='SELECT '''||pSINGLENAME||''' AS TABLENAME,TO_CLOB(''INSERT INTO '||pSINGLENAME||'(';
			VAL:='';          --每一次循環清空上一次的值
			CONSTR:='';
			FOR Y IN
			(
				SELECT B.COLUMN_NAME,B.DATA_TYPE
					FROM SYS.DBA_TABLES A
					JOIN SYS.DBA_TAB_COLUMNS B ON(A.OWNER=B.OWNER AND A.TABLE_NAME=B.TABLE_NAME)
					WHERE A.OWNER=pUSER AND A.TABLE_NAME=pSINGLENAME AND B.DATA_TYPE NOT LIKE '%LOB' AND B.DATA_TYPE NOT LIKE '%LONG'
					ORDER BY B.COLUMN_ID
			)
			LOOP
				SINGLECOL:=CHR(10)||'CASE WHEN "'||Y.COLUMN_NAME||'" IS NULL THEN ';
				------------------------------------------------------------------------------------------------------------
				--此部分解決當字段長度大於等於4000時報字符串鏈接過長的錯誤,若是是非數字和日期類型(此類型長度較小)則統一強制轉換成CLOB類型
				IF Y.DATA_TYPE NOT IN('NUMBER','DATE') THEN
					CONSCOL:=SINGLECOL||'TO_CLOB('' IS NULL'') ELSE TO_CLOB(''=';
					VAL:=VAL||SINGLECOL||'TO_CLOB(''NULL'') ELSE TO_CLOB(';
				ELSE
					CONSCOL:=SINGLECOL||''' IS NULL'' ELSE ''=';
					VAL:=VAL||SINGLECOL||'''NULL'' ELSE ';
				------------------------------------------------------------------------------------------------------------
				END IF;
				IF Y.DATA_TYPE='NUMBER' THEN 								--數值類型不帶引號
					SINGLECOL:='''||"'||Y.COLUMN_NAME||'"||''''' ;
					CONSCOL:=CONSCOL||SINGLECOL;
					VAL:=VAL||''''||SINGLECOL;
				ELSIF Y.DATA_TYPE='DATE' THEN 							--日期類型進行轉換
					SINGLECOL:='TO_DATE(''''''||TO_CHAR("'||Y.COLUMN_NAME||'",''YYYY-MM-DD HH24:MI:SS'')||'''''',''''YYYY-MM-DD HH24:MI:SS'''')''';
					CONSCOL:=CONSCOL||SINGLECOL;
					VAL:=VAL||''''||SINGLECOL;
				ELSE 																				--其餘類型帶引號
					SINGLECOL:=''''''')||"'||Y.COLUMN_NAME||'"||''''''''';
					CONSCOL:=CONSCOL||SINGLECOL;
					VAL:=VAL||''''||SINGLECOL;
				END IF;
				VAL:=VAL||' END||'',''||';
				SELECT '"'||REPLACE(Y.COLUMN_NAME,'''','''''')||'"' INTO REPLACENAME FROM DUAL;
				COL:=COL||REPLACENAME||',';
				CONSTR:=CONSTR||REPLACENAME||'''||'||CONSCOL||' END||'' AND ';
			END LOOP;
			IF VAL IS NOT NULL THEN 		--若是字段列表爲空(由於clob字段不給與處理),則不處理該表
				IF (pMERGER=1 AND X.HASCONSTRAINT='NO') OR pMERGER NOT IN(0,1) THEN	--判斷記錄的每一行在表中是否存在
					SELECT SUBSTR(COL,1,LENGTH(COL)-1) ||') SELECT '')||'|| SUBSTR(VAL,1,LENGTH(VAL)-4) ||' FROM DUAL'||CHR(10)||
						'	WHERE NOT EXISTS('||CHR(10)||
						'		SELECT * FROM '||pSINGLENAME||' WHERE	'||SUBSTR(CONSTR,1,LENGTH(CONSTR)-4)||CHR(10)||
						'	)'||pENDSTR||''' AS CONTEN FROM '|| pSINGLENAME||' '||X.WHERESTR
						INTO SINGLETXT2 FROM DUAL;
				ELSE											--有主見或者惟一約束或者容許添加劇復記錄,則直接爲通常的Insert Into格式
					SELECT SUBSTR(COL,1,LENGTH(COL)-1) ||') VALUES('')||'|| SUBSTR(VAL,1,LENGTH(VAL)-4)||
						')'||pENDSTR||''' AS CONTEN FROM '|| pSINGLENAME||' '||X.WHERESTR
						INTO SINGLETXT2 FROM DUAL;
				END IF;
        SINGLETXT1:='SELECT '''||pSINGLENAME||''' AS TABLENAME,''DELETE FROM '||pSINGLENAME||' WHERE '||SUBSTR(CONSTR,1,LENGTH(CONSTR)-4)||''' AS CONTEN FROM '||pSINGLENAME;
        --獲取刪除表記錄的SQL語句字符串
				IF pDELQLTEXT IS NULL THEN
					pDELQLTEXT:=SINGLETXT1;											--單表的Delete查詢語句
				ELSE																				  --經過Union All方式來拼接全部的查詢語句
					pDELQLTEXT:=pDELQLTEXT||' UNION ALL '||SINGLETXT1;
				END IF;
        --獲取添加表記錄的SQL語句字符串
				IF pINSERSQLTEXT IS NULL THEN
					pINSERSQLTEXT:=SINGLETXT2;									--單表的Insert查詢語句
				ELSE																				  --經過Union All方式來拼接全部的查詢語句
					pINSERSQLTEXT:=pINSERSQLTEXT||' UNION ALL '||SINGLETXT2;
				END IF;
			END IF;
		END;
	END LOOP;
	IF pINSERSQLTEXT IS NULL THEN
		pINSERSQLTEXT:='SELECT NULL AS TABLENAME,DUMMY AS CONTEN FROM DUAL WHERE 1=2';	--修正查詢動態SQL爲空報錯的bug
	END IF;
	--SYS.DBMS_OUTPUT.PUT_LINE('/*SQL語句:*/'||pSQLTEXT);
	EXCEPTION
	WHEN OTHERS THEN
		SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'導出表出錯:'||SQLERRM||',發生在表:'||pSINGLENAME);
		NULL;
END;

PROCEDURE GET_REMOTEINSERT_SQL
--功能:獲取用戶下遠程連接表記錄的INSERT語句的的查詢SQL語句
--參數:
--調用:
/*
DECLARE
  pSQLTEXT CLOB;
BEGIN
  PKG_GET_INSERT.GET_REMOTEINSERT_SQL('DATABASE_LINK1',NULL,'DEV_INFOEXTAB',0,';',pSQLTEXT);
	dbms_output.put_line(pSQLTEXT);
END;
*/
--日期:2013-04-11
(
	pLINKNAME		IN	VARCHAR2,				--遠程連接名稱
	DBUSER 			IN 	VARCHAR2:=NULL, --遠程連接用戶名,爲空則採用連接用戶名,默認爲空
	pTBLIST 		IN 	VARCHAR2:=NULL,	--表和where條件的鏈接,多個鏈接用','分隔,注意:where條件中不能有','不然將出現分割錯誤,表名按照在字符串中前後位置排序
	pMERGER			IN	NUMBER:=0, 			--Insert語句的操做模式
	pENDSTR			IN	VARCHAR2:=';',	--每條Inser語句的結束符,默認以';'結束,這樣能夠進行批量執行
	pSQLTEXT 		OUT CLOB						--SQL語句字符串
)
AS
	pUSER 			VARCHAR2(200);
	SINGLECOL		VARCHAR2(4000);	      --單列值
	COL 				CLOB;									--Insert列名
	VAL 				CLOB;                 --Insert列值
	CONSCOL			CLOB;                 --重複條件判斷列值
	CONSTR			CLOB;                 --重複條件判斷拼接字符串,格式如Col1=Value1 And Col2=Value2 And Col3=Value3 And..
	SINGLETXT		CLOB;									--保存單表的完整Inser語句
	REPLACENAME VARCHAR2(30);					--替換後的列名集合
	pMINRN			PLS_INTEGER;					--最小行號
	pSINGLENAME VARCHAR2(30);					--單表名稱
	pWHERESTR		VARCHAR2(4000);				--where條件字符串
	pHASCON			VARCHAR2(10);					--是否有約束或主鍵
	pCOLNAME		VARCHAR2(50);					--列名
	pDATATYPE		VARCHAR2(100);				--列數據類型
	pTBCURSOR		SYS_REFCURSOR;				--表記錄遊標
	pCOLCURSOR	SYS_REFCURSOR;				--列類型遊標
	pSELTBTEXT	VARCHAR2(4000);				--查詢表記錄的sql語句
	pSELCOLTEXT	VARCHAR2(4000);				--查詢列類型記錄的sql語句
BEGIN
	IF pLINKNAME IS NOT NULL THEN     --若是連接名稱不爲空
		IF DBUSER IS NULL THEN					--若是名稱爲空則採用連接用戶名
			SELECT USERNAME INTO pUSER FROM SYS.DBA_DB_LINKS WHERE DB_LINK=pLINKNAME AND OWNER=USER;
		ELSE
			pUSER:=DBUSER;
		END IF;
		pSELTBTEXT:= 'SELECT DISTINCT MIN(RN) OVER(PARTITION BY TBNAME) AS MINRN,TBNAME,WHERESTR,HASCONSTRAINT FROM(
				SELECT RN,TBNAME,WHERESTR,CASE WHEN TC.TABLE_NAME IS NULL THEN ''NO'' ELSE ''YES'' END AS HASCONSTRAINT FROM(
					SELECT RN,DECODE(ISWHERE,0,TBNAME,SUBSTR(TBNAME,1,INSTR(TBNAME,''WHERE'')-2)) AS TBNAME,
						DECODE(ISWHERE,0,'''',SUBSTR(TBNAME,INSTR(TBNAME,''WHERE''))) AS WHERESTR
						FROM
						(
							SELECT RN,TBNAME,INSTR(TBNAME,''WHERE'') AS ISWHERE
								FROM
									(
										SELECT LEVEL AS RN,REGEXP_SUBSTR(UPPER('''||pTBLIST||'''),''[^,]+'',1,LEVEL) AS TBNAME
											FROM DUAL
												CONNECT BY LEVEL<LENGTH('''||pTBLIST||''')-LENGTH(REPLACE('''||pTBLIST||''','',''))+2
									)
								UNION
								SELECT 0 AS RN,TABLE_NAME AS TBNAME,INSTR(TABLE_NAME,''WHERE'') AS ISWHERE
									FROM SYS.DBA_TABLES@'||pLINKNAME||'
									WHERE OWNER='''||pUSER||''' AND '''||pTBLIST||''' IS NULL AND TEMPORARY=''N''
						)
				) TB LEFT JOIN SYS.DBA_CONSTRAINTS@'||pLINKNAME||' TC ON (TB.TBNAME=TC.TABLE_NAME AND TC.OWNER='''||pUSER||''' AND TC.CONSTRAINT_TYPE IN(''P'',''U''))
				WHERE TBNAME IS NOT NULL
			) ORDER BY MINRN ';
		OPEN pTBCURSOR FOR pSELTBTEXT;
		LOOP
			FETCH pTBCURSOR INTO pMINRN,pSINGLENAME,pWHERESTR,pHASCON;
			EXIT WHEN pTBCURSOR%NOTFOUND;
			COL:='SELECT '''||pSINGLENAME||''' AS TABLENAME,TO_CLOB(''INSERT INTO '||pSINGLENAME||'(';
			VAL:='';          --每一次循環清空上一次的值
			CONSTR:='';
			pSELCOLTEXT:='SELECT B.COLUMN_NAME,B.DATA_TYPE
				FROM SYS.DBA_TABLES@'||pLINKNAME||' A
				JOIN SYS.DBA_TAB_COLUMNS@'||pLINKNAME||' B ON(A.OWNER=B.OWNER AND A.TABLE_NAME=B.TABLE_NAME)
				WHERE A.OWNER='''||pUSER||''' AND A.TABLE_NAME='''||pSINGLENAME||''' AND B.DATA_TYPE NOT LIKE ''%LOB'' AND B.DATA_TYPE NOT LIKE ''%LONG''
				ORDER BY B.COLUMN_ID';
			OPEN pCOLCURSOR FOR pSELCOLTEXT;
			LOOP
				FETCH pCOLCURSOR INTO pCOLNAME,pDATATYPE;
				EXIT WHEN pCOLCURSOR%NOTFOUND;
				SINGLECOL:='CASE WHEN "'||pCOLNAME||'" IS NULL THEN ';
				------------------------------------------------------------------------------------------------------------
				--此部分解決當字段長度大於等於4000時報字符串鏈接過長的錯誤,若是是非數字和日期類型(此類型長度較小)則統一強制轉換成CLOB類型
				IF pDATATYPE NOT IN('NUMBER','DATE') THEN
					CONSCOL:=SINGLECOL||'TO_CLOB('' IS NULL'') ELSE TO_CLOB(''=';
					VAL:=VAL||SINGLECOL||'TO_CLOB(''NULL'') ELSE TO_CLOB(';
				ELSE
					CONSCOL:=SINGLECOL||''' IS NULL'' ELSE ''=';
					VAL:=VAL||SINGLECOL||'''NULL'' ELSE ';
				------------------------------------------------------------------------------------------------------------
				END IF;
				IF pDATATYPE='NUMBER' THEN 								--數值類型不帶引號
					SINGLECOL:='''||"'||pCOLNAME||'"||''''' ;
					CONSCOL:=CONSCOL||SINGLECOL;
					VAL:=VAL||''''||SINGLECOL;
				ELSIF pDATATYPE='DATE' THEN 							--日期類型進行轉換
					SINGLECOL:='TO_DATE(''''''||TO_CHAR("'||pCOLNAME||'",''YYYY-MM-DD HH24:MI:SS'')||'''''',''''YYYY-MM-DD HH24:MI:SS'''')''';
					CONSCOL:=CONSCOL||SINGLECOL;
					VAL:=VAL||''''||SINGLECOL;
				ELSE 																			--其餘類型帶引號
					SINGLECOL:=''''''')||"'||pCOLNAME||'"||''''''''';
					CONSCOL:=CONSCOL||SINGLECOL;
					VAL:=VAL||''''||SINGLECOL;
				END IF;
				VAL:=VAL||' END||'',''||';
				SELECT '"'||REPLACE(pCOLNAME,'''','''''')||'"' INTO REPLACENAME FROM DUAL;
				COL:=COL||REPLACENAME||',';
				CONSTR:=CONSTR||REPLACENAME||'''||'||CONSCOL||' END||'' AND ';
			END LOOP;
			IF VAL IS NOT NULL THEN 		--若是字段列表爲空(由於clob字段不給與處理),則不處理該表
				IF (pMERGER=1 AND pHASCON='NO') OR pMERGER NOT IN(0,1) THEN	--判斷記錄的每一行在表中是否存在
					SELECT SUBSTR(COL,1,LENGTH(COL)-1) ||') SELECT '')||'|| SUBSTR(VAL,1,LENGTH(VAL)-4) ||' FROM DUAL'||CHR(10)||
						'	WHERE NOT EXISTS('||CHR(10)||
						'		SELECT * FROM '||pSINGLENAME||' WHERE	'||SUBSTR(CONSTR,1,LENGTH(CONSTR)-4)||CHR(10)||
						'	)'||pENDSTR||''' AS CONTEN FROM '|| pSINGLENAME||'@'||pLINKNAME||' '||pWHERESTR
						INTO SINGLETXT FROM DUAL;
				ELSE											--有主見或者惟一約束或者容許添加劇復記錄,則直接爲通常的Insert Into格式
					SELECT SUBSTR(COL,1,LENGTH(COL)-1) ||') VALUES('')||'|| SUBSTR(VAL,1,LENGTH(VAL)-4)||
						')'||pENDSTR||''' AS CONTEN FROM '|| pSINGLENAME||'@'||pLINKNAME||' '||pWHERESTR
						INTO SINGLETXT FROM DUAL;
				END IF;
				IF pSQLTEXT IS NULL THEN
					pSQLTEXT:=SINGLETXT;											--單表的Insert查詢語句
				ELSE																				--經過Union All方式來拼接全部的查詢語句
					pSQLTEXT:=pSQLTEXT||' UNION ALL '||SINGLETXT;
				END IF;
			END IF;
		END LOOP;
		IF pSQLTEXT IS NULL THEN
			pSQLTEXT:='SELECT NULL AS TABLENAME,DUMMY AS CONTEN FROM DUAL WHERE 1=2';	--修正查詢動態SQL爲空報錯的bug
		END IF;
	ELSE
		SYS.DBMS_OUTPUT.PUT_LINE('數據庫連接名稱不能爲空!');
	END IF;
	--SYS.DBMS_OUTPUT.PUT_LINE('/*SQL語句:*/'||pSQLTEXT);
	EXCEPTION
	WHEN NO_DATA_FOUND THEN
		SYS.DBMS_OUTPUT.PUT_LINE('當前系統用戶下未找到數據庫連接'||pLINKNAME||',請檢查或新建數據庫連接!');
	WHEN OTHERS THEN
		SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'導出遠程表出錯:'||SQLERRM||',發生在表:'||pSINGLENAME);
		NULL;
END;

PROCEDURE GET_ALL_INSERT
--功能:獲取用戶下表記錄的INSERT語句
--參數:
--調用:
/*
DECLARE
  PCURSOR SYS_REFCURSOR;
BEGIN
  PKG_GET_INSERT.GET_ALL_INSERT('DKGLL','DEV_INFOEXTAB',0,';',PCURSOR);
END;
*/
--日期:2013-04-11
(
	DBUSER 			IN 	VARCHAR2:=USER, --用戶名
	pTBLIST 		IN 	VARCHAR2:=NULL,	--表和where條件的鏈接,多個鏈接用','分隔,注意:where條件中不能有','不然將出現分割錯誤,表名按照在字符串中前後位置排序
	pMERGER			IN	NUMBER:=0, 			--Insert語句的操做模式
	pENDSTR			IN	VARCHAR2:=';',	--每條Inser語句的結束符,默認以';'結束,這樣能夠進行批量執行
	pCURSOR 		OUT SYS_REFCURSOR
)
AS
	pSQLTEXT1 		CLOB;	             	--SQL語句字符串
	pSQLTEXT2 		CLOB;	             	--SQL語句字符串
BEGIN
	GET_INSERT_SQL(DBUSER,pTBLIST,pMERGER,pENDSTR,pSQLTEXT1,pSQLTEXT2);  --獲取Insert腳本的查詢SQL語句
	OPEN pCURSOR FOR pSQLTEXT1;
END;

PROCEDURE GET_ALL_REMOTEINSERT
--功能:獲取用戶下遠程連接表記錄的INSERT語句
--參數:
--調用:
/*
DECLARE
  PCURSOR SYS_REFCURSOR;
BEGIN
  PKG_GET_INSERT.GET_ALL_REMOTEINSERT('DATABASE_LINK1',NULL,'dev_infoextab',0,';',PCURSOR);
END;
*/
--日期:2013-04-11
(
	pLINKNAME		IN	VARCHAR2,				--遠程連接名稱
	DBUSER 			IN 	VARCHAR2:=USER, --用戶名
	pTBLIST 		IN 	VARCHAR2:=NULL,	--表和where條件的鏈接,多個鏈接用','分隔,注意:where條件中不能有','不然將出現分割錯誤,表名按照在字符串中前後位置排序
	pMERGER			IN	NUMBER:=0, 			--Insert語句的操做模式
	pENDSTR			IN	VARCHAR2:=';',	--每條Inser語句的結束符,默認以';'結束,這樣能夠進行批量執行
	pCURSOR 		OUT SYS_REFCURSOR
)
AS
	pUSER 			VARCHAR2(200):=COALESCE(UPPER(DBUSER),USER);
	pCOUNT			PLS_INTEGER;
	pSQLTEXT 		CLOB;	             	--SQL語句字符串
BEGIN
	SELECT COUNT(1) INTO pCOUNT FROM SYS.DBA_TABLES WHERE OWNER=pUSER AND TABLE_NAME='TEMP_REMOTEINSERT';
  IF pCOUNT=0 THEN                                         									--保存insert數據的臨時表不存在則建立一個全局臨時表
		pSQLTEXT:='CREATE GLOBAL TEMPORARY TABLE "'||pUSER||'"."TEMP_REMOTEINSERT" ('||CHR(10)||
							'	TABLENAME         VARCHAR2(50),'||CHR(10)||
							'	CONTEN         CLOB'||CHR(10)||
							') ON COMMIT PRESERVE ROWS';
	ELSE 																																			--刪除臨時表數據
		pSQLTEXT:='DELETE FROM TEMP_REMOTEINSERT';
  END IF;
	EXECUTE IMMEDIATE pSQLTEXT;
	GET_REMOTEINSERT_SQL(pLINKNAME,DBUSER,pTBLIST,pMERGER,pENDSTR,pSQLTEXT);  --獲取Insert腳本的查詢SQL語句
	--LOB列數據沒法經過數據庫連接直接查詢,必須經過臨時表或者物化視圖方式查詢,不然會報ORA-22992: 沒法使用從遠程表選擇的 LOB 定位器的錯誤
	--此處採用臨時表過分的方式查詢,經測試,經過臨時表插入遠程連接表數據16000條需耗時80秒,效率較低.此處的效率瓶頸在於CLOB字段和TO_CLOB函數運用上,
	--系統對於CLOB字段存儲在LOB段中,不管是本地仍是經過遠程連接存儲和查詢效率都較低,建議控制該字段長度,或者利用多個VARCHAR2字段代替CLOB字段
	pSQLTEXT:='INSERT INTO TEMP_REMOTEINSERT SELECT TABLENAME,CONTEN FROM('||pSQLTEXT||') TB';
	EXECUTE IMMEDIATE pSQLTEXT;
	OPEN pCURSOR FOR 'SELECT TABLENAME,CONTEN FROM TEMP_REMOTEINSERT';
	EXCEPTION
	WHEN OTHERS THEN
		SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'獲取遠程表INSERT語句出錯:'||SQLERRM);
		ROLLBACK;
END;

PROCEDURE SAVE_ALL_INSERT
--功能:保存用戶下表記錄或者遠程連接表記錄的INSERT語句到文件中
--參數:
--調用:
/*
--保存本地數據
BEGIN
	PKG_GET_INSERT.SAVE_ALL_INSERT(NULL,USER,'DEV_INFOEXTAB',0,'BACKDIR','insert腳本0429.sql');
END;
*/
/*
--保存遠程鏈接表數據
DECLARE PLINKNAME VARCHAR2(100);pCOUNT PLS_INTEGER;
BEGIN
  PLINKNAME := 'DATABASE_LINK1';
	PLINKNAME:=UPPER(PLINKNAME);
  SELECT COUNT(1) INTO pCOUNT FROM SYS.DBA_DB_LINKS WHERE OWNER=USER AND DB_LINK=PLINKNAME;
	DBMS_OUTPUT.PUT_LINE(pCOUNT);
	IF pCOUNT=0 THEN
		PKG_DBMANAGE.CREATE_DBLINK(
			PHOST => '172.16.3.251',
			PLINKDB => 'TBS1',
			PLINKUSER => 'DKGLL',
			PLINKPWD => 'DKGLL',
			PLINKNAME => PLINKNAME
		);                             --創建數據庫連接
	END IF;
	PKG_GET_INSERT.SAVE_ALL_INSERT(PLINKNAME,NULL,'dev_infoextab',0,'BACKDIR','insert腳本0428.sql');
END;
*/
--日期:2013-04-25
(
	pLINKNAME		IN	VARCHAR2:=NULL,						--遠程連接名稱,爲空則使用本地表,默認採用本地表
	DBUSER 			IN 	VARCHAR2:=USER, 					--用戶名
	pTBLIST 		IN 	VARCHAR2:=NULL,						--表和where條件的鏈接
	pMERGER			IN	NUMBER:=0, 								--Insert語句的操做模式
	DIR 				IN VARCHAR2:='DATA_PUMP_DIR',	--目錄名稱(若是不填,則使用當前數據庫目錄)
  FILENAME 		IN VARCHAR:=NULL							--保存文件名稱
)
AS
	pSQLTEXT1		CLOB;
	pSQLTEXT2		CLOB;
	pFILED 			UTL_FILE.FILE_TYPE;
	pTABLENAME	VARCHAR2(50);
	pCONTENT 	 	VARCHAR2(32767);							--寫入文件的每一行最大值不能超過32767個字節
	pRFECUR 		SYS_REFCURSOR;
BEGIN
	IF pLINKNAME IS NULL THEN
		GET_INSERT_SQL(DBUSER,pTBLIST,pMERGER,';',pSQLTEXT1,pSQLTEXT2);  --獲取Insert腳本的查詢SQL語句
    OPEN pRFECUR FOR pSQLTEXT2;                            --轉換成遊標
	ELSE
		GET_ALL_REMOTEINSERT(pLINKNAME,DBUSER,pTBLIST,pMERGER,';',pRFECUR);	--獲取用戶下遠程連接表記錄的INSERT語句
	END IF;
	--打開文件,限制每行最大字符數不能超過32767個字節數
  pFILED:=SYS.UTL_FILE.FOPEN(DIR,NVL(FILENAME,'導出Insert腳本'||TO_CHAR(CURRENT_DATE,'YYYYMMDDHH24')||'.sql'),'W',32767);
	LOOP
		FETCH pRFECUR INTO pTABLENAME,pCONTENT;
    EXIT WHEN pRFECUR%NOTFOUND;
		SYS.UTL_FILE.PUT_LINE(pFILED,pCONTENT);       				--寫入文件,按照字節長度寫入文件,不能超過32767個字節數
  END LOOP;
	SYS.UTL_FILE.FCLOSE(pFILED);                    				--關閉文件
	EXCEPTION
	WHEN OTHERS THEN
		SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'保存表數據出錯:'||SQLERRM||',發生在表:'||pTABLENAME) ;
		ROLLBACK;
END;

PROCEDURE GET_LOADER_SQL
--功能:獲取表數據進行Loader格式輸出
--參數:
--調用:
/*
DECLARE
  pSQLTEXT CLOB;
BEGIN
  PKG_GET_INSERT.GET_LOADER_SQL('DKGLL','DEV_INFOEXTAB','|',pSQLTEXT);
END;
*/
/*
DECLARE
 PCURSOR SYS_REFCURSOR;
  pSQLTEXT CLOB;
BEGIN
  PKG_GET_INSERT.GET_LOADER_SQL('DKGLL','TBUSERNAME',',',pSQLTEXT);           --Loader格式表數據
  --dbms_output.put_line(pSQLTEXT);
  OPEN PCURSOR FOR pSQLTEXT;
  PKG_DBMANAGE.CURSOR_TO_FILE('PKG_DBMANAGER_DIR','TBUSERNAME.txt',1,PCURSOR);   --寫入指定目錄的外部表txt文件
  PKG_DBMANAGE.CLONE_EXTERNAL_TB('PKG_DBMANAGER_DIR','TBUSERNAME');              --克隆生成外部表,查詢該表數據便可
END; 
*/
--日期:2014-12-10
(
	DBUSER 			IN 	VARCHAR2:=USER, --用戶名
	pTBNAME 		IN 	VARCHAR2:=NULL,	--表和where條件的鏈接
  pSEP        IN  VARCHAR2:='|',  --分隔符
	pSQLTEXT 		OUT CLOB						--SQL語句字符串
)
AS
	pUSER   VARCHAR2(200):=COALESCE(UPPER(DBUSER),USER);
	pCOL	  VARCHAR2(4000);	        --單列值
  pRFECUR SYS_REFCURSOR;
BEGIN
  FOR Y IN
  (
    SELECT B.COLUMN_NAME,B.DATA_TYPE
      FROM SYS.DBA_TABLES A
      JOIN SYS.DBA_TAB_COLUMNS B ON(A.OWNER=B.OWNER AND A.TABLE_NAME=B.TABLE_NAME)
      WHERE A.OWNER=pUSER AND A.TABLE_NAME=pTBNAME AND B.DATA_TYPE NOT LIKE '%LOB' AND B.DATA_TYPE NOT LIKE '%LONG'
      ORDER BY B.COLUMN_ID
  )
  LOOP
				IF Y.DATA_TYPE='NUMBER' THEN 								--數值類型不帶引號
					pCOL:='"'||Y.COLUMN_NAME||'"||'''||pSEP||'''||' ;
				ELSIF Y.DATA_TYPE='DATE' OR Y.DATA_TYPE LIKE 'TIMESTAMP%' THEN 							--日期類型進行轉換
					pCOL:='TO_CHAR("'||Y.COLUMN_NAME||'",''YYYY-MM-DD HH24:MI:SS'')||'''||pSEP||'''||' ;
				ELSE 																				--其餘類型帶引號
					pCOL:='"'||Y.COLUMN_NAME||'"||'''||pSEP||'''||' ;
				END IF;
        pSQLTEXT:=pSQLTEXT||pCOL;
  END LOOP;
  pSQLTEXT:='SELECT RTRIM('||SUBSTR(pSQLTEXT,1,LENGTH(pSQLTEXT)-2)||','','') FROM '||pTBNAME;
	EXCEPTION
	WHEN OTHERS THEN
		SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'導出表出錯:'||SQLERRM||',發生在表:'||pTBNAME);
		NULL;
END;
END;
/
CREATE OR REPLACE PACKAGE PKG_TESTDATA
AS 
--功能:獲取在用戶表中添加測試數據的文本
PROCEDURE GET_TEST_DATA(
	DBUSER 		IN 	VARCHAR2:=USER,   
  pTBNAME 	IN 	VARCHAR2,
	pSQLTEXT 	OUT CLOB
);

--功能:在用戶表中添加測試數據
PROCEDURE ADD_TEST_DATA(
	DBUSER 		IN VARCHAR2:=USER,   
  pTBNAME 	IN VARCHAR2,
	pCOUNT 		IN NUMBER
);
END;
/
CREATE OR REPLACE PACKAGE BODY PKG_TESTDATA
AS 
PROCEDURE GET_TEST_DATA
--功能:獲取在用戶表中添加測試數據的文本
--參數:DBUSER-用戶名,pTBNAME-表名,pSQLTEXT-返回測試數據文本
--調用:
/*
DECLARE pTXT CLOB;
BEGIN
	PKG_TESTDATA.GET_TEST_DATA('DKGLL','USR_INFOTAB',pTXT);
	DBMS_OUTPUT.PUT_LINE(pTXT);
END;
*/
--日期:2013-03-01
(
	DBUSER 		IN 	VARCHAR2:=USER,   
  pTBNAME 	IN 	VARCHAR2,
	pSQLTEXT 	OUT CLOB
)
AS
	pUSER 	VARCHAR2(200):=COALESCE(UPPER(DBUSER),USER); 
  Val 		VARCHAR2(4000):='';
  Coltxt 	VARCHAR2(4000):='';
  Valtxt 	VARCHAR2(4000):=''; 
BEGIN 
  FOR X IN(
		SELECT TABLE_NAME,COLUMN_NAME,SQLTYPE,
			CASE SQLTYPE 
			WHEN 'INT' THEN NVL(DATA_PRECISION,10) 
			ELSE CHAR_LENGTH END AS CHARLENGTH,DATA_SCALE FROM(
				SELECT A.TABLE_NAME,B.COLUMN_NAME,
					CASE DATA_TYPE
					WHEN 'NUMBER' THEN 'INT'
					WHEN 'DECIMAL' THEN 'INT'
					WHEN 'NUMERIC' THEN 'INT'
					WHEN 'INT' THEN 'INT'
					WHEN 'FLOAT' THEN 'INT'
					WHEN 'SMALLINT' THEN 'INT'
					WHEN 'VARCHAR2' THEN 'STRING'
					WHEN 'DATE' THEN 'DATETIME' 
					WHEN 'VARCHAR2' THEN 'STRING'
					WHEN 'NVARCHAR' THEN 'STRING'
					WHEN 'VARCHAR' THEN 'STRING'
					WHEN 'NVARCHAR' THEN 'STRING'
					WHEN 'CHAR' THEN 'STRING'
					WHEN 'NCHAR' THEN 'STRING'
					WHEN 'BLOB' THEN 'STRING'
					WHEN 'NBLOB' THEN 'STRING'
					WHEN 'CLOB' THEN 'STRING'
					WHEN 'NCLOB' THEN 'STRING'
					WHEN 'LONG' THEN 'STRING'
					ELSE NULL	END AS SQLTYPE, 
					B.DATA_PRECISION,B.CHAR_LENGTH,
					CASE WHEN B.DATA_SCALE IS NOT NULL THEN B.DATA_SCALE ELSE 0 END AS DATA_SCALE,B.COLUMN_ID
					FROM SYS.DBA_TABLES A 
						JOIN SYS.DBA_TAB_COLUMNS B ON (A.OWNER=B.OWNER AND A.TABLE_NAME=B.TABLE_NAME)
						WHERE A.OWNER=pUSER AND A.TABLE_NAME=pTBNAME
			) TB 
			WHERE SQLTYPE IS NOT NULL
			ORDER BY TABLE_NAME,COLUMN_ID
	) 
	LOOP
		Coltxt:=Coltxt||',"'||X.COLUMN_NAME||'"';
		IF X.SQLTYPE='INT' THEN            --處理數字類型,採用隨機數
			IF X.CHARLENGTH=1 THEN
				X.CHARLENGTH:=2;
        ELSIF X.CHARLENGTH>=11 THEN
          X.CHARLENGTH:=10;
        END IF;
        IF X.CHARLENGTH-X.DATA_SCALE>0 THEN 
          X.CHARLENGTH:=X.CHARLENGTH-X.DATA_SCALE;        
          Val:='TRUNC(DBMS_RANDOM.VALUE(RPAD(10,'||X.CHARLENGTH||'-1,0),RPAD(10,'||X.CHARLENGTH||',0)))'; 
        ELSE 
          Val:='0';
			END IF;
		ELSIF X.SQLTYPE='STRING' THEN      --處理字符類型,採用GUID類型
			IF X.CHARLENGTH>=3999 OR X.CHARLENGTH=0 THEN
				X.CHARLENGTH:=3999; 
			END IF;
			Val:='RPAD(SYS_GUID(),'||X.CHARLENGTH||',SYS_GUID())';
		ELSE                               --處理日期類型,採用當前系統日期時間
			Val:='SYSDATE';
		END IF; 
		Valtxt:=Valtxt||','||Val;         
  END LOOP;
  pSQLTEXT:='INSERT INTO '||pTBNAME||' ('||SUBSTR(Coltxt,2)||') VALUES ('||SUBSTR(Valtxt,2)||')';
END; 

PROCEDURE ADD_TEST_DATA
--功能:在用戶表中添加測試數據
--參數:DBUSER-用戶名,pTBNAME-表名,pCOUNT-添加條數
--調用:EXECUTE PKG_TESTDATA.ADD_TEST_DATA(NULL,'TABLE3',2);
--日期:2013-03-01
(
	DBUSER 		IN VARCHAR2:=USER,   
  pTBNAME 	IN VARCHAR2,
	pCOUNT 		IN NUMBER
)
AS
	pTXT CLOB;
BEGIN
	GET_TEST_DATA(DBUSER,pTBNAME,pTXT);
	FOR X IN 1..pCOUNT LOOP
		EXECUTE IMMEDIATE pTXT; 
	END LOOP; 	
  EXCEPTION 
	WHEN OTHERS THEN 
    SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'添加測試數據出錯:' ||SQLERRM);
    RAISE;
END;
END;
/ 
CREATE OR REPLACE PACKAGE PKG_CREATE_PROC
AS 
--功能:獲取添加表記錄的存儲過程文本(注意過程名稱標識符不能超過30個字符)
PROCEDURE GET_ADD_PROC(
	DBUSER 		IN 	VARCHAR2,								--用戶
  pTBNAME 	IN 	VARCHAR2,								--表名,多個表以','分隔	
	pISLIKE 	IN 	NUMBER:=0,							--表名是精確匹配仍是進行模糊搜索,默認爲精確查找
	pADDSTR		IN	VARCHAR2:='ADD_',				--過程標識符,默認過程名稱爲標識符加上表名
	pPRESTR		IN	VARCHAR2:='p',					--存儲過程參數前置標識符,默認爲小寫字母'p'
  pSQLTEXT 	OUT CLOB										--返回添加表記錄的存儲過程文本
);

--功能:獲取修改表記錄的存儲過程文本(根據主鍵列修改,注意過程名稱標識符不能超過30個字符)
PROCEDURE GET_UPDATE_PROC(
	DBUSER 				IN 	VARCHAR2,						--用戶
  pTBNAME 			IN 	VARCHAR2,						--表名,多個表以','分隔
	pISLIKE 			IN 	NUMBER:=0,					--表名是精確匹配仍是進行模糊搜索,默認爲精確查找
	pUPPERDATESTR	IN	VARCHAR2:='UPDATE_',--過程標識符,默認過程名稱爲標識符加上表名
	pPRESTR				IN	VARCHAR2:='p',			--存儲過程參數前置標識符,默認爲小寫字母'p'
  pSQLTEXT 			OUT CLOB								--返回添加表記錄的存儲過程文本
);

--功能:獲取刪除表記錄的存儲過程文本(根據主鍵列刪除,注意過程名稱標識符不能超過30個字符)
PROCEDURE GET_DELETE_PROC(
	DBUSER 				IN 	VARCHAR2,						--用戶
  pTBNAME 			IN 	VARCHAR2,						--表名,多個表以','分隔
	pISLIKE 			IN 	NUMBER:=0,					--表名是精確匹配仍是進行模糊搜索,默認爲精確查找
	pDELETESTR		IN	VARCHAR2:='DEL_',		--過程標識符,默認過程名稱爲標識符加上表名
	pPRESTR				IN	VARCHAR2:='p',			--存儲過程參數前置標識符,默認爲小寫字母'p'
  pSQLTEXT 			OUT CLOB								--返回添加表記錄的存儲過程文本
);

--功能:獲取用戶增長修改刪除標記裏的存儲過程文本(注意過程名稱標識符不能超過30個字符)
PROCEDURE GET_DDL_PROC( 
	DBUSER 				IN 	VARCHAR2,						--用戶
  pTBNAME 			IN 	VARCHAR2,						--表名,多個表以','分隔
	pISLIKE 			IN 	NUMBER:=0,					--表名是精確匹配仍是進行模糊搜索,默認爲精確查找
	pADDSTR				IN	VARCHAR2:='ADD_',		--過程標識符,默認過程名稱爲標識符加上表名
	pUPPERDATESTR	IN	VARCHAR2:='UPDATE_',--過程標識符,默認過程名稱爲標識符加上表名
	pDELETESTR		IN	VARCHAR2:='DEL_',		--過程標識符,默認過程名稱爲標識符加上表名
	pPRESTR				IN	VARCHAR2:='p',			--存儲過程參數前置標識符,默認爲小寫字母'p'
  pSQLTEXT 			OUT CLOB								--返回添加表記錄的存儲過程文本
);
END;
/
CREATE OR REPLACE PACKAGE BODY PKG_CREATE_PROC
AS 
PROCEDURE GET_ADD_PROC
--功能:獲取添加表記錄的存儲過程文本(注意過程名稱標識符不能超過30個字符)
--參數: 
--調用:
/*
DECLARE pSQLTEXT CLOB;
BEGIN
	PKG_CREATE_PROC.GET_ADD_PROC(DBUSER=>NULL,pTBNAME=>'USR_INFOTAB,A,B,C,CC',pSQLTEXT=>pSQLTEXT);
	DBMS_OUTPUT.PUT_LINE(pSQLTEXT);
END;
*/
--日期:2013-02-10
(
	DBUSER 		IN 	VARCHAR2,								--用戶
  pTBNAME 	IN 	VARCHAR2,								--表名,多個表以','分隔
	pISLIKE 	IN 	NUMBER:=0,							--表名是精確匹配仍是進行模糊搜索,默認爲精確查找
	pADDSTR		IN	VARCHAR2:='ADD_',				--過程標識符,默認過程名稱爲標識符加上表名
	pPRESTR		IN	VARCHAR2:='p',					--存儲過程參數前置標識符,默認爲小寫字母'p'
  pSQLTEXT 	OUT CLOB										--返回添加表記錄的存儲過程文本
)
AS
	pUSER 		VARCHAR2(200):=COALESCE(UPPER(DBUSER),USER); 
	pPROCNAME	VARCHAR2(50); 
BEGIN
	FOR X IN
	(
		SELECT DISTINCT TABLE_NAME,
			LISTAGG('	'||pPRESTR||COLUMN_NAME||' IN '||DATA_TYPE,','||CHR(10)) 
				WITHIN GROUP(ORDER BY COLUMN_ID) OVER(PARTITION BY TABLE_NAME) AS PARALIST,
			LISTAGG(COLUMN_NAME,',') 
				WITHIN GROUP(ORDER BY COLUMN_ID) OVER(PARTITION BY TABLE_NAME) AS COLLIST,
			LISTAGG(pPRESTR||COLUMN_NAME,',') 
				WITHIN GROUP(ORDER BY COLUMN_ID) OVER(PARTITION BY TABLE_NAME) AS VALLIST
			FROM SYS.DBA_TAB_COLUMNS 
			WHERE OWNER=pUSER AND (
				(pISLIKE=0 AND INSTR(','||pTBNAME||',',','||TABLE_NAME||',',1)>0) OR (pISLIKE=1 AND TABLE_NAME LIKE '%'||pTBNAME||'%')
			)
	)
	LOOP 
		pPROCNAME:=SUBSTR(X.TABLE_NAME,0,25);
		pSQLTEXT:=pSQLTEXT||
			'CREATE OR REPLACE PROCEDURE '||pADDSTR||pPROCNAME||CHR(10)|| 
			'--功能:添加'||X.TABLE_NAME||'表記錄'||CHR(10)||
			'--參數:'||CHR(10)||
			'--調用:'||CHR(10)||
			'--日期:'||TO_CHAR(SYSDATE,'YYYY-MM-DD')||CHR(10)||
			'('||CHR(10)||
			X.PARALIST||CHR(10)||
			')'||CHR(10)||
			'AS'||CHR(10)||
			'BEGIN'||CHR(10)||
			'	INSERT INTO '||X.TABLE_NAME||'('||X.COLLIST||')'||CHR(10)||
			'		VALUES('||X.VALLIST||');'||CHR(10)||
			'	COMMIT;'||CHR(10)||
			'	EXCEPTION'||CHR(10)||
			'	WHEN OTHERS THEN'||CHR(10)||
			'		ROLLBACK;'||CHR(10)||			
			'END '||pADDSTR||pPROCNAME||';'||CHR(10)||
			'/'||CHR(10);	
	END LOOP; 
END;

PROCEDURE GET_UPDATE_PROC
--功能:獲取修改表記錄的存儲過程文本(根據主鍵列修改,注意標識符不能超過30個字符)
--參數: 
--調用:
/*
DECLARE pSQLTEXT CLOB;
BEGIN
	PKG_CREATE_PROC.GET_UPDATE_PROC(DBUSER=>NULL,pTBNAME=>'A',pSQLTEXT=>pSQLTEXT);
	DBMS_OUTPUT.PUT_LINE(pSQLTEXT);
END;
*/
--日期:2013-02-10
(
	DBUSER 				IN 	VARCHAR2,						--用戶
  pTBNAME 			IN 	VARCHAR2,						--表名,多個表以','分隔
	pISLIKE 			IN 	NUMBER:=0,					--表名是精確匹配仍是進行模糊搜索,默認爲精確查找
	pUPPERDATESTR	IN	VARCHAR2:='UPDATE_',--過程標識符,默認過程名稱爲標識符加上表名
	pPRESTR				IN	VARCHAR2:='p',			--存儲過程參數前置標識符,默認爲小寫字母'p'
  pSQLTEXT 			OUT CLOB								--返回添加表記錄的存儲過程文本
)
AS
	pUSER 		VARCHAR2(200):=COALESCE(UPPER(DBUSER),USER); 
	pPROCNAME	VARCHAR2(50); 
	pWHERE		VARCHAR2(4000);
BEGIN
	FOR X IN(
		SELECT DISTINCT TABLE_NAME,
			LISTAGG('	'||pPRESTR||COLUMN_NAME||' IN '||DATA_TYPE,','||CHR(10)) 
				WITHIN GROUP(ORDER BY COLUMN_ID) OVER(PARTITION BY TABLE_NAME) AS PARALIST,
			LISTAGG(CASE ISPRIMARY WHEN 0 THEN COLUMN_NAME||'='||pPRESTR||COLUMN_NAME ELSE '' END,',') 
				WITHIN GROUP(ORDER BY COLUMN_ID) OVER(PARTITION BY TABLE_NAME) AS SETLIST,
			LISTAGG(CASE ISPRIMARY WHEN 1 THEN COLUMN_NAME||'='||pPRESTR||COLUMN_NAME ELSE '' END,' AND ') 
				WITHIN GROUP(ORDER BY COLUMN_ID) OVER(PARTITION BY TABLE_NAME) AS WHERELIST
			FROM (
				SELECT A.TABLE_NAME,A.COLUMN_NAME,A.DATA_TYPE,A.COLUMN_ID,
					CASE WHEN B.COLUMN_NAME IS NULL THEN 0 ELSE 1 END ISPRIMARY FROM SYS.DBA_TAB_COLUMNS A
					LEFT JOIN (
						SELECT TA.OWNER,TA.TABLE_NAME,TA.COLUMN_NAME FROM SYS.DBA_CONS_COLUMNS TA 
							JOIN SYS.DBA_CONSTRAINTS TB ON (TA.OWNER=TB.OWNER AND TA.TABLE_NAME=TB.TABLE_NAME AND TA.CONSTRAINT_NAME=TB.CONSTRAINT_NAME)
							WHERE TB.CONSTRAINT_TYPE='P' 
					) B ON (A.OWNER=B.OWNER AND A.TABLE_NAME=B.TABLE_NAME AND A.COLUMN_NAME=B.COLUMN_NAME) 
					WHERE A.OWNER=pUSER AND (
						(pISLIKE=0 AND INSTR(','||pTBNAME||',',','||A.TABLE_NAME||',',1)>0) OR (pISLIKE=1 AND A.TABLE_NAME LIKE '%'||pTBNAME||'%')
					)
			)
	)
	LOOP
		pPROCNAME:=SUBSTR(X.TABLE_NAME,0,25);
		SELECT DECODE(X.WHERELIST,NULL,'		/*WHERE<搜索條件>*/','		WHERE	'||X.WHERELIST) INTO pWHERE FROM DUAL;  --若是沒有主鍵則去掉WHERE條件
		pSQLTEXT:=pSQLTEXT||
			'CREATE OR REPLACE PROCEDURE '||pUPPERDATESTR||pPROCNAME||CHR(10)||
			'--功能:修改'||X.TABLE_NAME||'表記錄'||CHR(10)||
			'--參數:'||CHR(10)||
			'--調用:'||CHR(10)||
			'--日期:'||TO_CHAR(SYSDATE,'YYYY-MM-DD')||CHR(10)||
			'('||CHR(10)||
			X.PARALIST||CHR(10)||
			')'||CHR(10)||
			'AS'||CHR(10)||
			'BEGIN'||CHR(10)||
			'	UPDATE '||X.TABLE_NAME||' SET '||X.SETLIST||CHR(10)||
			pWHERE||X.WHERELIST||';'||CHR(10)||
			'	COMMIT;'||CHR(10)||
			'	EXCEPTION'||CHR(10)||
			'	WHEN OTHERS THEN'||CHR(10)||
			'		ROLLBACK;'||CHR(10)||				
			'END '||pUPPERDATESTR||pPROCNAME||';'||CHR(10)||
			'/'||CHR(10);			
	END LOOP;
END;

PROCEDURE GET_DELETE_PROC
--功能:獲取刪除表記錄的存儲過程文本(根據主鍵列刪除,注意標識符不能超過30個字符)
--參數: 
--調用:
/*
DECLARE pSQLTEXT CLOB;
BEGIN
	PKG_CREATE_PROC.GET_DELETE_PROC(DBUSER=>NULL,pTBNAME=>'A,B,C,CC',pSQLTEXT=>pSQLTEXT);
	DBMS_OUTPUT.PUT_LINE(pSQLTEXT);
END;
*/
--日期:2013-02-10
(
	DBUSER 				IN 	VARCHAR2,						--用戶
  pTBNAME 			IN 	VARCHAR2,						--表名,多個表以','分隔
	pISLIKE 			IN 	NUMBER:=0,					--表名是精確匹配仍是進行模糊搜索,默認爲精確查找
	pDELETESTR		IN	VARCHAR2:='DEL_',		--過程標識符,默認過程名稱爲標識符加上表名
	pPRESTR				IN	VARCHAR2:='p',			--存儲過程參數前置標識符,默認爲小寫字母'p'
  pSQLTEXT 			OUT CLOB								--返回添加表記錄的存儲過程文本
)
AS
	pUSER 		VARCHAR2(200):=COALESCE(UPPER(DBUSER),USER); 
	pPROCNAME	VARCHAR2(50); 
	pWHERE		VARCHAR2(4000);
	pPARA			VARCHAR2(4000);
BEGIN
	FOR X IN(
		SELECT DISTINCT TABLE_NAME,
			LISTAGG(CASE ISPRIMARY WHEN 1 THEN '	'||pPRESTR||COLUMN_NAME||' IN '||DATA_TYPE ELSE '' END,','||CHR(10)) 
				WITHIN GROUP(ORDER BY COLUMN_ID) OVER(PARTITION BY TABLE_NAME) AS PARALIST,
			LISTAGG(CASE ISPRIMARY WHEN 1 THEN COLUMN_NAME||'='||pPRESTR||COLUMN_NAME ELSE '' END,' AND ') 
				WITHIN GROUP(ORDER BY COLUMN_ID) OVER(PARTITION BY TABLE_NAME) AS WHERELIST
			FROM (
				SELECT A.TABLE_NAME,A.COLUMN_NAME,A.DATA_TYPE,A.COLUMN_ID,
					CASE WHEN B.COLUMN_NAME IS NULL THEN 0 ELSE 1 END ISPRIMARY FROM SYS.DBA_TAB_COLUMNS A
					LEFT JOIN (
						SELECT TA.OWNER,TA.TABLE_NAME,TA.COLUMN_NAME FROM SYS.DBA_CONS_COLUMNS TA 
							JOIN SYS.DBA_CONSTRAINTS TB ON (TA.OWNER=TB.OWNER AND TA.TABLE_NAME=TB.TABLE_NAME AND TA.CONSTRAINT_NAME=TB.CONSTRAINT_NAME)
							WHERE TB.CONSTRAINT_TYPE='P' 
					) B ON (A.OWNER=B.OWNER AND A.TABLE_NAME=B.TABLE_NAME AND A.COLUMN_NAME=B.COLUMN_NAME) 
					WHERE A.OWNER=pUSER AND (
						(pISLIKE=0 AND INSTR(','||pTBNAME||',',','||A.TABLE_NAME||',',1)>0) OR (pISLIKE=1 AND A.TABLE_NAME LIKE '%'||pTBNAME||'%')
					)
			)
	)
	LOOP
		pPROCNAME:=SUBSTR(X.TABLE_NAME,0,25);
		SELECT DECODE(X.WHERELIST,NULL,' /*WHERE<搜索條件>*/',' WHERE	'||X.WHERELIST),
			DECODE(X.WHERELIST,NULL,'','('||CHR(10)||X.PARALIST||CHR(10)||')'||CHR(10))
			INTO pWHERE,pPARA FROM DUAL;			--若是沒有主鍵則去掉WHERE條件和輸入參數
		pSQLTEXT:=pSQLTEXT||
			'CREATE OR REPLACE PROCEDURE '||pDELETESTR||pPROCNAME||CHR(10)|| 
			'--功能:刪除'||X.TABLE_NAME||'表記錄'||CHR(10)||
			'--參數:'||CHR(10)||
			'--調用:'||CHR(10)||
			'--日期:'||TO_CHAR(SYSDATE,'YYYY-MM-DD')||CHR(10)||
			pPARA||
			'AS'||CHR(10)||
			'BEGIN'||CHR(10)||
			'	DELETE FROM '||X.TABLE_NAME||pWHERE||';'||CHR(10)||
			'	COMMIT;'||CHR(10)||
			'	EXCEPTION'||CHR(10)||
			'	WHEN OTHERS THEN'||CHR(10)||
			'		ROLLBACK;'||CHR(10)||			
			'END '||pDELETESTR||pPROCNAME||';'||CHR(10)||
			'/'||CHR(10);			
	END LOOP;
END;

PROCEDURE GET_DDL_PROC
--功能:獲取用戶增長修改刪除標記裏的存儲過程文本(注意標識符不能超過30個字符)
--參數: 
--調用:
/*
DECLARE pSQLTEXT CLOB;
BEGIN
	PKG_CREATE_PROC.GET_DDL_PROC(DBUSER=>NULL,pTBNAME=>'A,B,C,CC',pSQLTEXT=>pSQLTEXT);
	DBMS_OUTPUT.PUT_LINE(pSQLTEXT);
END;
*/
--日期:2013-02-10
( 
	DBUSER 				IN 	VARCHAR2,						--用戶
  pTBNAME 			IN 	VARCHAR2,						--表名,多個表以','分隔
	pISLIKE 			IN 	NUMBER:=0,					--表名是精確匹配仍是進行模糊搜索,默認爲精確查找
	pADDSTR				IN	VARCHAR2:='ADD_',		--過程標識符,默認過程名稱爲標識符加上表名
	pUPPERDATESTR	IN	VARCHAR2:='UPDATE_',--過程標識符,默認過程名稱爲標識符加上表名
	pDELETESTR		IN	VARCHAR2:='DEL_',		--過程標識符,默認過程名稱爲標識符加上表名
	pPRESTR				IN	VARCHAR2:='p',			--存儲過程參數前置標識符,默認爲小寫字母'p'
  pSQLTEXT 			OUT CLOB								--返回添加表記錄的存儲過程文本
)
AS
	pADDTEXT 		CLOB;
	pUPDATETEXT CLOB;
	pDELETETEXT CLOB;
BEGIN
	GET_ADD_PROC(DBUSER=>DBUSER,pTBNAME=>pTBNAME,pSQLTEXT=>pADDTEXT);        	--獲取添加表記錄的存儲過程
	GET_UPDATE_PROC(DBUSER=>DBUSER,pTBNAME=>pTBNAME,pSQLTEXT=>pUPDATETEXT);		--獲取修改表記錄的存儲過程
	GET_DELETE_PROC(DBUSER=>DBUSER,pTBNAME=>pTBNAME,pSQLTEXT=>pDELETETEXT);		--獲取刪除表記錄的存儲過程
	pSQLTEXT:=pADDTEXT||CHR(10)||pUPDATETEXT||CHR(10)||pDELETETEXT;
	EXCEPTION 
	WHEN OTHERS THEN
		SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'生成存儲過程出錯:'||SQLERRM) ;
		ROLLBACK;
END;
END;
/
CREATE OR REPLACE PACKAGE PKG_DYNAMIC_SQL
AUTHID CURRENT_USER
AS 
--功能:根據傳入的動態查詢SQL語句分析遊標的列數和列名,可用於列名和列數未知的動態遊標列索引取值
PROCEDURE GET_REFCURSOR_COLUMN
(
	pSQLSTR IN VARCHAR2										--動態查詢的SQL語句
);

--功能:根據傳入的動態遊標來分析該遊標的列數和列名,可用於列名和列數未知的動態遊標列索引取值
PROCEDURE GET_REFCURSOR_COLUMN
(
	pREFCURSOR IN OUT SYS_REFCURSOR				--動態遊標
);

--功能:執行動態sql語句,執行錯誤則回滾並輸出錯誤行號和錯誤消息
PROCEDURE EXECUTE_SQL(pSQL IN CLOB);

--功能:集合分頁查詢,返回總行數和分頁結果集
PROCEDURE GET_PAGE_ROWS(
	pSQL 				IN 	CLOB,						--分頁查詢sql語句
	pCOLLIST 		IN 	VARCHAR2,		   	--返回的列
	pPAGEINDEX 	IN 	INT,						--查詢頁索引
	pPAGESIZE 	IN 	INT,						--查詢每頁行數
	pTOTALROW 	OUT INT,					  --返回總行數
	pPAGECURSOR OUT SYS_REFCURSOR 	--返回分頁數據集
);

--功能:集合分頁查詢,返回總行數和分頁結果集,其中分頁後返回的列與分頁前返回的不一樣
PROCEDURE GET_PAGE_ROWS(
	pSQL 				IN 	CLOB,						--分頁查詢sql語句
	pCOLLIST1 	IN 	VARCHAR2,		   	--分頁前返回的列
	pCOLLIST2 	IN 	VARCHAR2,		   	--分頁後返回的列
	pPAGEINDEX 	IN 	INT,						--查詢頁索引
	pPAGESIZE 	IN 	INT,						--查詢每頁行數
	pTOTALROW 	OUT INT,					  --返回總行數
	pPAGECURSOR OUT SYS_REFCURSOR 	--返回分頁數據集
);
END;
/
CREATE OR REPLACE PACKAGE BODY PKG_DYNAMIC_SQL
AS 
PROCEDURE GET_REFCURSOR_COLUMN
--功能:根據傳入的動態查詢SQL語句分析遊標的列數和列名,可用於列名和列數未知的動態遊標列索引取值
--參數: 
--調用:EXEC PKG_DYNAMIC_SQL.GET_REFCURSOR_COLUMN('SELECT * FROM DEV_BASECLASSTAB');
--日期:2014-04-27
(
	pSQLSTR IN VARCHAR2										--動態查詢的SQL語句
)
AS
pREFCURSOR 		SYS_REFCURSOR; 						--動態遊標
pCURSORID 		INTEGER;									--動態遊標ID
pCOLUMNCOUNT 	INTEGER;									--遊標的列數
pDESC_TAB 		DBMS_SQL.DESC_TAB;			
BEGIN
	OPEN pREFCURSOR FOR pSQLSTR;
	pCURSORID:=SYS.DBMS_SQL.TO_CURSOR_NUMBER(pREFCURSOR);
	SYS.DBMS_SQL.DESCRIBE_COLUMNS(pCURSORID,pCOLUMNCOUNT,pDESC_TAB);
	FOR I IN 1..pCOLUMNCOUNT
	LOOP
		DBMS_OUTPUT.PUT_LINE(pDESC_TAB(I).COL_NAME);		
	END LOOP;
	SYS.DBMS_SQL.CLOSE_CURSOR(pCURSORID);
END;

PROCEDURE GET_REFCURSOR_COLUMN
--功能:根據傳入的動態遊標來分析該遊標的列數和列名,可用於列名和列數未知的動態遊標列索引取值
--參數: 
--調用:
/*
DECLARE pREFCURSOR SYS_REFCURSOR;
BEGIN
	OPEN pREFCURSOR FOR SELECT * FROM DEV_BASECLASSTAB;
	PKG_DYNAMIC_SQL.GET_REFCURSOR_COLUMN(pREFCURSOR);
END;
*/
--日期:2014-04-27
(
	pREFCURSOR IN OUT SYS_REFCURSOR				--動態遊標
)
AS 
pCURSORID 		INTEGER;									--動態遊標ID
pCOLUMNCOUNT 	INTEGER;									--遊標的列數
pDESC_TAB 		DBMS_SQL.DESC_TAB;			
BEGIN
	pCURSORID:=SYS.DBMS_SQL.TO_CURSOR_NUMBER(pREFCURSOR);
	SYS.DBMS_SQL.DESCRIBE_COLUMNS(pCURSORID,pCOLUMNCOUNT,pDESC_TAB);
	FOR I IN 1..pCOLUMNCOUNT
	LOOP
		DBMS_OUTPUT.PUT_LINE(pDESC_TAB(I).COL_NAME);		
	END LOOP;
	SYS.DBMS_SQL.CLOSE_CURSOR(pCURSORID);
END;

PROCEDURE EXECUTE_SQL
--功能:執行動態sql語句,執行錯誤則回滾並輸出錯誤行號和錯誤消息
--參數:pSQL-查詢sql語句
--調用:EXECUTE PKG_DYNAMIC_SQL.EXECUTE_SQL('CREATE TABLE X');
--日期:2013-03-01
(
  pSQL IN CLOB 
)
AS
BEGIN
  EXECUTE IMMEDIATE pSQL;
  COMMIT;
  EXCEPTION 
	WHEN OTHERS THEN 
    SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'執行動態SQL語句出錯:' ||SQLERRM);
    RAISE;
END;

PROCEDURE EXECUTE_PLSQL
--功能:執行動態pl/sql語句,執行錯誤則回滾並輸出錯誤行號和錯誤消息
--參數:pSQL-查詢sql語句
--調用:EXECUTE PKG_DYNAMIC_SQL.EXECUTE_SQL('INSERT INTO TB VALUES (q'{11}')');
--日期:2013-03-01
(
  pSQL IN CLOB 
)
AS
BEGIN
	--將SQL語句封裝到BEGIN-END匿名塊中,保證不管傳什麼樣的字符串都會被做爲一個有效的PL/SQL塊執行
  EXECUTE IMMEDIATE 'BEGIN '||CHR(10)||RTRIM(pSQL,';')||'; '||CHR(10)||'END;'; --注意語句結束必須帶';'結束符,不然報錯
  COMMIT;
  EXCEPTION 
	WHEN OTHERS THEN 
    SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'執行動態PL/SQL語句塊出錯:' ||SQLERRM);
    ROLLBACK;
END;

PROCEDURE GET_PAGE_ROWS
--功能:集合分頁查詢,返回總行數和分頁結果集
--參數:見下方說明
--調用:
/*
DECLARE pTOTALROW INT;pPAGECURSOR SYS_REFCURSOR;
BEGIN
	PKG_DYNAMIC_SQL.GET_PAGE_ROWS('SELECT * FROM USER_OBJECTS','OBJECT_NAME,OBJECT_TYPE',1,100,pTOTALROW,pPAGECURSOR);
END;
*/
--日期:2013-02-17
(
	pSQL 				IN 	CLOB,						--分頁查詢sql語句
	pCOLLIST 		IN 	VARCHAR2,		   	--返回的列
	pPAGEINDEX 	IN 	INT,						--查詢頁索引
	pPAGESIZE 	IN 	INT,						--查詢每頁行數
	pTOTALROW 	OUT INT,					  --返回總行數
	pPAGECURSOR OUT SYS_REFCURSOR 	--返回分頁數據集
)
AS
	pNEWPAGEINDEX INT:=pPAGEINDEX;
	pNEWPAGESIZE 	INT:=pPAGESIZE;
	pSTART 				PLS_INTEGER;
	pEND 					PLS_INTEGER;
	SQLTEXT 			CLOB;
BEGIN
  IF pPAGEINDEX<1 THEN   --頁索引小於1時默認爲選擇第一頁
    pNEWPAGEINDEX:=1;
  END IF;
  IF pPAGESIZE<1 THEN    --頁行數小於1時默認已選擇1行
    pNEWPAGESIZE:=1;
  END IF;  
  pSTART:=(pNEWPAGEINDEX-1)*pNEWPAGESIZE;
  pEND:=pNEWPAGEINDEX*pNEWPAGESIZE; 
  EXECUTE IMMEDIATE 'SELECT COUNT(1) FROM ('||pSQL||')' INTO pTOTALROW;
  SQLTEXT:='SELECT '||pCOLLIST||' FROM(SELECT '||pCOLLIST||',ROWNUM FROM('||pSQL||') TA)TB WHERE "ROWNUM">'||pSTART||' AND "ROWNUM"<='||pEND;
  SYS.DBMS_OUTPUT.PUT_LINE('/*SQL語句:*/'||SQLTEXT);
  OPEN pPAGECURSOR FOR SQLTEXT;
  EXCEPTION 
  WHEN OTHERS THEN
		SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'執行SQL語句出錯:' ||SQLERRM||CHR(10)||'/*SQL語句:*/'||SQLTEXT);
    NULL;
END;

PROCEDURE GET_PAGE_ROWS
--功能:集合分頁查詢,返回總行數和分頁結果集,其中分頁後返回的列與分頁前返回的不一樣
--參數:見下方說明
--調用:
/*
DECLARE pTOTALROW INT;pPAGECURSOR SYS_REFCURSOR;
BEGIN
	PKG_DYNAMIC_SQL.GET_PAGE_ROWS('SELECT * FROM USER_OBJECTS','OBJECT_NAME,OBJECT_TYPE',1,100,pTOTALROW,pPAGECURSOR);
END;
*/
--日期:2013-02-17
(
	pSQL 				IN 	CLOB,						--分頁查詢sql語句
	pCOLLIST1 	IN 	VARCHAR2,		   	--分頁前返回的列
	pCOLLIST2 	IN 	VARCHAR2,		   	--分頁後返回的列
	pPAGEINDEX 	IN 	INT,						--查詢頁索引
	pPAGESIZE 	IN 	INT,						--查詢每頁行數
	pTOTALROW 	OUT INT,					  --返回總行數
	pPAGECURSOR OUT SYS_REFCURSOR 	--返回分頁數據集
)
AS
	pNEWPAGEINDEX INT:=pPAGEINDEX;
	pNEWPAGESIZE 	INT:=pPAGESIZE;
	pSTART 				PLS_INTEGER;
	pEND 					PLS_INTEGER;
	SQLTEXT 			CLOB;
BEGIN
  IF pPAGEINDEX<1 THEN   --頁索引小於1時默認爲選擇第一頁
    pNEWPAGEINDEX:=1;
  END IF;
  IF pPAGESIZE<1 THEN    --頁行數小於1時默認已選擇1行
    pNEWPAGESIZE:=1;
  END IF;  
  pSTART:=(pNEWPAGEINDEX-1)*pNEWPAGESIZE;
  pEND:=pNEWPAGEINDEX*pNEWPAGESIZE; 
  EXECUTE IMMEDIATE 'SELECT COUNT(1) FROM ('||pSQL||')' INTO pTOTALROW;
  SQLTEXT:='SELECT '||pCOLLIST2||' FROM(SELECT '||pCOLLIST1||',ROWNUM FROM('||pSQL||') TA)TB WHERE "ROWNUM">'||pSTART||' AND "ROWNUM"<='||pEND;
  SYS.DBMS_OUTPUT.PUT_LINE('/*SQL語句:*/'||SQLTEXT);
  OPEN pPAGECURSOR FOR SQLTEXT;
  EXCEPTION 
  WHEN OTHERS THEN
		SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'執行SQL語句出錯:' ||SQLERRM||CHR(10)||'/*SQL語句:*/'||SQLTEXT);
END;
END;
/
CREATE OR REPLACE PACKAGE PKG_TEST
AS
--功能:開始計時,保存CPU時間到開始時間字段中
PROCEDURE START_TIMER;

--功能:計算消耗的時間(單位:毫秒)
FUNCTION ELAPSED_TIME RETURN NUMBER;

--功能:輸出執行動態SQL語句所消耗的時間(單位:毫秒)
PROCEDURE SHOW_ELAPSED_TIME(
  pSQLTEXT  IN VARCHAR2:=NULL,        --SQL語句塊
  pSQLTYPE  IN NUMBER:=1,             --SQL語句類型,默認爲1-動態SQL語句,2-動態PL/SQL語句,其餘-查詢語句
  pRESET_IN IN BOOLEAN:=TRUE          --是否從新計時,默認每次執行SQL語句均從新計時
);
END;
/
CREATE OR REPLACE PACKAGE BODY PKG_TEST
AS
LAST_TIMING NUMBER:=NULL; 

PROCEDURE START_TIMER
--功能:開始計時,保存CPU時間到開始時間字段中
--參數:
--調用:
--日期:2014-05-22
AS
BEGIN
  LAST_TIMING:=SYS.DBMS_UTILITY.GET_CPU_TIME;
END;

FUNCTION ELAPSED_TIME 
--功能:計算消耗的時間(單位:毫秒)
--參數:
--調用:
--日期:2014-05-22
RETURN NUMBER
IS
  END_TIME  PLS_INTEGER:=SYS.DBMS_UTILITY.GET_CPU_TIME; 
BEGIN 
  --因爲函數DBMS_UTILITY.GET_CPU_TIME所返回的數字表明的是從某一個時間點以來所通過的總的秒數,而這個數字會至關大(受限於咱們的操做系統),達到必定程度就會滾動到0後從新開始計數,
  --所以,若是對於GET_TIME的調用恰巧發生在滾動以前,結束時間-開始時間就會是負值.下面的寫法可有效避免出現負值的狀況.
  RETURN MOD(END_TIME - LAST_TIMING + POWER (2, 32), POWER (2, 32))*10;
END;

PROCEDURE SHOW_ELAPSED_TIME
--功能:輸出執行動態SQL語句所消耗的時間(單位:毫秒)
--參數:
--調用:
--日期:2014-05-22
(
  pSQLTEXT  IN VARCHAR2:=NULL,        --SQL語句塊
  pSQLTYPE  IN NUMBER:=1,             --SQL語句類型,默認爲1-動態SQL語句,2-動態PL/SQL語句,其餘-查詢語句
  pRESET_IN IN BOOLEAN:=TRUE          --是否從新計時,默認每次執行SQL語句均從新計時
)
AS
  pTBNAME VARCHAR2(30);
BEGIN
  IF pRESET_IN THEN
    START_TIMER;                      --從新開始計時
  END IF;
  IF pSQLTEXT IS NOT NULL THEN 
    IF pSQLTYPE=1 THEN                --執行動態sql語句
      EXECUTE IMMEDIATE pSQLTEXT;       
    ELSIF pSQLTYPE=2 THEN             --將SQL語句封裝到BEGIN-END匿名塊中,保證不管傳什麼樣的字符串都會被做爲一個有效的PL/SQL塊執行
      EXECUTE IMMEDIATE 'BEGIN '||CHR(10)||RTRIM(pSQLTEXT,';')||'; '||CHR(10)||'END;'; --注意語句結束必須帶';'結束符,不然報錯
    ELSE                              --經過建立臨時表的模式進行間接計算查詢SQL語句消耗時間,此方式測算查詢語句時間不許確,最好仍是經過查看執行計劃來分析
      pTBNAME:='TMP_'||LPAD(SYS_GUID(),25); 
      EXECUTE IMMEDIATE 'CREATE GLOBAL TEMPORARY TABLE '||pTBNAME||' AS SELECT * FROM('||pSQLTEXT||') TB'; 
    END IF;
  END IF;
  SYS.DBMS_OUTPUT.PUT_LINE('執行耗時:'||ELAPSED_TIME||'毫秒!');
  IF pTBNAME IS NOT NULL THEN         --用完直接刪除臨時表
    EXECUTE IMMEDIATE 'DROP TABLE '||pTBNAME;   
  END IF;
  COMMIT;
  EXCEPTION 
	WHEN OTHERS THEN 
    SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'執行動態SQL語句出錯:' ||SQLERRM);
    RAISE;
END;
END;
/
create or replace PACKAGE PKG_GET_DDL
AS 
--功能:獲取用戶下對象的源碼,主要利用到dbms_metadata.get_ddl包,也能夠查詢dba_source視圖來進行相關操做
PROCEDURE GET_DDL(
  pUSER 		IN 	VARCHAR2:=USER,		        --用戶 
  pREUSER   IN  VARCHAR2,                 --轉換爲新的用戶
  pMODE     IN  NUMBER:=0,                --是否模糊匹配,0-模糊匹配,1-精確匹配
  LIKENAME 	IN 	VARCHAR2:=NULL,		        --模糊搜索條件,返回全部匹配對象的源碼
  TAG 			IN 	NUMBER:=0, 				        --對象類型
  pSQLTEXT 	OUT CLOB							        --源碼文本
);

--功能:獲取用戶下具備依賴關係的對象(如函數、過程、視圖、包)的源碼,主要利用到dbms_metadata.get_ddl包,也能夠查詢dba_source視圖來進行相關操做
PROCEDURE GET_DEPEND_DDL(
  pUSER 		IN 	VARCHAR2:=USER,		        --用戶 
  pREUSER   IN  VARCHAR2,                 --轉換爲新的用戶,默認不轉換 
  pSQLTEXT 	OUT CLOB							        --源碼文本
);

--功能:保存用戶下對象的源碼到單個文件或多個文件中
PROCEDURE SAVE_DDL(
  pUSER 		IN 	VARCHAR2:=USER,		        --用戶 
  pREUSER   IN  VARCHAR2:=NULL,           --轉換爲新的用戶,默認不轉換
  pMODE     IN  NUMBER:=0,                --是否模糊匹配,0-模糊匹配,1-精確匹配
  LIKENAME 	IN 	VARCHAR2:=NULL,						--模糊搜索條件,返回全部匹配對象的源碼
  TAG 			IN 	NUMBER:=0, 								--對象類型 
	pISMERGE	IN 	NUMBER:=0,								--保存到單個文件仍是多個文件,默認爲0-單個文件,其餘-多個文件
	DIR 			IN 	VARCHAR2:='DATA_PUMP_DIR',--目錄名稱(若是不填,則使用當前數據庫目錄)
  FILENAME 	IN 	VARCHAR:=NULL							--單個文件的文件名稱
);
END;
/
create or replace PACKAGE BODY PKG_GET_DDL
AS 
PROCEDURE GET_DDL
--功能:獲取用戶下對象的源碼,主要利用到dbms_metadata.get_ddl包,也能夠查詢dba_source視圖來進行相關操做
--參數: 
--調用:
/*
DECLARE pSQLTEXT CLOB;
BEGIN
	PKG_GET_DDL.GET_DDL('DKGLL','',0,'USR_INFOTAB',12,pSQLTEXT);
	DBMS_OUTPUT.PUT_LINE(pSQLTEXT);
	PKG_DBMANAGE.CLOB_TO_FILE('BACKDIR','('||TO_CHAR(CURRENT_DATE,'YYYYMMDDHH24')||').sql',1,pSQLTEXT); --保存到文件
END;
*/
--日期:2013-03-01
(
  pUSER 		IN 	VARCHAR2:=USER,		--用戶 
  pREUSER   IN  VARCHAR2,         --源對象轉換爲新的用戶
  pMODE     IN  NUMBER:=0,        --是否模糊匹配,0-模糊匹配,1-精確匹配
  LIKENAME 	IN 	VARCHAR2:=NULL,		--模糊搜索條件,返回全部匹配對象的源碼
  TAG 			IN 	NUMBER:=0, 				--對象類型
  pSQLTEXT 	OUT CLOB							--源碼文本
) 
--操做均基於指定用戶下進行,其餘用戶不作處理
--0.所有
--1.序列
--2.表(未解決鍵/索引對應關係以及建立前後順序問題,需注意)
--3.索引
--4.觸發器
--5.視圖
--6.類型
--7.函數
--8.過程
--9.包
--10.同義詞
--11.JAVA SOURCE
--12:實體化視圖
AS 
  pCURROBJTYPE    VARCHAR2(200):=' ';
	pCOUNT		      INT;
	DDL_TEXT 	      CLOB;
  pREPLACEUSER    VARCHAR2(200);
BEGIN 
--  --該版本能夠修改對象的擁有者爲新的用戶,但需解決ORA-04030嘗試分配字節時進程內存不足的問題
--	FOR X IN( 
--		SELECT OBJECT_TYPE,OBJECT_NAME FROM SYS.DBA_OBJECTS 
--			WHERE OWNER=pUSER 
--				AND ((pMODE=0 AND OBJECT_NAME LIKE '%'||LIKENAME||'%' OR INSTR(','||LIKENAME||',',','||OBJECT_NAME||',',1)>0) 
--          OR (pMODE=1 AND OBJECT_NAME=LIKENAME)
--        ) AND OBJECT_TYPE IN('SEQUENCE','TABLE','INDEX','TRIGGER','VIEW','TYPE','FUNCTION','PROCEDURE','PACKAGE')
--				AND OBJECT_TYPE=DECODE(TAG,0,OBJECT_TYPE,1,'SEQUENCE',2,'TABLE',3,'INDEX',4,'TRIGGER',5,'VIEW',6,'TYPE',7,'FUNCTION',8,'PROCEDURE',9,'PACKAGE') 
--        AND ((OBJECT_TYPE='TYPE' AND OBJECT_NAME  NOT LIKE 'SYS_PLSQL_%') OR (OBJECT_TYPE<>'TYPE'))
--			ORDER BY DECODE(OBJECT_TYPE,'SEQUENCE',1,'TABLE',2,'INDEX',3,'TRIGGER',4,'VIEW',5,'TYPE',6,'FUNCTION',7,'PROCEDURE',8,'PACKAGE',9)
--	)
--	LOOP
--    V_HANDLE:=SYS.DBMS_METADATA.OPEN(X.OBJECT_TYPE);
--    SYS.DBMS_METADATA.SET_FILTER(v_HANDLE,'NAME',X.OBJECT_NAME,X.OBJECT_TYPE);
--
--    v_TRANS_HANDLE:=SYS.DBMS_METADATA.ADD_TRANSFORM(v_HANDLE,'MODIFY');
--    IF pREUSER IS NOT NULL THEN
--      SYS.DBMS_METADATA.SET_REMAP_PARAM(v_TRANS_HANDLE,'REMAP_SCHEMA',pUSER,pREUSER); 
--    END IF;
--    v_TRANS_HANDLE:=SYS.DBMS_METADATA.ADD_TRANSFORM(v_HANDLE,'DDL');
--    
--    --確保每一個語句都帶分號
--    SYS.DBMS_METADATA.SET_TRANSFORM_PARAM(v_TRANS_HANDLE,'SQLTERMINATOR',TRUE);
--    --若是是獲取表對象的DDL語句,則去除STORAGE、PCTFREE等多餘參數 
--    IF X.OBJECT_TYPE='TABLE' THEN
--      SYS.DBMS_METADATA.SET_TRANSFORM_PARAM(v_TRANS_HANDLE,'STORAGE',FALSE); 
--      SYS.DBMS_METADATA.SET_TRANSFORM_PARAM(v_TRANS_HANDLE,'SEGMENT_ATTRIBUTES',FALSE); 
--    END IF;
--    
--    DDL_TEXT:=SYS.DBMS_METADATA.FETCH_CLOB(V_HANDLE);    
--    
--		IF X.OBJECT_TYPE<>'TABLE' THEN
--			SELECT COUNT(1) INTO pCOUNT FROM DUAL WHERE REGEXP_LIKE(RTRIM(DDL_TEXT),'/$');           
--			IF pCOUNT=0 THEN          			--若是不存在換行結束符則需加上'/'
--				DDL_TEXT:=TRIM(DDL_TEXT)||CHR(10)||'/';
--			END IF;
--			IF X.OBJECT_TYPE='PACKAGE' THEN	--修正包體與包聲明之間沒有換行結束符報錯的BUG
--				DDL_TEXT:=REPLACE(DDL_TEXT,'CREATE OR REPLACE PACKAGE BODY','/'||CHR(10)||'CREATE OR REPLACE PACKAGE BODY');
--			END IF;
--    ELSIF INSTR(DDL_TEXT,';')=0 THEN
--      DDL_TEXT:=TRIM(DDL_TEXT)||';';
--		END IF;
--		pSQLTEXT:=pSQLTEXT||DDL_TEXT;  
--  END LOOP; 

  SELECT DECODE(pREUSER,pUSER,pREUSER,DECODE(pREUSER,NULL,'','"'||pREUSER||'".')) INTO pREPLACEUSER FROM DUAL;
	FOR X IN
  ( 
		SELECT DECODE(OBJECT_TYPE,'JAVA SOURCE','JAVA_SOURCE','MATERIALIZED VIEW','MATERIALIZED_VIEW',OBJECT_TYPE) AS OBJECT_TYPE,OBJECT_NAME FROM SYS.DBA_OBJECTS 
			WHERE OWNER=pUSER 
				AND ((pMODE=0 AND OBJECT_NAME LIKE '%'||LIKENAME||'%' OR INSTR(','||LIKENAME||',',','||OBJECT_NAME||',',1)>0) 
          OR (pMODE=1 AND OBJECT_NAME=LIKENAME)
        ) AND OBJECT_TYPE IN('SEQUENCE','TABLE','INDEX','TRIGGER','VIEW','TYPE','FUNCTION','PROCEDURE','PACKAGE','SYNONYM','JAVA SOURCE','MATERIALIZED VIEW')
				AND OBJECT_TYPE=DECODE(TAG,0,OBJECT_TYPE,1,'SEQUENCE',2,'TABLE',3,'INDEX',4,'TRIGGER',5,'VIEW',6,'TYPE',7,'FUNCTION',8,'PROCEDURE',9,'PACKAGE',10,'SYNONYM',11,'JAVA SOURCE',12,'MATERIALIZED VIEW') 
        AND ((OBJECT_TYPE='TYPE' AND OBJECT_NAME  NOT LIKE 'SYS_PLSQL_%') OR (OBJECT_TYPE<>'TYPE'))
			ORDER BY DECODE(OBJECT_TYPE,'SEQUENCE',1,'TABLE',2,'INDEX',3,'TRIGGER',4,'VIEW',5,'TYPE',6,'FUNCTION',7,'PROCEDURE',8,'PACKAGE',9,'SYNONYM',10,'JAVA_SOURCE',11,'MATERIALIZED_VIEW',12)
	)
	LOOP
    --確保每一個語句都帶分號
    SYS.DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'SQLTERMINATOR',TRUE);
    --去除STORAGE、PCTFREE等多餘參數
    SYS.DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'STORAGE',FALSE); 
    SYS.DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'SEGMENT_ATTRIBUTES',FALSE);
    
		SELECT SYS.dbms_metadata.get_ddl(X.OBJECT_TYPE,X.OBJECT_NAME,pUSER) INTO DDL_TEXT FROM DUAL;
    IF X.OBJECT_TYPE<>'TABLE' AND  X.OBJECT_TYPE<>'INDEX' THEN
			SELECT COUNT(1) INTO pCOUNT FROM DUAL WHERE REGEXP_LIKE(RTRIM(DDL_TEXT),'/$');           
			IF pCOUNT=0 THEN          			--若是不存在換行結束符則需加上'/'
				DDL_TEXT:=TRIM(DDL_TEXT)||CHR(10)||'/';
			END IF;
			IF X.OBJECT_TYPE='PACKAGE' THEN	--修正包體與包聲明之間沒有換行結束符報錯的BUG 
				DDL_TEXT:=REGEXP_REPLACE(DDL_TEXT,'CREATE OR REPLACE PACKAGE BODY "'||pUSER||'".','/'||CHR(10)||'CREATE OR REPLACE PACKAGE BODY '||pREPLACEUSER,1,1);
			END IF;
    ELSIF INSTR(DDL_TEXT,';')=0 THEN
      DDL_TEXT:=TRIM(DDL_TEXT)||';';
		END IF;
    --替換對象的擁有者爲新的用戶,注意:若是爲包、觸發器,則包體、觸發器的修改也須要進行二次替換
    IF pREUSER<>pUSER OR pREUSER IS NULL THEN 
      IF (X.OBJECT_TYPE='TABLE' OR X.OBJECT_TYPE='INDEX') THEN     --若是是TABLE或INDEX,則須要所有替換對象擁有者以及對象依賴得表的擁有者爲新的用戶      
        pSQLTEXT:=pSQLTEXT||REPLACE(DDL_TEXT,'"'||pUSER||'".',pREPLACEUSER);            
      ELSE                 
        pSQLTEXT:=pSQLTEXT||REGEXP_REPLACE(DDL_TEXT,'"'||pUSER||'".',pREPLACEUSER,1,1);       
      END IF;
      IF X.OBJECT_TYPE='TRIGGER' THEN
        pSQLTEXT:=REPLACE(pSQLTEXT,'ALTER TRIGGER "'||pUSER||'".','ALTER TRIGGER '||pREPLACEUSER);    
      END IF;
    ELSE
      pSQLTEXT:=pSQLTEXT||DDL_TEXT;      
    END IF;
  END LOOP;   
END;

PROCEDURE GET_DEPEND_DDL
--功能:獲取用戶下具備依賴關係的對象(如函數、視圖、過程、包)的源碼,主要利用到dbms_metadata.get_ddl包,也能夠查詢dba_source視圖來進行相關操做
--參數: 
--調用:
/*
DECLARE pSQLTEXT CLOB;
BEGIN
	PKG_GET_DDL.GET_DEPEND_DDL('TEST','',pSQLTEXT);  --pREUSER爲空表示導出該源用戶下的全部依賴關係的對象
	--DBMS_OUTPUT.PUT_LINE(pSQLTEXT);
	PKG_DBMANAGE.CLOB_TO_FILE('BACKDIR','('||TO_CHAR(CURRENT_DATE,'YYYYMMDDHH24')||').sql',1,pSQLTEXT); --保存到文件
END;
*/
--日期:2016-02-16
(
  pUSER 		IN 	VARCHAR2:=USER,		--用戶 
  pREUSER   IN  VARCHAR2,         --源對象轉換爲新的用戶
  pSQLTEXT 	OUT CLOB							--源碼文本
) 
AS 
  pCURROBJTYPE    VARCHAR2(200):=' ';
	pCOUNT		      INT;
	DDL_TEXT 	      CLOB;
  pREPLACEUSER    VARCHAR2(200);
BEGIN  
  --若是替換的用戶名稱爲空,則表示不須要該用戶前綴 
  SELECT DECODE(pREUSER,pUSER,pREUSER,DECODE(pREUSER,NULL,'','"'||pREUSER||'".')) INTO pREPLACEUSER FROM DUAL;
	FOR X IN
  ( 
		WITH TB AS (
      SELECT * FROM SYS.DBA_DEPENDENCIES 
        WHERE OWNER=pUSER 
          AND REFERENCED_OWNER=pUSER
          AND TYPE IN ('FUNCTION','PROCEDURE','VIEW') 
      UNION ALL
      SELECT * FROM SYS.DBA_DEPENDENCIES 
        WHERE OWNER=pUSER 
          AND REFERENCED_OWNER=pUSER
          AND REFERENCED_TYPE='PACKAGE'
          AND TYPE IN ('PACKAGE BODY') 
          AND NAME<>REFERENCED_NAME
    ) 
    SELECT T1.OWNER,T1.OBJECT_NAME,T1.OBJECT_TYPE,T2.ML,TOP_NAME FROM (
      SELECT * FROM SYS.DBA_OBJECTS WHERE OWNER=pUSER AND OBJECT_TYPE IN ('FUNCTION','PROCEDURE','VIEW','PACKAGE')
    ) T1 LEFT JOIN (
      SELECT DISTINCT TOP_NAME,ML FROM (
        SELECT REFERENCED_NAME,TOP_NAME,LN,MAX(LN) OVER(PARTITION BY TOP_NAME) AS ML FROM (
          SELECT "REFERENCED_NAME",CONNECT_BY_ROOT "REFERENCED_NAME" AS TOP_NAME,LEVEL AS LN FROM TB  
          CONNECT BY PRIOR "REFERENCED_NAME"="NAME"
          ORDER BY "REFERENCED_NAME",LN 
        )
      ) WHERE LN=ML
    ) T2 ON T1.OBJECT_NAME=T2.TOP_NAME
      ORDER BY ML,TOP_NAME 
	)
	LOOP
    --確保每一個語句都帶分號
    SYS.DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'SQLTERMINATOR',TRUE);
    --去除STORAGE、PCTFREE等多餘參數
    SYS.DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'STORAGE',FALSE); 
    SYS.DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'SEGMENT_ATTRIBUTES',false);
    
		SELECT SYS.dbms_metadata.get_ddl(X.OBJECT_TYPE,X.OBJECT_NAME,pUSER) INTO DDL_TEXT FROM DUAL;
    IF X.OBJECT_TYPE<>'TABLE' AND  X.OBJECT_TYPE<>'INDEX' THEN
			SELECT COUNT(1) INTO pCOUNT FROM DUAL WHERE REGEXP_LIKE(RTRIM(DDL_TEXT),'/$');           
			IF pCOUNT=0 THEN          			--若是不存在換行結束符則需加上'/'
				DDL_TEXT:=TRIM(DDL_TEXT)||CHR(10)||'/';
			END IF;
			IF X.OBJECT_TYPE='PACKAGE' THEN	--修正包體與包聲明之間沒有換行結束符報錯的BUG
				DDL_TEXT:=REGEXP_REPLACE(DDL_TEXT,'CREATE OR REPLACE PACKAGE BODY "'||pUSER||'".','/'||CHR(10)||'CREATE OR REPLACE PACKAGE BODY '||pREPLACEUSER,1,1);
			END IF;
    ELSIF INSTR(DDL_TEXT,';')=0 THEN
      DDL_TEXT:=TRIM(DDL_TEXT)||';';
		END IF;
    --替換對象的擁有者爲新的用戶,注意:若是爲包、觸發器,則包體、觸發器的修改也須要進行二次替換
    IF pREUSER<>pUSER OR pREUSER IS NULL THEN
      pSQLTEXT:=pSQLTEXT||REGEXP_REPLACE(DDL_TEXT,'"'||pUSER||'".',pREPLACEUSER,1,1); 
      IF X.OBJECT_TYPE='TRIGGER' THEN
        pSQLTEXT:=REPLACE(pSQLTEXT,'ALTER TRIGGER "'||pUSER||'".','ALTER TRIGGER '||pREPLACEUSER);    
      END IF;
    ELSE
      pSQLTEXT:=pSQLTEXT||DDL_TEXT;      
    END IF;
  END LOOP;   
END;
			
PROCEDURE SAVE_DDL
--功能:保存用戶下對象的源碼到單個文件或多個文件中
--參數: 
--調用:
/*
BEGIN
	PKG_GET_DDL.SAVE_DDL
	(
		DBUSER=>NULL,
		LIKENAME=>'PKG',
		TAG=>9,
		pISMERGE=>0,
		DIR=>'BACKDIR',
		FILENAME=>'管理包0429.sql'
	);
END;
*/
--日期:2014-04-28
(
  pUSER 		IN 	VARCHAR2:=USER,						--用戶
  pREUSER   IN  VARCHAR2:=NULL,           --源對象轉換爲新的用戶,默認不轉換
  pMODE     IN  NUMBER:=0,                --是否模糊匹配,0-模糊匹配,1-精確匹配
  LIKENAME 	IN 	VARCHAR2:=NULL,						--模糊搜索條件,返回全部匹配對象的源碼
  TAG 			IN 	NUMBER:=0, 								--對象類型 
	pISMERGE	IN 	NUMBER:=0,								--保存到單個文件仍是多個文件,默認爲0-單個文件,其餘-多個文件
	DIR 			IN 	VARCHAR2:='DATA_PUMP_DIR',--目錄名稱(若是不填,則使用當前數據庫目錄)
  FILENAME 	IN 	VARCHAR:=NULL							--單個文件的文件名稱
)
AS
	pCOUNT		INT;
	pSQLTEXT 	CLOB;
BEGIN 
	IF pISMERGE=0 THEN											--保存全部對象源碼到單個文件 
		GET_DDL(pUSER,pREUSER,pMODE,LIKENAME,TAG,pSQLTEXT);	--獲取用戶下對象的源碼
		PKG_DBMANAGE.CLOB_TO_FILE(DIR,NVL(FILENAME,'源碼('||TO_CHAR(CURRENT_DATE,'YYYYMMDDHH24')||').sql'),1,pSQLTEXT); --保存源碼到文件
	ELSE 																		--分別保存對象源碼到單獨的文件中去,單獨文件的名稱取對象名稱
		FOR X IN
    (  
      SELECT OBJECT_TYPE,OBJECT_NAME FROM SYS.DBA_OBJECTS 
        WHERE OWNER=pUSER 
          AND ((pMODE=0 AND OBJECT_NAME LIKE '%'||LIKENAME||'%' OR INSTR(','||LIKENAME||',',','||OBJECT_NAME||',',1)>0) 
            OR (pMODE=1 AND OBJECT_NAME=LIKENAME)
          ) AND OBJECT_TYPE IN('SEQUENCE','TABLE','INDEX','TRIGGER','VIEW','TYPE','FUNCTION','PROCEDURE','PACKAGE')
          AND OBJECT_TYPE=DECODE(TAG,0,OBJECT_TYPE,1,'SEQUENCE',2,'TABLE',3,'INDEX',4,'TRIGGER',5,'VIEW',6,'TYPE',7,'FUNCTION',8,'PROCEDURE',9,'PACKAGE') 
          AND ((OBJECT_TYPE='TYPE' AND OBJECT_NAME  NOT LIKE 'SYS_PLSQL_%') OR (OBJECT_TYPE<>'TYPE'))
        ORDER BY DECODE(OBJECT_TYPE,'SEQUENCE',1,'TABLE',2,'INDEX',3,'TRIGGER',4,'VIEW',5,'TYPE',6,'FUNCTION',7,'PROCEDURE',8,'PACKAGE',9)
		)
		LOOP 
      PKG_GET_DDL.GET_DDL(pUSER,pREUSER,1,X.OBJECT_NAME,TAG,pSQLTEXT);
			PKG_DBMANAGE.CLOB_TO_FILE(DIR,X.OBJECT_NAME||'('||TO_CHAR(CURRENT_DATE,'YYYYMMDDHH24')||').sql',1,pSQLTEXT);
		END LOOP; 
	END IF;
END;
END;
/
create or replace PACKAGE PKG_COMPAREDB
AS
--功能:基於指定用戶下修改列類型,暫時只處理CLOB類型、NVARCHR到其餘類型的轉換等
PROCEDURE UPDATE_COL_TYPE(
  pUSER       IN  VARCHAR2,
  pTABLENAME  IN  VARCHAR2,
  pCOLNAME    IN  VARCHAR2,
  pNEWCOLTYPE IN  VARCHAR2,
  pOLDCOLTYPE IN  VARCHAR2:=NULL,
  pATTR       IN  VARCHAR2,
  pNULLTEXT   IN  VARCHAR2,
  pSQLTEXT    OUT CLOB
);

--功能:獲取對比修改序列的語句
PROCEDURE COMPARE_SEQUENCE(
	pSOURCEUSER 	IN VARCHAR2, 				--源用戶名
	pTARGETUSER 	IN VARCHAR2, 				--目標用戶名
	pSEQUENCENAME IN VARCHAR2:=NULL,	--源序列名,能夠爲一個或多個序列,多個序列以','分隔,爲空則選擇全部序列
  pSQLTEXT      OUT CLOB
);

--功能:獲取對比修改表的SQL語句,注意:此處pSOURCEUSER,pTARGETUSER,pTABLENAME默認所有爲大寫.因爲獲取源碼權限問題,該過程只能在源用戶庫上執行
PROCEDURE COMPARE_TABLE(
	pSOURCEUSER 	IN VARCHAR2, 				--源用戶名
	pTARGETUSER 	IN VARCHAR2, 				--目標用戶名
	pTABLENAME 	  IN VARCHAR2:=NULL,	--源表,能夠爲一張或多張表,多個表以','分隔,爲空則選擇結構類型一致的全部表
  pDROPTABLE    IN  NUMBER:=1,      --是否刪除表:0-不刪除,其餘-刪除,默認-刪除
  pSQLTEXT      OUT CLOB
);

--功能:因爲觸發器錯誤可能致使系統異常,須要對觸發器進行比對處理
PROCEDURE COMPARE_TRIGGER(
	pSOURCEUSER 	IN VARCHAR2, 				--源用戶名
	pTARGETUSER 	IN VARCHAR2, 				--目標用戶名
  pSQLTEXT      OUT CLOB
);

--功能:獲取對比修改JOB的SQL語句
PROCEDURE COMPARE_JOB(
	pSOURCEUSER 	IN VARCHAR2, 				--源用戶名
	pTARGETUSER 	IN VARCHAR2, 				--目標用戶名
  pTAG          IN PLS_INTEGER,     --0-比較,1:不比較,直接獲取全部源碼
  pSQLTEXT      OUT CLOB
);

--功能:獲取對比修改SCHEDULER JOB的SQL語句
PROCEDURE COMPARE_SCHEDULER(
	pSOURCEUSER 	IN VARCHAR2, 				--源用戶名
	pTARGETUSER 	IN VARCHAR2, 				--目標用戶名
  pTAG          IN PLS_INTEGER,     --0-比較,1:不比較,直接獲取全部源碼
  pSQLTEXT      OUT CLOB
);

--功能:獲取對比修改數據庫對象的SQL語句.注意因爲獲取源碼權限問題,該過程只能在源用戶庫上執行
PROCEDURE COMPARE_DB(
	pSOURCEUSER 	IN  VARCHAR2, 			--源用戶名
	pTARGETUSER 	IN  VARCHAR2,  			--目標用戶名
  pOBJTYPE      IN  NUMBER,         --對象類型,0-對比表、序列、類型,1-導出全部具備依賴關係的對象(視圖、函數、過程、包),2-在1的基礎上導出全部觸發器
  pDROPTABLE    IN  NUMBER:=1,      --是否刪除表:0-不刪除,其餘-刪除,默認-刪除
  pSQLTEXT      OUT CLOB
);
END;
/
create or replace PACKAGE BODY "PKG_COMPAREDB"
AS
PROCEDURE UPDATE_COL_TYPE
--功能:基於指定用戶下修改列類型,暫時只處理CLOB類型、NVARCHR到其餘類型以及NUMBER類型的轉換等
--注意:若是該列有主外鍵、索引、約束則會修改失敗
--參數:pUSER-數據庫用戶,pTABLENAME-表名,pNEWCOLTYPE-修改以後的列類型,pOLDCOLTYPE-修改以前的列類型(若是爲空,則不對原始類型作特定處理),pCOLNAME-要修改的原始列名
--調用:
/*
DECLARE
  PUSER VARCHAR2(200);
  PTABLENAME VARCHAR2(200);
  PCOLNAME VARCHAR2(200);
  PNEWCOLTYPE VARCHAR2(200);
  pATTR VARCHAR2(200);
  PSQLTEXT CLOB;
BEGIN
  PUSER := 'DKGLL';
  PTABLENAME := 'ALM_ALARMDEVICE';
  PCOLNAME := 'DVRNAME';
  PNEWCOLTYPE := 'VARCHAR2(64 BYTE)';
  pATTR :=' DEFAULT ''21''''211'' NOT NULL ';
  PKG_COMPAREDB.UPDATE_COL_TYPE(
    PUSER => PUSER,
    PTABLENAME => PTABLENAME,
    PCOLNAME => PCOLNAME,
    PNEWCOLTYPE => PNEWCOLTYPE,
    pATTR => pATTR,
    pNULLTEXT => 'NOT NULL',
    PSQLTEXT => PSQLTEXT
  );
  DBMS_OUTPUT.PUT_LINE('PSQLTEXT = ' || PSQLTEXT);
END;
*/
--日期:2016-01-27
(
  pUSER       IN  VARCHAR2,
  pTABLENAME  IN  VARCHAR2,
  pCOLNAME    IN  VARCHAR2,
  pNEWCOLTYPE IN  VARCHAR2,
  pOLDCOLTYPE IN  VARCHAR2:=NULL,
  pATTR       IN  VARCHAR2,
  pNULLTEXT   IN  VARCHAR2,
  pSQLTEXT    OUT CLOB
)
AS
  pCOUNT        PLS_INTEGER;
  pDATACOUNT    NUMBER:=9999;
  pCOMMCOUNT    PLS_INTEGER;
  pCOLTYPE      VARCHAR2(50);
  pMIDTB        VARCHAR2(30);
  pNEWCOLTYPE1  VARCHAR2(30);
  pCOMMENT      VARCHAR2(4000);
BEGIN
  SELECT COUNT(1) INTO pCOUNT FROM SYS.DBA_TAB_COLUMNS WHERE OWNER=pUSER AND TABLE_NAME=pTABLENAME AND COLUMN_NAME=pCOLNAME AND DATA_TYPE NOT LIKE '%CLOB';
  IF pCOUNT=1 THEN        --表、列存在而且列不爲CLOB類型則進行修改
    SELECT CASE
      WHEN pNEWCOLTYPE LIKE '%CLOB' OR pNEWCOLTYPE LIKE '%NUMBER%' OR pOLDCOLTYPE LIKE 'N%CHAR%' OR pOLDCOLTYPE LIKE '%NUMBER%' THEN pNEWCOLTYPE
      ELSE 'CLOB' END INTO pNEWCOLTYPE1
      FROM DUAL;
    SELECT COUNT(1) INTO pCOUNT FROM SYS.DBA_TAB_COLUMNS WHERE OWNER=pUSER AND TABLE_NAME=pTABLENAME AND COLUMN_NAME=pCOLNAME AND DATA_TYPE='LONG';
    IF pNEWCOLTYPE LIKE '%NUMBER%' OR pOLDCOLTYPE LIKE '%NUMBER%' THEN
      EXECUTE IMMEDIATE 'SELECT COUNT(1) FROM "'||pUSER||'"."'||pTABLENAME||'" WHERE '||pCOLNAME||' IS NOT NULL ' INTO pDATACOUNT;
    END IF;
    --非LONG類型、NUMBER字段不爲空時須要經過創建中間列的方式進行修改
    --注意:此處需解決原有列的主外鍵、約束、默認值、索引、列註釋等問題
    IF pCOUNT=0 AND pDATACOUNT>0 THEN
      --pMIDTB:='MID_'||TO_CHAR(SYSTIMESTAMP,'YYYYMMDDHH24MISSFF3');
      pMIDTB:='MID_'||SUBSTR(REPLACE(SYS.DBMS_RANDOM.VALUE(1,9),'.',''),1,16);
      pSQLTEXT:='ALTER TABLE "'||pUSER||'"."'||pTABLENAME||'" ADD '||pMIDTB||' '||pNEWCOLTYPE1||pATTR||';';
      IF pATTR LIKE '%NOT NULL%' THEN
        pSQLTEXT:=pSQLTEXT||CHR(10)||'DELETE "'||pUSER||'"."'||pTABLENAME||'" WHERE "'||pCOLNAME||'" IS NULL;';
      END IF;
      pSQLTEXT:=pSQLTEXT||CHR(10)||'UPDATE "'||pUSER||'"."'||pTABLENAME||'" SET '||pMIDTB||'=TO_CHAR("'||pCOLNAME||'");';
      pSQLTEXT:=pSQLTEXT||CHR(10)||'ALTER TABLE "'||pUSER||'"."'||pTABLENAME||'" DROP COLUMN "'||pCOLNAME||'";';
      pSQLTEXT:=pSQLTEXT||CHR(10)||'ALTER TABLE "'||pUSER||'"."'||pTABLENAME||'" RENAME COLUMN '||pMIDTB||' TO "'||pCOLNAME||'";';

      SELECT COUNT(1) INTO pCOMMCOUNT FROM SYS.DBA_COL_COMMENTS WHERE OWNER=pUSER AND TABLE_NAME=pTABLENAME AND COLUMN_NAME=pCOLNAME;
      IF pCOMMCOUNT>0 THEN
        SELECT 'COMMENT ON COLUMN "'||pUSER||'"."'||TABLE_NAME||'"."'||COLUMN_NAME||'" IS '''||REPLACE(COMMENTS,'''','''''')||''';' INTO pCOMMENT FROM SYS.DBA_COL_COMMENTS
          WHERE OWNER=pUSER AND TABLE_NAME=pTABLENAME AND COLUMN_NAME=pCOLNAME;
        pSQLTEXT:=pSQLTEXT||CHR(10)||pCOMMENT;
      END IF;
    ELSE                  --LONG類型可直接修改成CLOB類型,NUMBER類型爲空時也能夠修改成其餘類型
      pSQLTEXT:='ALTER TABLE "'||pUSER||'"."'||pTABLENAME||'" MODIFY ("'||pCOLNAME||'" '||pNEWCOLTYPE||pNULLTEXT||');';
    END IF;
  END IF;
END;

PROCEDURE COMPARE_SEQUENCE
--功能:獲取對比修改序列的語句
--參數:
--調用:
/*
DECLARE pSQLTEXT CLOB;
BEGIN
	PKG_COMPAREDB.COMPARE_SEQUENCE('TEST','',NULL,pSQLTEXT);
  --DBMS_OUTPUT.PUT_LINE(pSQLTEXT);
  PKG_DBMANAGE.CLOB_TO_FILE('BACKDIR','('||TO_CHAR(CURRENT_DATE,'YYYYMMDDHH24')||').sql','1',pSQLTEXT);
END;
*/
--日期:2016-02-10
(
	pSOURCEUSER 	IN VARCHAR2, 				--源用戶名
	pTARGETUSER 	IN VARCHAR2, 				--目標用戶名
	pSEQUENCENAME IN VARCHAR2:=NULL,	--源序列名,能夠爲一個或多個序列,多個序列以','分隔,爲空則選擇全部序列
  pSQLTEXT      OUT CLOB
)
AS
  pSEQTEXT        VARCHAR2(1000);
  pREPLACEUSER    VARCHAR2(200);
  pMIN_VALUE1     NUMBER;           --源序列最小值
  pMIN_VALUE2     NUMBER;           --目標序列最小值
  pMAX_VALUE1     NUMBER;
  pMAX_VALUE2     NUMBER;
  pINCREMENT_BY1  NUMBER;
  pINCREMENT_BY2  NUMBER;
  pCACHE_SIZE1    NUMBER;
  pCACHE_SIZE2    NUMBER;
  pORDER_FLAG1    CHAR(10);
  pORDER_FLAG2    CHAR(10);
  pCYCLE_FLAG1    CHAR(10);
  pCYCLE_FLAG2    CHAR(10);
BEGIN
  --若是目標用戶爲空,則表示不須要該用戶前綴
  SELECT DECODE(pTARGETUSER,NULL,'','"'||pTARGETUSER||'".') INTO pREPLACEUSER FROM DUAL;
  --1:源序列存在而目標序列不存在則添加
  FOR X IN
  (
    SELECT * FROM SYS.DBA_SEQUENCES TA WHERE SEQUENCE_OWNER=pSOURCEUSER
      AND (INSTR(','||pSEQUENCENAME||',',','||SEQUENCE_NAME||',',1)>0 OR pSEQUENCENAME IS NULL)
      AND NOT EXISTS (
        SELECT * FROM SYS.DBA_SEQUENCES WHERE SEQUENCE_OWNER=pTARGETUSER AND SEQUENCE_NAME=TA.SEQUENCE_NAME
      )
  )
  LOOP
    SELECT 'CREATE SEQUENCE  '||pREPLACEUSER||'"'||X.SEQUENCE_NAME||'"  MINVALUE '||X.MIN_VALUE||' MAXVALUE '||X.MAX_VALUE||
      ' INCREMENT BY '||X.INCREMENT_BY||' START WITH '||X.LAST_NUMBER||
      DECODE(X.CACHE_SIZE,0,' NOCACHE',' CACHE '||X.CACHE_SIZE)||
      DECODE(X.ORDER_FLAG,'Y',' ORDER',' NOORDER')||
      DECODE(X.CYCLE_FLAG,'Y',' CYCLE',' NOCYCLE')||';'
      INTO pSEQTEXT FROM DUAL;
    IF pSQLTEXT IS NOT NULL THEN
      pSQLTEXT:=pSQLTEXT||CHR(10)||pSEQTEXT;
    ELSE
      pSQLTEXT:=pSEQTEXT;
    END IF;
  END LOOP;
  --2:源序列不存在而目標序列存在則刪除
  FOR X IN
  (
    SELECT * FROM SYS.DBA_SEQUENCES TA WHERE SEQUENCE_OWNER=pTARGETUSER
      AND (INSTR(','||pSEQUENCENAME||',',','||SEQUENCE_NAME||',',1)>0 OR pSEQUENCENAME IS NULL)
      AND NOT EXISTS (
        SELECT * FROM SYS.DBA_SEQUENCES WHERE SEQUENCE_OWNER=pSOURCEUSER AND SEQUENCE_NAME=TA.SEQUENCE_NAME
      )
  )
  LOOP
    pSQLTEXT:=pSQLTEXT||CHR(10)||'DROP SEQUENCE '||pREPLACEUSER||X.SEQUENCE_NAME||';';
  END LOOP;
  --3:原序列、目標序列均存在且源序列的屬性與目標序列的屬性不一樣則進行修改,因爲序列屬性可能依賴於業務數據的變化,故暫定一旦序列創建,不在單獨修改序列的屬性
END;

PROCEDURE COMPARE_TRIGGER
--功能:因爲觸發器錯誤可能致使系統異常,須要對觸發器進行比對處理
--參數:
--調用:
/*
DECLARE pSQLTEXT CLOB;
BEGIN
	PKG_COMPAREDB.COMPARE_TRIGGER('DKGLL','',pSQLTEXT);
  --DBMS_OUTPUT.PUT_LINE(pSQLTEXT);
  PKG_DBMANAGE.CLOB_TO_FILE('BACKDIR','('||TO_CHAR(CURRENT_DATE,'YYYYMMDDHH24')||').sql','1',pSQLTEXT);
END;
*/
--日期:2016-02-18
(
	pSOURCEUSER 	IN VARCHAR2, 				--源用戶名
	pTARGETUSER 	IN VARCHAR2, 				--目標用戶名
  pSQLTEXT      OUT CLOB
)
AS
BEGIN
  --1:源TRIGGER不存在而目標TRIGGER存在則刪除
  --2:源TRIGGER與目標TRIGGER的狀態不一致需進行修改
  FOR X IN
  (
    SELECT 'DROP TRIGGER "'||pTARGETUSER||'"."'||TRIGGER_NAME||'";' AS TRIGTEXT FROM SYS.DBA_TRIGGERS TA WHERE OWNER=pTARGETUSER
      AND NOT EXISTS (
        SELECT * FROM SYS.DBA_TRIGGERS WHERE OWNER=pSOURCEUSER AND TRIGGER_NAME=TA.TRIGGER_NAME
      )
    UNION ALL
    SELECT 'ALTER TRIGGER "'||pTARGETUSER||'".'||TA.TRIGGER_NAME||TA.STATUS AS TRIGTEXT FROM SYS.DBA_TRIGGERS TA
      JOIN SYS.DBA_TRIGGERS TB ON (TA.OWNER=pTARGETUSER AND TB.OWNER=pSOURCEUSER AND TA.TRIGGER_NAME=TB.TRIGGER_NAME AND TA.STATUS<>TB.STATUS)
  )
  LOOP
    IF pSQLTEXT IS NOT NULL THEN
      pSQLTEXT:=pSQLTEXT||CHR(10)||X.TRIGTEXT;
    ELSE
      pSQLTEXT:=X.TRIGTEXT;
    END IF;
  END LOOP;
END;

PROCEDURE COMPARE_JOB
--功能:獲取對比修改JOB的SQL語句
--參數:
--調用:
/*
DECLARE pSQLTEXT CLOB;
BEGIN
	PKG_COMPAREDB.COMPARE_JOB('TEST','',pSQLTEXT);
  DBMS_OUTPUT.PUT_LINE(pSQLTEXT);
  --PKG_DBMANAGE.CLOB_TO_FILE('BACKDIR','('||TO_CHAR(CURRENT_DATE,'YYYYMMDDHH24')||').sql','1',pSQLTEXT);
END;
*/
--日期:2016-02-18
(
	pSOURCEUSER 	IN VARCHAR2, 				--源用戶名
	pTARGETUSER 	IN VARCHAR2, 				--目標用戶名
  pTAG          IN PLS_INTEGER,     --0-比較,1:不比較,直接獲取全部源碼
  pSQLTEXT      OUT CLOB
)
AS
  pJOBTEXT      VARCHAR2(2000);
  pREPLACEUSER  VARCHAR2(200);
BEGIN
  SELECT NVL(pTARGETUSER,USER) INTO pREPLACEUSER FROM DUAL;
  --原則上一個JOB經過WHAT(幹什麼),INTERVAL(執行間隔時間)來區分
  --1:源JOB存在而目標JOB不存在則添加
  FOR X IN
  (
    SELECT * FROM SYS.DBA_JOBS TA WHERE LOG_USER=pSOURCEUSER AND PRIV_USER=pSOURCEUSER AND SCHEMA_USER=pSOURCEUSER
      AND (
        NOT EXISTS (
          SELECT * FROM SYS.DBA_JOBS WHERE pTAG=0 AND LOG_USER=pTARGETUSER AND PRIV_USER=pTARGETUSER AND SCHEMA_USER=pTARGETUSER AND UPPER("WHAT")=UPPER(TA."WHAT") AND UPPER("INTERVAL")=UPPER(TA."INTERVAL")
        ) OR pTAG=1
      )
  )
  LOOP
    pJOBTEXT:='DECLARE JOBNO NUMBER;'||CHR(10)||
              '  pCOUNT PLS_INTEGER;'||CHR(10)||
              'BEGIN'||CHR(10)||
              '  SELECT COUNT(1) INTO pCOUNT FROM SYS.DBA_JOBS TA WHERE LOG_USER='''||pREPLACEUSER||''' AND PRIV_USER='''||pREPLACEUSER||''' AND SCHEMA_USER='''||pREPLACEUSER||''' AND WHAT='''||X.WHAT||''' AND interval= '''||X.INTERVAL||''';'||CHR(10)||
              '  IF pCOUNT = 0 THEN'||CHR(10)||
              '   SYS.DBMS_JOB.SUBMIT(job => JOBNO,'||CHR(10)||
              '                       what => '''||X.WHAT||''','||CHR(10)||
              '                       next_date => TO_DATE('''||TO_CHAR(X.NEXT_DATE,'YYYY-MM-DD HH24:MI:SS')||''',''YYYY-MM-DD HH24:MI:SS''),'||CHR(10)||
              '                       interval => '''||X.INTERVAL||''');'||CHR(10)||
              '   COMMIT;'||CHR(10)||
              '  END IF;'||CHR(10)||
              'END;'||CHR(10)||
              '/';
    IF pSQLTEXT IS NOT NULL THEN
      pSQLTEXT:=pSQLTEXT||CHR(10)||pJOBTEXT;
    ELSE
      pSQLTEXT:=pJOBTEXT;
    END IF;
  END LOOP;
  --2:源JOB不存在而目標JOB存在則刪除
  FOR X IN
  (
    SELECT * FROM SYS.DBA_JOBS TA WHERE LOG_USER=pTARGETUSER AND PRIV_USER=pTARGETUSER AND SCHEMA_USER=pTARGETUSER
      AND NOT EXISTS (
        SELECT * FROM SYS.DBA_JOBS WHERE LOG_USER=pSOURCEUSER AND PRIV_USER=pSOURCEUSER AND SCHEMA_USER=pSOURCEUSER AND UPPER("WHAT")=UPPER(TA."WHAT") AND UPPER("INTERVAL")=UPPER(TA."INTERVAL")
      )
  )
  LOOP
    pJOBTEXT:='DECLARE pCOUNT PLS_INTEGER;'||CHR(10)||
              'BEGIN'||CHR(10)||
              '  SELECT COUNT(1) INTO pCOUNT FROM SYS.DBA_JOBS TA WHERE LOG_USER='''||pREPLACEUSER||''' AND PRIV_USER='''||pREPLACEUSER||''' AND SCHEMA_USER='''||pREPLACEUSER||''' AND WHAT='''||X.WHAT||''' AND interval= '''||X.INTERVAL||''';'||CHR(10)||
              '  IF pCOUNT <> 0 THEN'||CHR(10)||
              '   DBMS_JOB.REMOVE('||X.JOB||'); '||CHR(10)||
              '   COMMIT;'||CHR(10)||
              '  END IF;'||CHR(10)||
              'END;'||CHR(10)||
              '/';
    IF pSQLTEXT IS NOT NULL THEN
      pSQLTEXT:=pSQLTEXT||CHR(10)||pJOBTEXT;
    ELSE
      pSQLTEXT:=pJOBTEXT;
    END IF;
  END LOOP;
END;

PROCEDURE COMPARE_SCHEDULER
--功能:獲取對比修改SCHEDULER JOB的SQL語句
--參數:
--調用:
/*
DECLARE pSQLTEXT CLOB;
BEGIN
	PKG_COMPAREDB.COMPARE_SCHEDULER('TEST','DKGLL',1,pSQLTEXT);
  DBMS_OUTPUT.PUT_LINE(pSQLTEXT);
  --PKG_DBMANAGE.CLOB_TO_FILE('BACKDIR','('||TO_CHAR(CURRENT_DATE,'YYYYMMDDHH24')||').sql','1',pSQLTEXT);
END;
*/
--日期:2016-02-18
(
	pSOURCEUSER 	IN VARCHAR2, 				--源用戶名
	pTARGETUSER 	IN VARCHAR2, 				--目標用戶名
  pTAG          IN PLS_INTEGER,     --0-比較,1:不比較,直接獲取全部源碼,
  pSQLTEXT      OUT CLOB
)
AS
  pREPLACEUSER    VARCHAR2(200);
  pSCHEDULERTEXT  VARCHAR2(4000);
  pCREATEJOBTEXT  VARCHAR2(4000);
  pATTRTEXT       VARCHAR2(4000);
  pLOGLEVEL       VARCHAR2(200);
BEGIN
  SELECT NVL(pTARGETUSER,USER) INTO pREPLACEUSER FROM DUAL;
  --1:源SCHEDULER JOB存在而目標SCHEDULER JOB不存在則添加
  FOR X IN
  (
    SELECT * FROM SYS.DBA_SCHEDULER_JOBS TA WHERE OWNER=pSOURCEUSER
      AND (
        NOT EXISTS (
          SELECT * FROM SYS.DBA_SCHEDULER_JOBS WHERE pTAG=0 AND OWNER=pTARGETUSER AND UPPER("JOB_NAME")=UPPER(TA."JOB_NAME")
        ) OR pTAG=1
      )
  )
  LOOP
    pCREATEJOBTEXT := '';
    pATTRTEXT := '';
    SELECT DECODE(X.LOGGING_LEVEL,'OFF','LOGGING_OFF','FAILED RUNS','LOGGING_FAILED_RUNS','RUNS','LOGGING_RUNS','FULL','LOGGING_FULL') INTO pLOGLEVEL FROM DUAL;
    pCREATEJOBTEXT := '    DBMS_SCHEDULER.CREATE_JOB ('||CHR(10)||
                      '            job_name => ''"'||pREPLACEUSER||'"."'||X.JOB_NAME||'"'','||CHR(10)||
                      '            job_type => '''||X.JOB_TYPE||''','||CHR(10)||
                      '            job_action => '''||pREPLACEUSER||'.'||LTRIM(X.JOB_ACTION,pSOURCEUSER||'.')||''','||CHR(10)||
                      '            number_of_arguments => '||X.number_of_arguments||','||CHR(10)||
                      '            start_date => TO_TIMESTAMP_TZ('''||TO_CHAR(X.START_DATE,'YYYY-MM-DD HH24:MI:SS:FF4')||''',''YYYY-MM-DD HH24:MI:SS.FF TZR''),'||CHR(10)||
                      '            repeat_interval => '''||X.REPEAT_INTERVAL||''','||CHR(10)||
                      '            end_date => TO_TIMESTAMP_TZ('''||TO_CHAR(X.END_DATE,'YYYY-MM-DD HH24:MI:SS:FF4')||''',''YYYY-MM-DD HH24:MI:SS.FF TZR''),'||CHR(10)||
                      '            enabled => '||X.ENABLED||','||CHR(10)||
                      '            auto_drop =>  '||X.AUTO_DROP||','||CHR(10)||
                      '            comments => '''||X.COMMENTS||''');'||CHR(10);
    IF X.RESTARTABLE IS NOT NULL THEN
      pATTRTEXT := pATTRTEXT||CHR(10)||'    DBMS_SCHEDULER.SET_ATTRIBUTE( '||CHR(10)||
                   '             name => ''"'||pREPLACEUSER||'"."'||X.JOB_NAME||'"'','||CHR(10)||
                   '             attribute => ''restartable'', value => '||X.RESTARTABLE||');'||CHR(10);
    END IF;

    --並行查詢暫時有問題
--    IF X.RESTARTABLE IS NOT NULL THEN
--      pATTRTEXT := pATTRTEXT||CHR(10)||'    DBMS_SCHEDULER.SET_ATTRIBUTE( '||CHR(10)||
--                   '             name => ''"'||pREPLACEUSER||'"."'||X.JOB_NAME||'"'','||CHR(10)||
--                   '             attribute => ''parallel_instances'', value => '||X.RESTARTABLE||');'||CHR(10);
--    END IF;

    IF X.job_priority IS NOT NULL THEN
      pATTRTEXT := pATTRTEXT||CHR(10)||'    DBMS_SCHEDULER.SET_ATTRIBUTE( '||CHR(10)||
                   '             name => ''"'||pREPLACEUSER||'"."'||X.JOB_NAME||'"'','||CHR(10)||
                   '             attribute => ''job_priority'', value => '||X.job_priority||');'||CHR(10);
    END IF;

    IF pLOGLEVEL IS NOT NULL THEN
      pATTRTEXT := pATTRTEXT||CHR(10)||'    DBMS_SCHEDULER.SET_ATTRIBUTE( '||CHR(10)||
                   '             name => ''"'||pREPLACEUSER||'"."'||X.JOB_NAME||'"'','||CHR(10)||
                   '             attribute => ''logging_level'', value => DBMS_SCHEDULER.'||pLOGLEVEL||');'||CHR(10);
    END IF;

    IF X.INSTANCE_ID IS NOT NULL THEN
      pATTRTEXT := pATTRTEXT||CHR(10)||'    DBMS_SCHEDULER.SET_ATTRIBUTE( '||CHR(10)||
                   '             name => ''"'||pREPLACEUSER||'"."'||X.JOB_NAME||'"'','||CHR(10)||
                   '             attribute => ''instance_id'', value => '||X.INSTANCE_ID||');'||CHR(10);
    END IF;

    IF X.MAX_FAILURES IS NOT NULL THEN
      pATTRTEXT := pATTRTEXT||CHR(10)||'    DBMS_SCHEDULER.SET_ATTRIBUTE( '||CHR(10)||
                   '             name => ''"'||pREPLACEUSER||'"."'||X.JOB_NAME||'"'','||CHR(10)||
                   '             attribute => ''max_failures'', value => '||X.MAX_FAILURES||');'||CHR(10);
    END IF;

    IF X.MAX_RUNS IS NOT NULL THEN
      pATTRTEXT := pATTRTEXT||CHR(10)||'    DBMS_SCHEDULER.SET_ATTRIBUTE( '||CHR(10)||
                   '             name => ''"'||pREPLACEUSER||'"."'||X.JOB_NAME||'"'','||CHR(10)||
                   '             attribute => ''max_runs'', value => '||X.MAX_RUNS||');'||CHR(10);
    END IF;

    IF X.max_run_duration IS NOT NULL THEN
      pATTRTEXT := pATTRTEXT||CHR(10)||'    DBMS_SCHEDULER.SET_ATTRIBUTE( '||CHR(10)||
                   '             name => ''"'||pREPLACEUSER||'"."'||X.JOB_NAME||'"'','||CHR(10)||
                   '             attribute => ''max_run_duration'', value => to_dsinterval('''||X.max_run_duration||'''));'||CHR(10);
    END IF;

    IF X.SCHEDULE_LIMIT IS NOT NULL THEN
      pATTRTEXT := pATTRTEXT||CHR(10)||'    DBMS_SCHEDULER.SET_ATTRIBUTE( '||CHR(10)||
                   '             name => ''"'||pREPLACEUSER||'"."'||X.JOB_NAME||'"'','||CHR(10)||
                   '             attribute => ''SCHEDULE_LIMIT'', value => to_dsinterval('''||X.SCHEDULE_LIMIT||'''));'||CHR(10);
    END IF;

    pSCHEDULERTEXT := 'DECLARE pCOUNT PLS_INTEGER;'||CHR(10)||
                      'BEGIN'||CHR(10)||
                      '  SELECT COUNT(1) INTO pCOUNT FROM SYS.DBA_SCHEDULER_JOBS TA WHERE OWNER='''||pREPLACEUSER||''' AND UPPER("JOB_NAME")=UPPER('''||X.JOB_NAME||''');'||CHR(10)||
                      '  IF pCOUNT = 0 THEN'||CHR(10)||pCREATEJOBTEXT||pATTRTEXT||CHR(10)||
                      '    DBMS_SCHEDULER.enable('||CHR(10)||
                      '             name => ''"'||pREPLACEUSER||'"."'||X.JOB_NAME||'"'');'||CHR(10)||
                      '  END IF;'||CHR(10)||
                      'END;'||CHR(10)||
                      '/';
    IF pSQLTEXT IS NOT NULL THEN
      pSQLTEXT:=pSQLTEXT||CHR(10)||pSCHEDULERTEXT;
    ELSE
      pSQLTEXT:=pSCHEDULERTEXT;
    END IF;
  END LOOP;
  --2:源SCHEDULER JOB不存在而目標SCHEDULER JOB存在則刪除
  FOR X IN
  (
    SELECT * FROM SYS.DBA_SCHEDULER_JOBS TA WHERE OWNER=pTARGETUSER
      AND NOT EXISTS (
        SELECT * FROM SYS.DBA_SCHEDULER_JOBS WHERE OWNER=pSOURCEUSER AND UPPER("JOB_NAME")=UPPER(TA."JOB_NAME")
      )
  )
  LOOP
    pSCHEDULERTEXT := 'DECLARE pCOUNT PLS_INTEGER;'||CHR(10)||
                      'BEGIN'||CHR(10)||
                      '  SELECT COUNT(1) INTO pCOUNT FROM SYS.DBA_SCHEDULER_JOBS TA WHERE OWNER='''||pREPLACEUSER||''' AND UPPER("JOB_NAME")=UPPER('''||X.JOB_NAME||''');'||CHR(10)||
                      '  IF pCOUNT <> 0 THEN'||CHR(10)||
                      '   DBMS_SCHEDULER.DROP_JOB(job_name => ''"'||X.JOB_NAME||'"'','||CHR(10)||
                      '                           defer => false,'||CHR(10)||
                      '                           force => false);'||CHR(10)||
                      '  END IF;'||CHR(10)||
                      'END;'||CHR(10)||
                      '/';
    IF pSQLTEXT IS NOT NULL THEN
      pSQLTEXT:=pSQLTEXT||CHR(10)||pSCHEDULERTEXT;
    ELSE
      pSQLTEXT:=pSCHEDULERTEXT;
    END IF;
  END LOOP;
END;

PROCEDURE COMPARE_TABLE
--功能:獲取對比修改表的SQL語句,注意:此處pSOURCEUSER,pTARGETUSER,pTABLENAME默認所有爲大寫.因爲獲取源碼權限問題,該過程只能在源用戶庫上執行
--參數:
--調用:
/*
DECLARE pSQLTEXT CLOB;
BEGIN
	PKG_COMPAREDB.COMPARE_TABLE('TEST','DKGLL','',1,pSQLTEXT); --pTARGETUSER爲空表示導出該源用戶下的全部表
  --DBMS_OUTPUT.PUT_LINE(pSQLTEXT);
  PKG_DBMANAGE.CLOB_TO_FILE('BACKDIR','('||TO_CHAR(CURRENT_DATE,'YYYYMMDDHH24')||').sql','1',pSQLTEXT);
END;
*/
--日期:2016-02-10
(
	pSOURCEUSER 	IN VARCHAR2, 				--源用戶名
	pTARGETUSER 	IN VARCHAR2, 				--目標用戶名
	pTABLENAME 	  IN VARCHAR2:=NULL,	--源表,能夠爲一張或多張表,多個表以','分隔,爲空則選擇結構類型一致的全部表
  pDROPTABLE    IN  NUMBER:=1,      --是否刪除表:0-不刪除,其餘-刪除,默認-刪除
  pSQLTEXT      OUT CLOB
)
AS
  pINDEX          PLS_INTEGER;
  pCOUNT          PLS_INTEGER;
  pCOUNT1         PLS_INTEGER;
  pCOUNT2         PLS_INTEGER;
  pATTR           VARCHAR2(2000);
  pUPDATECOL      VARCHAR2(4000);
  pREPLACEUSER    VARCHAR2(200);          --替換目標用戶的文本,如"DKGLL".
  pSOURCECODE     CLOB;                   --源DDL源碼
  pTARGETCODE     CLOB;                   --目標DDL源碼
  pTBCOMMENT      VARCHAR2(4000);         --表註釋文本
  pFOREIGN        VARCHAR2(2000);         --外鍵語句
  pPRIMARY        VARCHAR2(2000);         --依賴主鍵部分語句
  pREBULIDFORRIGN VARCHAR2(2000):='';     --重建外鍵語句
  pRULECODE       VARCHAR2(4000);         --約束(檢查、惟一)語句
  pTAG            CHAR(20);               --標誌是否須要修改
BEGIN
  pINDEX:=0;
  --若是目標用戶爲空,則表示不須要該用戶前綴
  SELECT DECODE(pTARGETUSER,NULL,'','"'||pTARGETUSER||'".') INTO pREPLACEUSER FROM DUAL;
  --1:源表存在而目標表不存在則添加,須要解決主外鍵的依賴關係,經過遞歸外鍵依賴表的鏈路進行排序,先添加主鍵表,再添加外鍵表
  FOR X IN
  (
    WITH TB AS (
      SELECT TB.CONSTRAINT_NAME,TB.CONSTRAINT_TYPE,TB.TABLE_NAME,TC.CONSTRAINT_NAME AS R_CONSTRAINT_NAME,TC.TABLE_NAME AS R_TABLE_NAME,TC.CONSTRAINT_TYPE AS R_CONSTRAINT_TYPE FROM SYS.DBA_CONSTRAINTS TB
        LEFT JOIN  SYS.DBA_CONSTRAINTS TC ON (TB.R_OWNER=TC.OWNER AND TB.R_CONSTRAINT_NAME=TC.CONSTRAINT_NAME)
       WHERE TB.OWNER=pSOURCEUSER AND TB.CONSTRAINT_TYPE IN('P','R')
        AND (INSTR(','||pTABLENAME||',',','||TB.TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL)
        AND TB.TABLE_NAME<>TC.TABLE_NAME   --加上此條件是爲了防止當表中外鍵列依賴於本表主鍵列是會在下邊的查詢中報conect by循環錯誤
    )
    SELECT T1.*,T2.ML FROM (
      SELECT * FROM SYS.DBA_TABLES TA WHERE OWNER=pSOURCEUSER
        AND (INSTR(','||pTABLENAME||',',','||TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL)
        AND NOT EXISTS (
          SELECT * FROM SYS.DBA_TABLES WHERE OWNER=pTARGETUSER AND TABLE_NAME=TA.TABLE_NAME
        )
    ) T1 LEFT JOIN (
      SELECT * FROM (
        SELECT DISTINCT TABLE_NAME,ML FROM (
          SELECT TABLE_NAME,TOPTABLE_NAME,LN,MAX(LN) OVER(PARTITION BY TABLE_NAME) AS ML FROM (
            SELECT DISTINCT TABLE_NAME,CONNECT_BY_ROOT TABLE_NAME AS TOPTABLE_NAME,LEVEL AS LN FROM TB
              CONNECT BY PRIOR TABLE_NAME=R_TABLE_NAME ORDER BY TABLE_NAME,LN
           )
        ) WHERE LN=ML
      )
    ) T2 ON T1.TABLE_NAME=T2.TABLE_NAME
      ORDER BY NVL(ML,-1),T1.TABLE_NAME
  )
  LOOP
    SELECT COUNT(1) INTO pCOUNT2 FROM SYS.DBA_OBJECTS WHERE OWNER=pSOURCEUSER AND OBJECT_NAME=X.TABLE_NAME AND OBJECT_TYPE='MATERIALIZED VIEW';
    IF pCOUNT2=0 THEN
      IF pINDEX=0 THEN
        pSQLTEXT:='--開始添加新表--------------------------------------------------------------------';
      END IF;
      pINDEX:=pINDEX+1;
      --1.1:獲取建表的源碼
      PKG_GET_DDL.GET_DDL(pSOURCEUSER,pTARGETUSER,1,X.TABLE_NAME,2,pSOURCECODE);
      pSQLTEXT:=pSQLTEXT||pSOURCECODE;
      --1.2:獲取列註釋
      FOR Y IN
      (
        SELECT 'COMMENT ON COLUMN '||pREPLACEUSER||'"'||TABLE_NAME||'"."'||COLUMN_NAME||'" IS '''||REPLACE(COMMENTS,'''','''''')||''';' AS COLCOMMENT
          FROM SYS.DBA_COL_COMMENTS WHERE OWNER=pSOURCEUSER AND TABLE_NAME=X.TABLE_NAME AND COMMENTS IS NOT NULL
      )
      LOOP
        pSQLTEXT:=pSQLTEXT||CHR(10)||Y.COLCOMMENT;
      END LOOP;
      --1.3:獲取表註釋
      SELECT COUNT(1) INTO pCOUNT FROM SYS.DBA_TAB_COMMENTS WHERE OWNER=pSOURCEUSER AND TABLE_NAME=X.TABLE_NAME AND COMMENTS IS NOT NULL;
      IF pCOUNT=1 THEN
        SELECT 'COMMENT ON TABLE '||pREPLACEUSER||'"'||TABLE_NAME||'" IS '''||REPLACE(COMMENTS,'''','''''')||''';' INTO pTBCOMMENT FROM SYS.DBA_TAB_COMMENTS WHERE OWNER=pSOURCEUSER AND TABLE_NAME=X.TABLE_NAME AND COMMENTS IS NOT NULL;
        pSQLTEXT:=pSQLTEXT||CHR(10)||pTBCOMMENT||CHR(10);
      ELSE
        pSQLTEXT:=pSQLTEXT||CHR(10);
      END IF;
      --1.4:獲取索引源碼
      FOR Y IN
      (
        SELECT INDEX_NAME FROM SYS.DBA_INDEXES TA WHERE OWNER=pSOURCEUSER AND TABLE_NAME=X.TABLE_NAME AND INDEX_NAME NOT LIKE 'BIN$%' AND INDEX_TYPE NOT IN('LOB')
          AND NOT EXISTS (
            SELECT * FROM SYS.DBA_CONSTRAINTS WHERE OWNER=pSOURCEUSER AND TABLE_NAME=TA.TABLE_NAME AND INDEX_NAME=TA.INDEX_NAME
          )
      )
      LOOP
        PKG_GET_DDL.GET_DDL(pSOURCEUSER,pTARGETUSER,1,Y.INDEX_NAME,3,pSOURCECODE);
        pSQLTEXT:=pSQLTEXT||pSOURCECODE;
      END LOOP;
    END IF;
  END LOOP;
  IF pINDEX>0 THEN
    pSQLTEXT:=pSQLTEXT||CHR(10)||('--添加新表結束!-------------------------------------------------------------------')||CHR(10);
    pINDEX:=0;
  END IF;

  IF pDROPTABLE<>0 THEN
    --2:源表不存在而目標表存在則刪除表,須要解決主外鍵的依賴關係,經過遞歸外鍵依賴表的鏈路進行排序,先刪除外鍵表,再刪除主鍵表
    --此處:若是目的數據庫包含OPENFIRE表,建議最好進行過濾,不然會致使出現問題
    FOR X IN
    (
      WITH TB AS (
        SELECT TB.CONSTRAINT_NAME,TB.CONSTRAINT_TYPE,TB.TABLE_NAME,TC.CONSTRAINT_NAME AS R_CONSTRAINT_NAME,TC.TABLE_NAME AS R_TABLE_NAME,TC.CONSTRAINT_TYPE AS R_CONSTRAINT_TYPE FROM SYS.DBA_CONSTRAINTS TB
          LEFT JOIN  SYS.DBA_CONSTRAINTS TC ON (TB.R_OWNER=TC.OWNER AND TB.R_CONSTRAINT_NAME=TC.CONSTRAINT_NAME)
         WHERE TB.OWNER=pTARGETUSER AND TB.CONSTRAINT_TYPE IN('P','R')
          AND (INSTR(','||pTABLENAME||',',','||TB.TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL)
          AND TB.TABLE_NAME<>TC.TABLE_NAME   --加上此條件是爲了防止當表中外鍵列依賴於本表主鍵列是會在下邊的查詢中報conect by循環錯誤
      )
      SELECT T1.*,T2.ML FROM (
        SELECT * FROM SYS.DBA_TABLES TA WHERE OWNER=pTARGETUSER
          AND (INSTR(','||pTABLENAME||',',','||TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL)
          AND NOT EXISTS (
            SELECT * FROM SYS.DBA_TABLES WHERE OWNER=pSOURCEUSER AND TABLE_NAME=TA.TABLE_NAME
          )
      ) T1 LEFT JOIN (
        SELECT * FROM (
          SELECT DISTINCT TABLE_NAME,ML FROM (
            SELECT TABLE_NAME,TOPTABLE_NAME,LN,MAX(LN) OVER(PARTITION BY TABLE_NAME) AS ML FROM (
              SELECT DISTINCT TABLE_NAME,CONNECT_BY_ROOT TABLE_NAME AS TOPTABLE_NAME,LEVEL AS LN FROM TB
                CONNECT BY PRIOR TABLE_NAME=R_TABLE_NAME ORDER BY TABLE_NAME,LN
             )
          ) WHERE LN=ML
        )
      ) T2 ON T1.TABLE_NAME=T2.TABLE_NAME
        ORDER BY ML DESC,T1.TABLE_NAME
    )
    LOOP
      IF X.TABLE_NAME NOT LIKE 'OF%' THEN    --OPENFIRE表的表以OF開頭
        SELECT COUNT(1) INTO pCOUNT2 FROM SYS.DBA_OBJECTS WHERE OWNER=pTARGETUSER AND OBJECT_NAME=X.TABLE_NAME AND OBJECT_TYPE='MATERIALIZED VIEW';
        IF pCOUNT2=0 THEN
          IF pINDEX=0 THEN
            pSQLTEXT:=pSQLTEXT||CHR(10)||('--開始刪除沒必要要的表---------------------------------------------------------------');
          END IF;
          pINDEX:=pINDEX+1;
          --pSQLTEXT:=pSQLTEXT||CHR(10)||'DROP TABLE "'||pTARGETUSER||'".'||X.TABLE_NAME||';';
          pSQLTEXT:=pSQLTEXT||CHR(10)||'EXEC PKG_DBMANAGE.DROP_OBJECT('''||pTARGETUSER||''','''||X.TABLE_NAME||''');';
        END IF;
      END IF;
    END LOOP;
    IF pINDEX>0 THEN
      pSQLTEXT:=pSQLTEXT||CHR(10)||('--刪除沒必要要的表結束!--------------------------------------------------------------')||CHR(10);
      pINDEX:=0;
    END IF;
  END IF;

  DELETE FROM TEMP_TAB_COLUMNS;
  --3:修改表列類型、表註釋、列註釋.特例:臨時表與普通表不能重名,不然修改沒法按照主外鍵的鏈路順序進行重建,只能簡單的進行刪除重建
  FOR X IN
  (
    SELECT TA.*,TB.TEMPORARY AS TEMPORARY2 FROM (
      SELECT * FROM SYS.DBA_TABLES TA WHERE OWNER=pTARGETUSER
        AND (INSTR(','||pTABLENAME||',',','||TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL)
    ) TA JOIN (
      SELECT * FROM SYS.DBA_TABLES TA WHERE OWNER=pSOURCEUSER
        AND (INSTR(','||pTABLENAME||',',','||TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL)
    ) TB ON TA.TABLE_NAME=TB.TABLE_NAME
  )
  LOOP
    --表類型相同
    IF X.TEMPORARY=X.TEMPORARY2 THEN
      --修改表列類型
      INSERT INTO TEMP_TAB_COLUMNS(OWNER,TABLE_NAME,COLUMN_NAME,DATA_TYPE,ORACLETYPE,NULLABLE,DATA_DEFAULT,COLUMN_ID)
      SELECT OWNER,TABLE_NAME,COLUMN_NAME,DATA_TYPE,
        CASE WHEN DATA_TYPE IN('NUMBER') THEN REPLACE(DATA_TYPE||'('||NVL(TO_CHAR(DATA_PRECISION),'*') ||','||NVL(TO_CHAR(DATA_SCALE),'*') ||')','(*,*)','')
          WHEN DATA_TYPE IN ('VARCHAR2','NVARCHAR2','CHAR','NCHAR') THEN DATA_TYPE||'('||CHAR_LENGTH||')'
          WHEN DATA_TYPE IN ('FLOAT') THEN DATA_TYPE||'('||DATA_PRECISION||')'
          ELSE DATA_TYPE END AS ORACLETYPE,NULLABLE,TO_LOB(DATA_DEFAULT) AS DATA_DEFAULT,COLUMN_ID FROM SYS.DBA_TAB_COLUMNS
        WHERE OWNER IN (pSOURCEUSER,pTARGETUSER)
          AND TABLE_NAME=X.TABLE_NAME
          AND (INSTR(','||pTABLENAME||',',','||TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL)
          ORDER BY TABLE_NAME,COLUMN_ID;
      FOR Y1 IN
      (
        SELECT 'ALTER TABLE '||pREPLACEUSER||'"'||X.TABLE_NAME||'"'||
          DECODE(OPRTYPE,'ADD',' ADD "'||COLUMN_NAME1||'" '||ORACLETYPE1,'MOD',' MODIFY "'||COLUMN_NAME1||'" '||ORACLETYPE1,'DROP',' DROP COLUMN '||COLUMN_NAME2,'') AS SQLTEXT,
          DECODE(NULLABLE1,NULLABLE2,'',DECODE(NULLABLE1,'N',' NOT NULL','Y',' NULL')) AS NULL_SQLTEXT,
          DECODE(DATA_DEFAULT1,'NULL','',' DEFAULT '||DATA_DEFAULT1) AS DATA_DEFAULT,
          'ALTER TABLE '||pREPLACEUSER||'"'||X.TABLE_NAME||'" MODIFY ("'||COLUMN_NAME1||'" DEFAULT '||DECODE(DATA_DEFAULT1,'NULL','NULL',DATA_DEFAULT1)||');' AS DEFAULT_SQLTEXT,OPRTYPE,
          DATA_DEFAULT1,DATA_DEFAULT2,NULLABLE1,ORACLETYPE1,DATA_TYPE1,DATA_TYPE2,COLUMN_NAME1,COLUMN_ID1,COLUMN_ID2 FROM (
            SELECT TA.TABLE_NAME,
              TA.COLUMN_NAME AS COLUMN_NAME1,TA.DATA_TYPE AS DATA_TYPE1,TA.ORACLETYPE AS ORACLETYPE1,TA.NULLABLE AS NULLABLE1,TA.DATA_DEFAULT AS DATA_DEFAULT1,
              TC.COLUMN_NAME AS COLUMN_NAME2,TC.DATA_TYPE AS DATA_TYPE2,TC.ORACLETYPE AS ORACLETYPE2,TC.NULLABLE AS NULLABLE2,TC.DATA_DEFAULT AS DATA_DEFAULT2,
              CASE WHEN TC.ORACLETYPE||TC.NULLABLE IS NULL THEN 'ADD'
                WHEN TA.ORACLETYPE||TA.NULLABLE IS NULL THEN 'DROP'
                WHEN NVL(TC.ORACLETYPE||TC.NULLABLE,' ')<>TA.ORACLETYPE||TA.NULLABLE THEN 'MOD'
                ELSE '' END AS OPRTYPE,TA.COLUMN_ID AS COLUMN_ID1,TC.COLUMN_ID AS COLUMN_ID2 FROM (
              SELECT TABLE_NAME,COLUMN_NAME,DATA_TYPE,ORACLETYPE,TRIM(NULLABLE) AS NULLABLE,TO_CHAR(NVL(DATA_DEFAULT,'NULL')) AS DATA_DEFAULT,COLUMN_ID FROM TEMP_TAB_COLUMNS WHERE OWNER=pSOURCEUSER AND TABLE_NAME=X.TABLE_NAME
            ) TA FULL JOIN (
              SELECT TABLE_NAME,COLUMN_NAME,DATA_TYPE,ORACLETYPE,TRIM(NULLABLE) AS NULLABLE,TO_CHAR(NVL(DATA_DEFAULT,'NULL')) AS DATA_DEFAULT,COLUMN_ID FROM TEMP_TAB_COLUMNS WHERE OWNER=pTARGETUSER AND TABLE_NAME=X.TABLE_NAME
            ) TC ON (TA.TABLE_NAME=TC.TABLE_NAME AND TA.COLUMN_NAME=TC.COLUMN_NAME)
          ) WHERE OPRTYPE IS NOT NULL OR ASCII(DATA_DEFAULT1)<>ASCII(DATA_DEFAULT2)
            ORDER BY DECODE(OPRTYPE,'ADD',1,'MOD',2,'DROP',3),COLUMN_ID1,COLUMN_ID2
      )
      LOOP
        IF Y1.OPRTYPE IS NOT NULL AND (Y1.DATA_TYPE2 NOT LIKE '%CLOB' OR Y1.DATA_TYPE2 IS NULL) THEN    --此處暫時不處理CLOB類型到其餘類型的轉化
          pINDEX:=pINDEX+1;
          IF pINDEX=1 THEN
            pSQLTEXT:=pSQLTEXT||CHR(10)||('--開始修改表類型、列類型、表註釋、列註釋----------------------------------------------');
          END IF;
          --此處暫時只處理(其餘類型到CLOB的類型轉換、NVARCHR到其餘類型的轉換等)問題
          --注意:若是該列有主外鍵、索引、約束則會修改失敗
          IF (Y1.OPRTYPE='MOD' AND (Y1.DATA_TYPE1 LIKE '%CLOB' OR Y1.DATA_TYPE1 LIKE '%NUMBER%' OR Y1.DATA_TYPE2 LIKE 'N%CHAR%' OR Y1.DATA_TYPE2 LIKE '%NUMBER%')) THEN
            --DBMS_OUTPUT.PUT_LINE(pTARGETUSER||','||X.TABLE_NAME||','||Y1.COLUMN_NAME1||','||Y1.DATA_TYPE1||','||Y1.NULL_SQLTEXT||' '||Y1.DATA_DEFAULT||pUPDATECOL);
            pUPDATECOL:='';
            IF Y1.DATA_TYPE1 NOT LIKE '%NUMBER%' THEN
              SELECT DECODE(Y1.NULLABLE1,'N',NVL(Y1.DATA_DEFAULT,' DEFAULT ''''')||' NOT NULL','Y',Y1.DATA_DEFAULT||' NULL') INTO pATTR FROM DUAL;
            ELSE
              SELECT DECODE(Y1.NULLABLE1,'N',NVL(Y1.DATA_DEFAULT,' DEFAULT 0')||' NOT NULL','Y',Y1.DATA_DEFAULT||' NULL') INTO pATTR FROM DUAL;
            END IF;
            IF Y1.DATA_TYPE1 LIKE '%CLOB' THEN
              UPDATE_COL_TYPE(pTARGETUSER,X.TABLE_NAME,Y1.COLUMN_NAME1,Y1.DATA_TYPE1,NULL,pATTR,Y1.NULL_SQLTEXT,pUPDATECOL);
            ELSIF Y1.DATA_TYPE1 LIKE '%NUMBER%' OR Y1.DATA_TYPE2 LIKE 'N%CHAR%' OR Y1.DATA_TYPE2 LIKE '%NUMBER%' THEN
              UPDATE_COL_TYPE(pTARGETUSER,X.TABLE_NAME,Y1.COLUMN_NAME1,Y1.ORACLETYPE1,Y1.DATA_TYPE2,pATTR,Y1.NULL_SQLTEXT,pUPDATECOL);
            END IF;
            IF pUPDATECOL IS NOT NULL THEN  --判斷生成修改的語句是否有效,無效則語句爲NULL
              pSQLTEXT:=pSQLTEXT||CHR(10)||pUPDATECOL;
              --若是不爲空的字段自己沒有設置默認值,則須要將默認值改回NULL
              IF Y1.NULLABLE1='N' AND Y1.DATA_DEFAULT IS NULL THEN
                pSQLTEXT:=pSQLTEXT||CHR(10)||'ALTER TABLE '||pREPLACEUSER||'"'||X.TABLE_NAME||'" MODIFY ("'||Y1.COLUMN_NAME1||'" DEFAULT NULL);';
              END IF;
            END IF;
          ELSIF Y1.OPRTYPE<>'DROP' THEN
            IF Y1.OPRTYPE='MOD' AND Y1.NULL_SQLTEXT LIKE '%NOT NULL%' THEN  --若是要修改的列原先爲null,現改成not null,則須要刪除字段值爲null的記錄
              pSQLTEXT:=pSQLTEXT||CHR(10)||'DELETE '||pREPLACEUSER||'"'||X.TABLE_NAME||'" WHERE "'||Y1.COLUMN_NAME1||'" IS NULL;';
            END IF;
            pSQLTEXT:=pSQLTEXT||CHR(10)||Y1.SQLTEXT||Y1.DATA_DEFAULT||Y1.NULL_SQLTEXT||';';
          ELSE
            pSQLTEXT:=pSQLTEXT||CHR(10)||Y1.SQLTEXT||';';
          END IF;
        END IF;
        IF (ASCII(Y1.DATA_DEFAULT1)<>ASCII(Y1.DATA_DEFAULT2) AND NOT (Y1.OPRTYPE='MOD' AND (Y1.DATA_TYPE1 LIKE '%CLOB' OR Y1.DATA_TYPE1 LIKE '%NUMBER%' OR Y1.DATA_TYPE2 LIKE 'N%CHAR%' OR Y1.DATA_TYPE2 LIKE '%NUMBER%'))) THEN
          pINDEX:=pINDEX+1;
          IF pINDEX=1 THEN
            pSQLTEXT:=pSQLTEXT||CHR(10)||('--開始修改表列類型、表註釋、列註釋---------------------------------------------------');
          END IF;
          pSQLTEXT:=pSQLTEXT||CHR(10)||Y1.DEFAULT_SQLTEXT;
        END IF;
      END LOOP;

      --修改表註釋
      FOR Y2 IN
      (
        SELECT 'COMMENT ON TABLE '||pREPLACEUSER||'"'||TABLE_NAME||'" IS '''||REPLACE(COMMENTS,'''','''''')||''';' AS SQLTEXT FROM (
          SELECT TA.TABLE_NAME,TA.COMMENTS,CASE WHEN NVL(TA.COMMENTS,' ')<>NVL(TB.COMMENTS,' ') THEN 'MOD' ELSE '' END AS OPETYPE FROM (
            SELECT * FROM SYS.DBA_TAB_COMMENTS WHERE OWNER=pSOURCEUSER AND TABLE_NAME=X.TABLE_NAME
          ) TA LEFT JOIN (
            SELECT * FROM SYS.DBA_TAB_COMMENTS WHERE OWNER=pTARGETUSER AND TABLE_NAME=X.TABLE_NAME
          ) TB ON TA.TABLE_NAME=TB.TABLE_NAME
        ) WHERE OPETYPE IS NOT NULL
      )
      LOOP
        pINDEX:=pINDEX+1;
        IF pINDEX=1 THEN
          pSQLTEXT:=pSQLTEXT||CHR(10)||('--開始修改表類型、列類型、表註釋、列註釋----------------------------------------------');
        END IF;
        pSQLTEXT:=pSQLTEXT||CHR(10)||Y2.SQLTEXT;
      END LOOP;

      --修改列註釋
      FOR Y3 IN
      (
        SELECT 'COMMENT ON COLUMN '||pREPLACEUSER||'"'||TABLE_NAME||'"."'||COLUMN_NAME||'" IS '''||REPLACE(COMMENTS,'''','''''')||''';' AS SQLTEXT FROM (
          SELECT TA.TABLE_NAME,TA.COLUMN_NAME,TA.COMMENTS,CASE WHEN NVL(TA.COMMENTS,' ')<>NVL(TB.COMMENTS,' ') THEN 'MOD' ELSE '' END AS OPETYPE FROM (
            SELECT * FROM SYS.DBA_COL_COMMENTS WHERE OWNER=pSOURCEUSER AND TABLE_NAME=X.TABLE_NAME
          ) TA LEFT JOIN (
            SELECT * FROM SYS.DBA_COL_COMMENTS WHERE OWNER=pTARGETUSER AND TABLE_NAME=X.TABLE_NAME
          ) TB ON TA.TABLE_NAME=TB.TABLE_NAME AND TA.COLUMN_NAME=TB.COLUMN_NAME
        ) WHERE OPETYPE IS NOT NULL
      )
      LOOP
        pINDEX:=pINDEX+1;
        IF pINDEX=1 THEN
          pSQLTEXT:=pSQLTEXT||CHR(10)||('--開始修改表類型、列類型、表註釋、列註釋----------------------------------------------');
        END IF;
        pSQLTEXT:=pSQLTEXT||CHR(10)||Y3.SQLTEXT;
      END LOOP;
    --表類型不一樣則修改表類型(刪除重建)
    ELSE
      --刪除表
      pSQLTEXT:=pSQLTEXT||CHR(10)||'EXEC PKG_DBMANAGE.DROP_OBJECT('''||pTARGETUSER||''','''||X.TABLE_NAME||''');';
      --重建表,操做步驟與第1步如出一轍
      SELECT COUNT(1) INTO pCOUNT2 FROM SYS.DBA_OBJECTS WHERE OWNER=pSOURCEUSER AND OBJECT_NAME=X.TABLE_NAME AND OBJECT_TYPE='MATERIALIZED VIEW';
      IF pCOUNT2=0 THEN
        pINDEX:=pINDEX+1;
        IF pINDEX=1 THEN
          pSQLTEXT:=pSQLTEXT||CHR(10)||('--開始修改表類型、列類型、表註釋、列註釋----------------------------------------------');
        END IF;
        --1.1:獲取建表的源碼
        PKG_GET_DDL.GET_DDL(pSOURCEUSER,pTARGETUSER,1,X.TABLE_NAME,2,pSOURCECODE);
        pSQLTEXT:=pSQLTEXT||pSOURCECODE;
        --1.2:獲取列註釋
        FOR Y IN
        (
          SELECT 'COMMENT ON COLUMN '||pREPLACEUSER||'"'||TABLE_NAME||'"."'||COLUMN_NAME||'" IS '''||REPLACE(COMMENTS,'''','''''')||''';' AS COLCOMMENT
            FROM SYS.DBA_COL_COMMENTS WHERE OWNER=pSOURCEUSER AND TABLE_NAME=X.TABLE_NAME AND COMMENTS IS NOT NULL
        )
        LOOP
          pSQLTEXT:=pSQLTEXT||CHR(10)||Y.COLCOMMENT;
        END LOOP;
        --1.3:獲取表註釋
        SELECT COUNT(1) INTO pCOUNT FROM SYS.DBA_TAB_COMMENTS WHERE OWNER=pSOURCEUSER AND TABLE_NAME=X.TABLE_NAME AND COMMENTS IS NOT NULL;
        IF pCOUNT=1 THEN
          SELECT 'COMMENT ON TABLE '||pREPLACEUSER||'"'||TABLE_NAME||'" IS '''||REPLACE(COMMENTS,'''','''''')||''';' INTO pTBCOMMENT FROM SYS.DBA_TAB_COMMENTS WHERE OWNER=pSOURCEUSER AND TABLE_NAME=X.TABLE_NAME AND COMMENTS IS NOT NULL;
          pSQLTEXT:=pSQLTEXT||CHR(10)||pTBCOMMENT||CHR(10);
        ELSE
          pSQLTEXT:=pSQLTEXT||CHR(10);
        END IF;
        --1.4:獲取索引源碼
        FOR Y IN
        (
          SELECT INDEX_NAME FROM SYS.DBA_INDEXES TA WHERE OWNER=pSOURCEUSER AND TABLE_NAME=X.TABLE_NAME AND INDEX_NAME NOT LIKE 'BIN$%' AND INDEX_TYPE NOT IN('LOB')
            AND NOT EXISTS (
              SELECT * FROM SYS.DBA_CONSTRAINTS WHERE OWNER=pSOURCEUSER AND TABLE_NAME=TA.TABLE_NAME AND INDEX_NAME=TA.INDEX_NAME
            )
        )
        LOOP
          PKG_GET_DDL.GET_DDL(pSOURCEUSER,pTARGETUSER,1,Y.INDEX_NAME,3,pSOURCECODE);
          pSQLTEXT:=pSQLTEXT||pSOURCECODE;
        END LOOP;
      END IF;
    END IF;
  END LOOP;
  IF pINDEX>0 THEN
    pSQLTEXT:=pSQLTEXT||CHR(10)||('--修改表類型、列類型、表註釋、列註釋結束!---------------------------------------------')||CHR(10);
    pINDEX:=0;
  END IF;

  --4:源外鍵不存在而目標外鍵存在則刪除
  FOR X IN
  (
    SELECT * FROM SYS.DBA_CONSTRAINTS TA WHERE OWNER=pTARGETUSER AND CONSTRAINT_TYPE='R'
      AND TABLE_NAME NOT LIKE 'BIN$%' AND TA.CONSTRAINT_NAME NOT LIKE 'BIN$%'
      AND (INSTR(','||pTABLENAME||',',','||TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL)
      AND NOT EXISTS (
        SELECT * FROM SYS.DBA_CONSTRAINTS WHERE OWNER=pSOURCEUSER AND CONSTRAINT_TYPE='R'
          AND TABLE_NAME NOT LIKE 'BIN$%' AND CONSTRAINT_NAME NOT LIKE 'BIN$%'
          AND (INSTR(','||pTABLENAME||',',','||TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL)
          AND TABLE_NAME=TA.TABLE_NAME
      )
      AND EXISTS (
        SELECT * FROM SYS.DBA_TABLES WHERE OWNER=pSOURCEUSER AND TABLE_NAME=TA.TABLE_NAME
      )
      AND EXISTS (
        SELECT * FROM SYS.DBA_TABLES WHERE OWNER=pTARGETUSER AND TABLE_NAME=TA.TABLE_NAME
      )
  )
  LOOP
    IF pINDEX=0 THEN
      pSQLTEXT:=pSQLTEXT||CHR(10)||('--開始刪除沒必要要的外鍵-------------------------------------------------------------');
    END IF;
    pINDEX:=pINDEX+1;
    --pSQLTEXT:=pSQLTEXT||CHR(10)||'ALTER TABLE "'||pTARGETUSER||'".'||X.TABLE_NAME||' DROP CONSTRAINT "'||X.CONSTRAINT_NAME||'";';
    pSQLTEXT:=pSQLTEXT||CHR(10)||'EXEC PKG_DBMANAGE.DROP_CONSTRAINT('''||pTARGETUSER||''','''||X.TABLE_NAME||''','''||X.CONSTRAINT_NAME||''');';
  END LOOP;
  IF pINDEX>0 THEN
    pSQLTEXT:=pSQLTEXT||CHR(10)||('--刪除沒必要要的外鍵結束!------------------------------------------------------------')||CHR(10);
    pINDEX:=0;
  END IF;

  --5:源主鍵存在而目標主鍵不存在則添加
  FOR X IN
  (
    SELECT * FROM SYS.DBA_CONSTRAINTS TA WHERE OWNER=pSOURCEUSER AND CONSTRAINT_TYPE='P'
      AND TABLE_NAME NOT LIKE 'BIN$%' AND TA.CONSTRAINT_NAME NOT LIKE 'BIN$%'
      AND (INSTR(','||pTABLENAME||',',','||TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL)
      AND NOT EXISTS (
        SELECT * FROM SYS.DBA_CONSTRAINTS WHERE OWNER=pTARGETUSER AND CONSTRAINT_TYPE='P'
          AND TABLE_NAME NOT LIKE 'BIN$%' AND TA.CONSTRAINT_NAME NOT LIKE 'BIN$%'
          AND (INSTR(','||pTABLENAME||',',','||TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL)
          AND TABLE_NAME=TA.TABLE_NAME
      )
      AND EXISTS (
        SELECT * FROM SYS.DBA_TABLES WHERE OWNER=pSOURCEUSER AND TABLE_NAME=TA.TABLE_NAME
      )
      AND EXISTS (
        SELECT * FROM SYS.DBA_TABLES WHERE OWNER=pTARGETUSER AND TABLE_NAME=TA.TABLE_NAME
      )
  )
  LOOP
    IF pINDEX=0 THEN
      pSQLTEXT:=pSQLTEXT||CHR(10)||'--開始添加新的主鍵----------------------------------------------------------------';
    END IF;
    pINDEX:=pINDEX+1;
    SELECT  'DELETE FROM '||pREPLACEUSER||'"'||TABLE_NAME||'" A WHERE NOT EXISTS('||CHR(10)||
            ' SELECT * FROM ('||CHR(10)||
            '	  SELECT MAX(ROWID) OVER(PARTITION BY '||COLLIST||') AS MAXROWID FROM '||pREPLACEUSER||'"'||TABLE_NAME||'"'||CHR(10)||
            '	) WHERE MAXROWID=A.ROWID'||CHR(10)||
            ');'||CHR(10)||
            'ALTER TABLE '||pREPLACEUSER||'"'||TABLE_NAME||'" ADD CONSTRAINT "'||CONSTRAINT_NAME||'" PRIMARY KEY('||COLLIST||') ENABLE;'
      INTO pPRIMARY FROM (
        SELECT DISTINCT TABLE_NAME,CONSTRAINT_NAME,LISTAGG('"'||COLUMN_NAME||'"',',') WITHIN GROUP(ORDER BY POSITION) OVER(PARTITION BY TABLE_NAME) AS COLLIST
          FROM SYS.DBA_CONS_COLUMNS WHERE OWNER=pSOURCEUSER AND CONSTRAINT_NAME=X.CONSTRAINT_NAME
      );
    pSQLTEXT:=pSQLTEXT||CHR(10)||pPRIMARY;
  END LOOP;
  IF pINDEX>0 THEN
    pSQLTEXT:=pSQLTEXT||CHR(10)||('--添加新的主鍵結束!---------------------------------------------------------------')||CHR(10);
    pINDEX:=0;
  END IF;

  --6:源外鍵存在而目標外鍵不存在則添加
  FOR X IN
  (
    SELECT * FROM SYS.DBA_CONSTRAINTS TA WHERE OWNER=pSOURCEUSER AND CONSTRAINT_TYPE='R'
      AND TABLE_NAME NOT LIKE 'BIN$%' AND TA.CONSTRAINT_NAME NOT LIKE 'BIN$%'
      AND (INSTR(','||pTABLENAME||',',','||TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL)
      AND NOT EXISTS (
        SELECT * FROM SYS.DBA_CONSTRAINTS WHERE OWNER=pTARGETUSER AND CONSTRAINT_TYPE='R'
          AND TABLE_NAME NOT LIKE 'BIN$%' AND CONSTRAINT_NAME NOT LIKE 'BIN$%'
          AND (INSTR(','||pTABLENAME||',',','||TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL)
          AND TABLE_NAME=TA.TABLE_NAME
      )
      AND EXISTS (
        SELECT * FROM SYS.DBA_TABLES WHERE OWNER=pSOURCEUSER AND TABLE_NAME=TA.TABLE_NAME
      )
      AND EXISTS (
        SELECT * FROM SYS.DBA_TABLES WHERE OWNER=pTARGETUSER AND TABLE_NAME=TA.TABLE_NAME
      )
  )
  LOOP
    IF pINDEX=0 THEN
      pSQLTEXT:=pSQLTEXT||CHR(10)||('--開始添加新的外鍵----------------------');
    END IF;
    pINDEX:=pINDEX+1;
    SELECT '"'||TABLE_NAME||'" ('||COLLIST||') ' INTO pPRIMARY FROM (
      SELECT DISTINCT TABLE_NAME,CONSTRAINT_NAME,LISTAGG('"'||COLUMN_NAME||'"',',') WITHIN GROUP(ORDER BY POSITION) OVER(PARTITION BY TABLE_NAME) AS COLLIST
        FROM SYS.DBA_CONS_COLUMNS WHERE CONSTRAINT_NAME=X.R_CONSTRAINT_NAME AND  OWNER=pSOURCEUSER
    );
    SELECT 'ALTER TABLE '||pREPLACEUSER||'"'||TABLE_NAME||'" ADD CONSTRAINT "'||CONSTRAINT_NAME||'" FOREIGN KEY('||COLLIST||') REFERENCES '||pPRIMARY||DECODE(X.DELETE_RULE,'CASCADE','ON DELETE CASCADE ',' ')||'ENABLE;' INTO pFOREIGN FROM (
      SELECT DISTINCT TABLE_NAME,CONSTRAINT_NAME,LISTAGG('"'||COLUMN_NAME||'"',',') WITHIN GROUP(ORDER BY POSITION) OVER(PARTITION BY TABLE_NAME) AS COLLIST
        FROM SYS.DBA_CONS_COLUMNS WHERE CONSTRAINT_NAME=X.CONSTRAINT_NAME AND OWNER=pSOURCEUSER
    );
    pSQLTEXT:=pSQLTEXT||CHR(10)||pFOREIGN;
  END LOOP;
  IF pINDEX>0 THEN
    pSQLTEXT:=pSQLTEXT||CHR(10)||('--添加新的外鍵結束!----------------------')||CHR(10);
    pINDEX:=0;
  END IF;

  --7:源主鍵不存在而目標主鍵存在則刪除
  FOR X IN
  (
    SELECT * FROM SYS.DBA_CONSTRAINTS TA WHERE OWNER=pTARGETUSER AND CONSTRAINT_TYPE='P'
      AND TABLE_NAME NOT LIKE 'BIN$%' AND TA.CONSTRAINT_NAME NOT LIKE 'BIN$%'
      AND (INSTR(','||pTABLENAME||',',','||TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL)
      AND NOT EXISTS (
        SELECT * FROM SYS.DBA_CONSTRAINTS WHERE OWNER=pSOURCEUSER AND CONSTRAINT_TYPE='P'
          AND TABLE_NAME NOT LIKE 'BIN$%' AND CONSTRAINT_NAME NOT LIKE 'BIN$%'
          AND (INSTR(','||pTABLENAME||',',','||TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL)
          AND TABLE_NAME=TA.TABLE_NAME
      )
      AND EXISTS (
        SELECT * FROM SYS.DBA_TABLES WHERE OWNER=pSOURCEUSER AND TABLE_NAME=TA.TABLE_NAME
      )
      AND EXISTS (
        SELECT * FROM SYS.DBA_TABLES WHERE OWNER=pTARGETUSER AND TABLE_NAME=TA.TABLE_NAME
      )
  )
  LOOP
    IF pINDEX=0 THEN
      pSQLTEXT:=pSQLTEXT||CHR(10)||('--開始刪除沒必要要的主鍵----------------------');
    END IF;
    pINDEX:=pINDEX+1;
    --pSQLTEXT:=pSQLTEXT||CHR(10)||'ALTER TABLE "'||pTARGETUSER||'".'||X.TABLE_NAME||' DROP CONSTRAINT '||X.CONSTRAINT_NAME||';';
    pSQLTEXT:=pSQLTEXT||CHR(10)||'EXEC PKG_DBMANAGE.DROP_CONSTRAINT('''||pTARGETUSER||''','''||X.TABLE_NAME||''','''||X.CONSTRAINT_NAME||''');';
  END LOOP;
  IF pINDEX>0 THEN
    pSQLTEXT:=pSQLTEXT||CHR(10)||('--刪除沒必要要的主鍵結束!----------------------')||CHR(10);
    pINDEX:=0;
  END IF;

  --8:主鍵列、外鍵列修改的邏輯:先刪除全部有變更的外鍵,再刪除全部有變更的主鍵,再從新添加主鍵,最後從新添加新的外鍵;若是隻是主外鍵名稱不相同,則從新改名便可
  --8.1:刪除全部有變更的外鍵
  --注意:此處若是外鍵名稱不相同,只須要從新改名
  FOR X IN
  (
    SELECT * FROM (
      SELECT TABLE_NAME,OLD_CONSTRAINT_NAME,NEW_CONSTRAINT_NAME,R_TABLE_NAME,FORIGNCOL,PRIMARYKEY,OPERATETYPE,DELETE_RULE,DENSE_RANK() OVER(PARTITION BY TABLE_NAME,OLD_CONSTRAINT_NAME ORDER BY OPERATETYPE DESC) AS DC FROM (
        SELECT T2.TABLE_NAME,T4.CONSTRAINT_NAME AS OLD_CONSTRAINT_NAME,T2.CONSTRAINT_NAME AS NEW_CONSTRAINT_NAME,T2.R_TABLE_NAME,T2.COLLIST AS FORIGNCOL,T4.COLLIST AS PRIMARYKEY,
          DECODE(T2.R_TABLE_NAME||'('||T2.COLLIST||')'||NVL(T2.DELETE_RULE,' '),T4.R_TABLE_NAME||'('||T4.COLLIST||')'||NVL(T4.DELETE_RULE,' '),DECODE(T2.CONSTRAINT_NAME,T4.CONSTRAINT_NAME,'','RENAME'),'DROP') AS OPERATETYPE,T2.DELETE_RULE FROM (
          SELECT DISTINCT TABLE_NAME,CONSTRAINT_NAME,DELETE_RULE,LISTAGG('"'||COLUMN_NAME||'"',',') WITHIN GROUP(ORDER BY POSITION) OVER(PARTITION BY TABLE_NAME,CONSTRAINT_NAME) AS COLLIST,
            R_TABLE_NAME,LISTAGG('"'||R_COULMN_NAME||'"',',') WITHIN GROUP(ORDER BY POSITION) OVER(PARTITION BY TABLE_NAME,CONSTRAINT_NAME) AS R_COLLIST FROM (
            SELECT TA.TABLE_NAME,TA.CONSTRAINT_NAME,TA.DELETE_RULE,TB.COLUMN_NAME,TA.R_CONSTRAINT_NAME,TC.TABLE_NAME AS R_TABLE_NAME,TD.COLUMN_NAME AS R_COULMN_NAME,TB.POSITION
              FROM SYS.DBA_CONSTRAINTS TA
              JOIN SYS.DBA_CONS_COLUMNS TB ON (TA.OWNER=TB.OWNER AND TA.CONSTRAINT_NAME=TB.CONSTRAINT_NAME AND TA.TABLE_NAME=TB.TABLE_NAME )
              JOIN SYS.DBA_CONSTRAINTS TC ON (TA.R_OWNER=TC.OWNER AND TA.R_CONSTRAINT_NAME=TC.CONSTRAINT_NAME)
              JOIN SYS.DBA_CONS_COLUMNS TD ON (TC.OWNER=TD.OWNER AND TC.CONSTRAINT_NAME=TD.CONSTRAINT_NAME AND TD.TABLE_NAME=TC.TABLE_NAME AND TB.POSITION=TD.POSITION)
              WHERE TA.OWNER=pSOURCEUSER AND TA.CONSTRAINT_TYPE='R'
                AND TA.R_OWNER=pSOURCEUSER AND TC.CONSTRAINT_TYPE='P'
                AND TA.TABLE_NAME NOT LIKE 'BIN$%' AND TA.CONSTRAINT_NAME NOT LIKE 'BIN$%'
                AND TC.TABLE_NAME NOT LIKE 'BIN$%' AND TC.CONSTRAINT_NAME NOT LIKE 'BIN$%'
          ) T1
        ) T2
        JOIN
        (
          SELECT DISTINCT TABLE_NAME,CONSTRAINT_NAME,DELETE_RULE,LISTAGG('"'||COLUMN_NAME||'"',',') WITHIN GROUP(ORDER BY POSITION) OVER(PARTITION BY TABLE_NAME,CONSTRAINT_NAME) AS COLLIST,
            R_TABLE_NAME,LISTAGG('"'||R_COULMN_NAME||'"',',') WITHIN GROUP(ORDER BY POSITION) OVER(PARTITION BY TABLE_NAME,CONSTRAINT_NAME) AS R_COLLIST FROM (
            SELECT TA.TABLE_NAME,TA.CONSTRAINT_NAME,TA.DELETE_RULE,TB.COLUMN_NAME,TA.R_CONSTRAINT_NAME,TC.TABLE_NAME AS R_TABLE_NAME,TD.COLUMN_NAME AS R_COULMN_NAME,TB.POSITION
              FROM SYS.DBA_CONSTRAINTS TA
              JOIN SYS.DBA_CONS_COLUMNS TB ON (TA.OWNER=TB.OWNER AND TA.CONSTRAINT_NAME=TB.CONSTRAINT_NAME AND TA.TABLE_NAME=TB.TABLE_NAME )
              JOIN SYS.DBA_CONSTRAINTS TC ON (TA.R_OWNER=TC.OWNER AND TA.R_CONSTRAINT_NAME=TC.CONSTRAINT_NAME)
              JOIN SYS.DBA_CONS_COLUMNS TD ON (TC.OWNER=TD.OWNER AND TC.CONSTRAINT_NAME=TD.CONSTRAINT_NAME AND TD.TABLE_NAME=TC.TABLE_NAME AND TB.POSITION=TD.POSITION)
              WHERE TA.OWNER=pTARGETUSER AND TA.CONSTRAINT_TYPE='R'
                AND TA.R_OWNER=pTARGETUSER AND TC.CONSTRAINT_TYPE='P'
                AND TA.TABLE_NAME NOT LIKE 'BIN$%' AND TA.CONSTRAINT_NAME NOT LIKE 'BIN$%'
                AND TC.TABLE_NAME NOT LIKE 'BIN$%' AND TC.CONSTRAINT_NAME NOT LIKE 'BIN$%'
          ) T3
        ) T4 ON T2.TABLE_NAME=T4.TABLE_NAME
      )
    ) WHERE OPERATETYPE IS NOT NULL AND DC=1
  )
  LOOP
    IF pINDEX=0 THEN
      pSQLTEXT:=pSQLTEXT||CHR(10)||('--開始更新全部有變更的外鍵----------------------------------------------------------');
    END IF;
    pINDEX:=pINDEX+1;
    IF X.OPERATETYPE='DROP' THEN
      pSQLTEXT:=pSQLTEXT||CHR(10)||'ALTER TABLE '||pREPLACEUSER||'"'||X.TABLE_NAME||'" DROP CONSTRAINT "'||X.OLD_CONSTRAINT_NAME||'";';
      SELECT pREBULIDFORRIGN||CHR(10)||'ALTER TABLE '||pREPLACEUSER||'"'||X.TABLE_NAME||'" ADD CONSTRAINT "'||X.NEW_CONSTRAINT_NAME||'" FOREIGN KEY('||X.FORIGNCOL||') REFERENCES "'||
        X.R_TABLE_NAME||'" ('||X.PRIMARYKEY||') '||DECODE(X.DELETE_RULE,'CASCADE','ON DELETE CASCADE ',' ')||'ENABLE;' INTO pREBULIDFORRIGN FROM DUAL;
    ELSE
      pSQLTEXT:=pSQLTEXT||CHR(10)||'ALTER TABLE '||pREPLACEUSER||'"'||X.TABLE_NAME||'" RENAME CONSTRAINT '||X.OLD_CONSTRAINT_NAME||' TO '||X.NEW_CONSTRAINT_NAME||';';
    END IF;
  END LOOP;
  IF pINDEX>0 THEN
    pSQLTEXT:=pSQLTEXT||CHR(10)||('--更新全部有變更的外鍵結束!---------------------------------------------------------')||CHR(10);
    pINDEX:=0;
  END IF;

  --8.2:刪除全部有變更的主鍵,同時添加新的主鍵
  --注意:此處若是主鍵名稱不相同,只須要從新改名
  FOR X IN
  (
    SELECT * FROM (
      SELECT TA.TABLE_NAME,TB.CONSTRAINT_NAME AS OLD_CONSTRAINT_NAME,TA.CONSTRAINT_NAME AS NEW_CONSTRAINT_NAME,TA.COLLIST,
        DECODE(TA.COLLIST,TB.COLLIST,DECODE(TA.CONSTRAINT_NAME,TB.CONSTRAINT_NAME,'','RENAME'),'DROP') AS OPERATETYPE FROM (
        SELECT DISTINCT TABLE_NAME,CONSTRAINT_NAME,LISTAGG('"'||COLUMN_NAME||'"',',') WITHIN GROUP(ORDER BY POSITION) OVER(PARTITION BY TABLE_NAME) AS COLLIST FROM (
          SELECT TB.TABLE_NAME,TB.CONSTRAINT_NAME,TB.COLUMN_NAME,POSITION FROM SYS.DBA_CONSTRAINTS TA
            JOIN SYS.DBA_CONS_COLUMNS TB ON (TA.OWNER=TB.OWNER AND TA.CONSTRAINT_NAME=TB.CONSTRAINT_NAME)
            WHERE TA.OWNER=pSOURCEUSER AND TA.CONSTRAINT_TYPE='P'
              AND TA.TABLE_NAME NOT LIKE 'BIN$%' AND TA.CONSTRAINT_NAME NOT LIKE 'BIN$%'
              AND (INSTR(','||pTABLENAME||',',','||TA.TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL)
        )
      ) TA
      JOIN
      (
        SELECT DISTINCT TABLE_NAME,CONSTRAINT_NAME,LISTAGG('"'||COLUMN_NAME||'"',',') WITHIN GROUP(ORDER BY POSITION) OVER(PARTITION BY TABLE_NAME) AS COLLIST
          FROM (
            SELECT TB.TABLE_NAME,TB.CONSTRAINT_NAME,TB.COLUMN_NAME,POSITION FROM SYS.DBA_CONSTRAINTS TA
              JOIN SYS.DBA_CONS_COLUMNS TB ON (TA.OWNER=TB.OWNER AND TA.CONSTRAINT_NAME=TB.CONSTRAINT_NAME)
              WHERE TA.OWNER=pTARGETUSER AND TA.CONSTRAINT_TYPE='P'
                AND TA.TABLE_NAME NOT LIKE 'BIN$%' AND TA.CONSTRAINT_NAME NOT LIKE 'BIN$%'
                AND (INSTR(','||pTABLENAME||',',','||TA.TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL)
          )
      ) TB ON TA.TABLE_NAME=TB.TABLE_NAME
    ) WHERE OPERATETYPE IS NOT NULL
  )
  LOOP
    IF pINDEX=0 THEN
      pSQLTEXT:=pSQLTEXT||CHR(10)||('--開始更新有變更的主鍵-------------------------------------------------------------');
    END IF;
    pINDEX:=pINDEX+1;
    --注意:此處需判斷主鍵以及主鍵索引是否存在,如主鍵不存在但主鍵索引存在,需刪除主鍵索引
    --因爲存儲過程當中沒法獲取其餘用戶的源碼,暫定刪除主鍵索引,重建主鍵
    IF X.OPERATETYPE='DROP' THEN
      --保存修改主鍵的語句
      SELECT COUNT(1) INTO pCOUNT FROM SYS.DBA_CONSTRAINTS WHERE OWNER=pTARGETUSER AND CONSTRAINT_NAME=X.OLD_CONSTRAINT_NAME;
      SELECT COUNT(1) INTO pCOUNT1 FROM SYS.DBA_INDEXES WHERE OWNER=pTARGETUSER AND INDEX_NAME=X.OLD_CONSTRAINT_NAME;
      IF pCOUNT=1 THEN          --主鍵存在須要刪除主鍵和主鍵索引級鏈刪除
        pSQLTEXT:=pSQLTEXT||CHR(10)||'ALTER TABLE '||pREPLACEUSER||'"'||X.TABLE_NAME||'" DROP CONSTRAINT '||X.OLD_CONSTRAINT_NAME||' cascade drop index;';
      ELSIF pCOUNT1=1 THEN      --主鍵不存在但主鍵索引存在,需刪除主鍵索引
        pSQLTEXT:=pSQLTEXT||CHR(10)||'DROP INDEX '||pREPLACEUSER||X.OLD_CONSTRAINT_NAME||';';
      END IF;
      pSQLTEXT:=pSQLTEXT||CHR(10)||'ALTER TABLE '||pREPLACEUSER||'"'||X.TABLE_NAME||'" ADD CONSTRAINT "'||X.NEW_CONSTRAINT_NAME||'" PRIMARY KEY('||X.COLLIST||') ENABLE;';
    ELSE
      pSQLTEXT:=pSQLTEXT||CHR(10)||'ALTER TABLE '||pREPLACEUSER||'"'||X.TABLE_NAME||'" RENAME CONSTRAINT '||X.OLD_CONSTRAINT_NAME||' TO '||X.NEW_CONSTRAINT_NAME||';';
    END IF;
  END LOOP;
  IF pINDEX>0 THEN
    pSQLTEXT:=pSQLTEXT||CHR(10)||('--更新有變更的主鍵結束!------------------------------------------------------------')||CHR(10);
    pINDEX:=0;
  END IF;

  --8.3:從新添加新的外鍵
  IF pREBULIDFORRIGN IS NOT NULL THEN
    pSQLTEXT:=pSQLTEXT||CHR(10)||('--開始從新添加新的外鍵-------------------------------------------------------------');
    pSQLTEXT:=pSQLTEXT||pREBULIDFORRIGN;
    pSQLTEXT:=pSQLTEXT||CHR(10)||('--從新添加新的外鍵結束!------------------------------------------------------------');
  END IF;

  --9:源約束(檢查、惟一)不存在而目標約束存在則刪除
  --注意:因爲在DBA_CONSTRAINTS中檢查約束、非空約束類型均爲'C',很難加以區分,暫時能夠查詢出GENERATED='USER NAME'爲檢查約束,GENERATED='GENERATED NAME'爲非空約束
  --注意:若是約束存在可是約束的列不相同也須要刪除重建
  FOR X IN
  (
    SELECT DISTINCT * FROM (
      SELECT TA.CONSTRAINT_NAME,TA.TABLE_NAME,LISTAGG(T1.COLUMN_NAME,',') WITHIN GROUP(ORDER BY T1.COLUMN_NAME) OVER(PARTITION BY TA.CONSTRAINT_NAME,TA.TABLE_NAME) AS COL_LIST,TA.CONSTRAINT_TYPE FROM SYS.DBA_CONSTRAINTS TA
        JOIN SYS.DBA_CONS_COLUMNS T1 ON (TA.OWNER=T1.OWNER AND TA.CONSTRAINT_NAME=T1.CONSTRAINT_NAME)
        WHERE TA.OWNER=pTARGETUSER AND
        ((TA.GENERATED='USER NAME' AND TA.CONSTRAINT_TYPE='C') OR TA.CONSTRAINT_TYPE='U')
        AND TA.TABLE_NAME NOT LIKE 'BIN$%' AND TA.CONSTRAINT_NAME NOT LIKE 'BIN$%'
        AND (INSTR(','||pTABLENAME||',',','||TA.TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL)
    ) C1
      WHERE NOT EXISTS (
        SELECT * FROM (
          SELECT TB.CONSTRAINT_NAME,TB.TABLE_NAME,LISTAGG(T2.COLUMN_NAME,',') WITHIN GROUP(ORDER BY T2.COLUMN_NAME) OVER(PARTITION BY TB.CONSTRAINT_NAME,TB.TABLE_NAME) AS COL_LIST,TB.CONSTRAINT_TYPE FROM SYS.DBA_CONSTRAINTS TB
            JOIN SYS.DBA_CONS_COLUMNS T2 ON (TB.OWNER=T2.OWNER AND TB.CONSTRAINT_NAME=T2.CONSTRAINT_NAME)
            WHERE TB.OWNER=pSOURCEUSER AND
            ((TB.GENERATED='USER NAME' AND TB.CONSTRAINT_TYPE='C') OR TB.CONSTRAINT_TYPE='U')
            AND TB.TABLE_NAME NOT LIKE 'BIN$%' AND TB.CONSTRAINT_NAME NOT LIKE 'BIN$%'
            AND (INSTR(','||pTABLENAME||',',','||TB.TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL)
        ) C2 WHERE C2.CONSTRAINT_NAME=C1.CONSTRAINT_NAME AND C2.CONSTRAINT_TYPE=C1.CONSTRAINT_TYPE AND C2.TABLE_NAME=C1.TABLE_NAME AND C2.COL_LIST=C1.COL_LIST
      )
      AND EXISTS (
        SELECT * FROM SYS.DBA_TABLES WHERE OWNER=pSOURCEUSER AND TABLE_NAME=C1.TABLE_NAME
      )
      AND EXISTS (
        SELECT * FROM SYS.DBA_TABLES WHERE OWNER=pTARGETUSER AND TABLE_NAME=C1.TABLE_NAME
      )
  )
  LOOP
    IF pINDEX=0 THEN
      pSQLTEXT:=pSQLTEXT||CHR(10)||('--開始刪除沒必要要的約束-------------------------------------------------------------');
    END IF;
    pINDEX:=pINDEX+1;
    --pSQLTEXT:=pSQLTEXT||CHR(10)||'ALTER TABLE "'||pTARGETUSER||'".'||X.TABLE_NAME||' DROP CONSTRAINT "'||X.CONSTRAINT_NAME||'";';
    pSQLTEXT:=pSQLTEXT||CHR(10)||'EXEC PKG_DBMANAGE.DROP_CONSTRAINT('''||pTARGETUSER||''','''||X.TABLE_NAME||''','''||X.CONSTRAINT_NAME||''');';
  END LOOP;
  IF pINDEX>0 THEN
    pSQLTEXT:=pSQLTEXT||CHR(10)||('--刪除沒必要要的約束結束!------------------------------------------------------------')||CHR(10);
    pINDEX:=0;
  END IF;

  --10:源約束(檢查、惟一)存在而目標約束不存在則添加
  --注意:因爲在DBA_CONSTRAINTS中檢查約束、非空約束類型均爲'C',很難加以區分,暫時能夠查詢出GENERATED='USER NAME'爲檢查約束,GENERATED='GENERATED NAME'爲非空約束
  --注意:若是約束存在可是約束的列不相同也須要刪除重建
  FOR X IN
  (
    SELECT DISTINCT * FROM (
      SELECT TA.CONSTRAINT_NAME,TA.TABLE_NAME,LISTAGG(T1.COLUMN_NAME,',') WITHIN GROUP(ORDER BY T1.COLUMN_NAME) OVER(PARTITION BY TA.CONSTRAINT_NAME,TA.TABLE_NAME) AS COL_LIST,TA.CONSTRAINT_TYPE FROM SYS.DBA_CONSTRAINTS TA
        JOIN SYS.DBA_CONS_COLUMNS T1 ON (TA.OWNER=T1.OWNER AND TA.CONSTRAINT_NAME=T1.CONSTRAINT_NAME)
        WHERE TA.OWNER=pSOURCEUSER AND
        ((TA.GENERATED='USER NAME' AND TA.CONSTRAINT_TYPE='C') OR TA.CONSTRAINT_TYPE='U')
        AND TA.TABLE_NAME NOT LIKE 'BIN$%' AND TA.CONSTRAINT_NAME NOT LIKE 'BIN$%'
        AND (INSTR(','||pTABLENAME||',',','||TA.TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL)
    ) C1
      WHERE NOT EXISTS (
        SELECT * FROM (
          SELECT TB.CONSTRAINT_NAME,TB.TABLE_NAME,LISTAGG(T2.COLUMN_NAME,',') WITHIN GROUP(ORDER BY T2.COLUMN_NAME) OVER(PARTITION BY TB.CONSTRAINT_NAME,TB.TABLE_NAME) AS COL_LIST,TB.CONSTRAINT_TYPE FROM SYS.DBA_CONSTRAINTS TB
            JOIN SYS.DBA_CONS_COLUMNS T2 ON (TB.OWNER=T2.OWNER AND TB.CONSTRAINT_NAME=T2.CONSTRAINT_NAME)
            WHERE TB.OWNER=pTARGETUSER AND
            ((TB.GENERATED='USER NAME' AND TB.CONSTRAINT_TYPE='C') OR TB.CONSTRAINT_TYPE='U')
            AND TB.TABLE_NAME NOT LIKE 'BIN$%' AND TB.CONSTRAINT_NAME NOT LIKE 'BIN$%'
            AND (INSTR(','||pTABLENAME||',',','||TB.TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL)
        ) C2 WHERE C2.CONSTRAINT_NAME=C1.CONSTRAINT_NAME AND C2.CONSTRAINT_TYPE=C1.CONSTRAINT_TYPE AND C2.TABLE_NAME=C1.TABLE_NAME AND C2.COL_LIST=C1.COL_LIST
      )
      AND EXISTS (
        SELECT * FROM SYS.DBA_TABLES WHERE OWNER=pSOURCEUSER AND TABLE_NAME=C1.TABLE_NAME
      )
      AND EXISTS (
        SELECT * FROM SYS.DBA_TABLES WHERE OWNER=pTARGETUSER AND TABLE_NAME=C1.TABLE_NAME
      )
  )
  LOOP
    IF pINDEX=0 THEN
      pSQLTEXT:=pSQLTEXT||CHR(10)||('--開始添加新的約束----------------------------------------------------------------');
    END IF;
    pINDEX:=pINDEX+1;
    IF X.CONSTRAINT_TYPE='U' THEN   --惟一約束
      pRULECODE:='ALTER TABLE '||pREPLACEUSER||'"'||X.TABLE_NAME||'" ADD CONSTRAINT "'||X.CONSTRAINT_NAME||'" UNIQUE('||X.COL_LIST||') ENABLE;';
    ELSE                            --檢查約束
      FOR R IN                      --此處循環寫法是爲了解決long類型字段在查詢語句中沒法進行拼接的問題
      (
        SELECT SEARCH_CONDITION FROM SYS.DBA_CONSTRAINTS WHERE OWNER=pSOURCEUSER AND TABLE_NAME=X.TABLE_NAME AND CONSTRAINT_NAME=X.CONSTRAINT_NAME
      )
      LOOP
        pRULECODE:='ALTER TABLE '||pREPLACEUSER||'"'||X.TABLE_NAME||'" ADD CONSTRAINT "'||X.CONSTRAINT_NAME||'" CHECK ('||R.SEARCH_CONDITION||') ENABLE;';
      END LOOP;
    END IF;
    pSQLTEXT:=pSQLTEXT||CHR(10)||pRULECODE;
  END LOOP;
  IF pINDEX>0 THEN
    pSQLTEXT:=pSQLTEXT||CHR(10)||('--添加新的約束結束!---------------------------------------------------------------')||CHR(10);
    pINDEX:=0;
  END IF;

  --11:源索引不存在而目標索引存在則刪除
  FOR X IN
  (
    SELECT DISTINCT TA.INDEX_NAME FROM SYS.DBA_INDEXES TA
      JOIN SYS.DBA_IND_COLUMNS TB ON TA.OWNER=TB.INDEX_OWNER AND TA.TABLE_NAME=TB.TABLE_NAME AND TA.INDEX_NAME=TB.INDEX_NAME
      WHERE TA.OWNER=pTARGETUSER
        AND TA.TABLE_NAME NOT LIKE 'BIN$%' AND TA.INDEX_NAME NOT LIKE 'BIN$%' AND INDEX_TYPE NOT IN('LOB')
        AND (INSTR(','||pTABLENAME||',',','||TA.TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL)
        AND NOT EXISTS (
          SELECT * FROM SYS.DBA_INDEXES T1
            JOIN SYS.DBA_IND_COLUMNS T2 ON T1.OWNER=T2.INDEX_OWNER AND T1.TABLE_NAME=T2.TABLE_NAME AND T1.INDEX_NAME=T2.INDEX_NAME
            WHERE OWNER=pSOURCEUSER
              AND T1.TABLE_NAME NOT LIKE 'BIN$%' AND T1.INDEX_NAME NOT LIKE 'BIN$%'
              AND T1.TABLE_NAME=TA.TABLE_NAME AND T1.INDEX_NAME=TA.INDEX_NAME
        )
        AND NOT EXISTS (
          SELECT * FROM SYS.DBA_CONSTRAINTS WHERE OWNER=pTARGETUSER AND TABLE_NAME=TA.TABLE_NAME AND INDEX_NAME=TA.INDEX_NAME
        )
        AND EXISTS (
          SELECT * FROM SYS.DBA_TABLES WHERE OWNER=pSOURCEUSER AND TABLE_NAME=TA.TABLE_NAME
        )
        AND EXISTS (
          SELECT * FROM SYS.DBA_TABLES WHERE OWNER=pTARGETUSER AND TABLE_NAME=TA.TABLE_NAME
        )
  )
  LOOP
    IF pINDEX=0 THEN
      pSQLTEXT:=pSQLTEXT||CHR(10)||('--開始刪除沒必要要的索引-------------------------------------------------------------');
    END IF;
    pINDEX:=pINDEX+1;
    pSQLTEXT:=pSQLTEXT||CHR(10)||'EXEC PKG_DBMANAGE.DROP_INDEX('''||pTARGETUSER||''','''||X.INDEX_NAME||''');';
  END LOOP;
  IF pINDEX>0 THEN
    pSQLTEXT:=pSQLTEXT||CHR(10)||('--刪除沒必要要的索引結束!------------------------------------------------------------')||CHR(10);
    pINDEX:=0;
  END IF;

  --12:源索引存在而目標索引不存在則添加
  FOR X IN
  (
    SELECT DISTINCT TA.INDEX_NAME FROM SYS.DBA_INDEXES TA
      JOIN SYS.DBA_IND_COLUMNS TB ON TA.OWNER=TB.INDEX_OWNER AND TA.TABLE_NAME=TB.TABLE_NAME AND TA.INDEX_NAME=TB.INDEX_NAME
      WHERE TA.OWNER=pSOURCEUSER
        AND TA.TABLE_NAME NOT LIKE 'BIN$%' AND TA.INDEX_NAME NOT LIKE 'BIN$%' AND TA.INDEX_TYPE NOT IN('LOB') AND TA.INDEX_TYPE NOT IN('LOB')
        AND (INSTR(','||pTABLENAME||',',','||TA.TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL)
        AND NOT EXISTS (
          SELECT * FROM SYS.DBA_INDEXES T1
            JOIN SYS.DBA_IND_COLUMNS T2 ON T1.OWNER=T2.INDEX_OWNER AND T1.TABLE_NAME=T2.TABLE_NAME AND T1.INDEX_NAME=T2.INDEX_NAME
            WHERE OWNER=pTARGETUSER
              AND T1.TABLE_NAME NOT LIKE 'BIN$%' AND T1.INDEX_NAME NOT LIKE 'BIN$%'
              AND T1.TABLE_NAME=TA.TABLE_NAME AND T1.INDEX_NAME=TA.INDEX_NAME
        )
        AND NOT EXISTS (
          SELECT * FROM SYS.DBA_CONSTRAINTS WHERE OWNER=pSOURCEUSER AND TABLE_NAME=TA.TABLE_NAME AND INDEX_NAME=TA.INDEX_NAME
        )
        AND EXISTS (
          SELECT * FROM SYS.DBA_TABLES WHERE OWNER=pSOURCEUSER AND TABLE_NAME=TA.TABLE_NAME
        )
        AND EXISTS (
          SELECT * FROM SYS.DBA_TABLES WHERE OWNER=pTARGETUSER AND TABLE_NAME=TA.TABLE_NAME
        )
  )
  LOOP
    IF pINDEX=0 THEN
      pSQLTEXT:=pSQLTEXT||CHR(10)||('--開始添加新的索引-----------------------------------------------------------------');
    END IF;
    pINDEX:=pINDEX+1;
    PKG_GET_DDL.GET_DDL(pSOURCEUSER,pTARGETUSER,1,X.INDEX_NAME,3,pSOURCECODE);
    pSQLTEXT:=pSQLTEXT||pSOURCECODE;
  END LOOP;
  IF pINDEX>0 THEN
    pSQLTEXT:=pSQLTEXT||CHR(10)||('--添加新的索引結束!---------------------------------------------------------------')||CHR(10);
    pINDEX:=0;
  END IF;

  --13:索引修改的邏輯:先刪除全部有變更的索引,再從新添加新的索引
  --遍歷索引的每一列,判斷列名、順序、排序等是否一致,若是不一致,則刪除重建,
  --注意:函數索引的列名通常爲「SYS_」,須要從DBA_IND_EXPRESSIONS對應查找到原始列名
  DELETE FROM TEMP_COLUMN_EXPRESSION;
  INSERT INTO TEMP_COLUMN_EXPRESSION(INDEX_OWNER,INDEX_NAME,INDEX_TYPE,UNIQUENESS,COMPRESSION,TABLE_NAME,TABLE_TYPE,COLUMN_NAME,COLUMN_EXPRESSION,COLUMN_POSITION,DESCEND)
  SELECT TB.INDEX_OWNER,TB.INDEX_NAME,TA.INDEX_TYPE,TA.UNIQUENESS,TA.COMPRESSION,Ta.TABLE_NAME,TA.TABLE_TYPE,TB.COLUMN_NAME,TO_LOB(TC.COLUMN_EXPRESSION) AS COLUMN_EXPRESSION,TB.COLUMN_POSITION,TB.DESCEND FROM SYS.DBA_INDEXES TA
    JOIN SYS.DBA_IND_COLUMNS TB ON (TA.INDEX_NAME=TB.INDEX_NAME AND TA.TABLE_NAME=TB.TABLE_NAME AND TA.OWNER=TB.INDEX_OWNER)
    LEFT JOIN SYS.DBA_IND_EXPRESSIONS TC ON ( TB.INDEX_OWNER=TC.INDEX_OWNER AND TB.TABLE_OWNER=TC.INDEX_OWNER AND TB.INDEX_NAME=TC.INDEX_NAME
                                              AND TB.TABLE_NAME=TC.TABLE_NAME AND TB.COLUMN_POSITION=TC.COLUMN_POSITION )
    WHERE ((TA.OWNER=pTARGETUSER AND TB.INDEX_OWNER=pTARGETUSER AND TB.TABLE_OWNER=pTARGETUSER) OR
      (TA.OWNER=pSOURCEUSER AND TB.INDEX_OWNER=pSOURCEUSER AND TB.TABLE_OWNER=pSOURCEUSER))
      AND TA.TABLE_NAME NOT LIKE 'BIN$%' AND TA.INDEX_NAME NOT LIKE 'BIN$%'
      AND (INSTR(','||pTABLENAME||',',','||TA.TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL)
      AND NOT EXISTS (
        SELECT * FROM SYS.DBA_CONSTRAINTS WHERE OWNER=TA.OWNER AND CONSTRAINT_NAME=TA.INDEX_NAME AND TABLE_NAME=TA.TABLE_NAME
      );
  FOR X IN
  (
    SELECT DISTINCT T1.INDEX_NAME FROM (
      SELECT DISTINCT INDEX_NAME,TABLE_NAME,UNIQUENESS,LISTAGG(COLUMN_NAME||' '||DESCEND,',')
        WITHIN GROUP(ORDER BY COLUMN_POSITION) OVER(PARTITION BY INDEX_NAME,TABLE_NAME) AS COL_SORT FROM (
          SELECT INDEX_NAME,UNIQUENESS,TABLE_NAME,TO_CHAR(NVL(COLUMN_EXPRESSION,COLUMN_NAME)) AS COLUMN_NAME,DESCEND,COLUMN_POSITION FROM TEMP_COLUMN_EXPRESSION T1 WHERE INDEX_OWNER=pSOURCEUSER
        )
      ) T1 JOIN (
        SELECT DISTINCT INDEX_NAME,TABLE_NAME,UNIQUENESS,LISTAGG(COLUMN_NAME||' '||DESCEND,',')
          WITHIN GROUP(ORDER BY COLUMN_POSITION) OVER(PARTITION BY INDEX_NAME,TABLE_NAME) AS COL_SORT FROM (
            SELECT INDEX_NAME,UNIQUENESS,TABLE_NAME,TO_CHAR(NVL(COLUMN_EXPRESSION,COLUMN_NAME)) AS COLUMN_NAME,DESCEND,COLUMN_POSITION FROM TEMP_COLUMN_EXPRESSION T1 WHERE INDEX_OWNER=pTARGETUSER
          )
      ) T2 ON T1.TABLE_NAME=T2.TABLE_NAME AND T1.INDEX_NAME=T2.INDEX_NAME
      WHERE T1.COL_SORT<>T2.COL_SORT
  )
  LOOP
    --獲取索引源碼
    PKG_GET_DDL.GET_DDL(pSOURCEUSER,pTARGETUSER,1,X.INDEX_NAME,3,pSOURCECODE);
    IF pINDEX=0 THEN
      pSQLTEXT:=pSQLTEXT||CHR(10)||('--開始更新有變更的索引-------------------------------------------------------------');
    END IF;
    pINDEX:=pINDEX+1;
    --刪除舊的索引
    pSQLTEXT:=pSQLTEXT||CHR(10)||'DROP INDEX '||pREPLACEUSER||X.INDEX_NAME||';';
    --添加新的索引
    pSQLTEXT:=pSQLTEXT||pSQLTEXT||pSOURCECODE;
  END LOOP;

  IF pINDEX>0 THEN
    pSQLTEXT:=pSQLTEXT||CHR(10)||('--更新有變更的索引結束!------------------------------------------------------------');
    pINDEX:=0;
  END IF;
END;

PROCEDURE COMPARE_DB
--功能:獲取對比修改數據庫對象的SQL語句.注意因爲獲取源碼權限問題,該過程只能在源用戶庫上執行
--參數:
--調用:
/*
DECLARE pSQLTEXT CLOB;
BEGIN
  SYS.DBMS_OUTPUT.ENABLE(999999);
	PKG_COMPAREDB.COMPARE_DB('DKGLL','',1,pSQLTEXT);
  --DBMS_OUTPUT.PUT_LINE(pSQLTEXT);
  PKG_DBMANAGE.CLOB_TO_FILE('BACKDIR','('||TO_CHAR(CURRENT_DATE,'YYYYMMDDHH24')||').sql','1',pSQLTEXT);
END;
*/
(
	pSOURCEUSER 	IN  VARCHAR2, 			--源用戶名
	pTARGETUSER 	IN  VARCHAR2,  			--目標用戶名
  pOBJTYPE      IN  NUMBER,         --對象類型:0-對比表、序列、處理觸發器的異常等,1-導出全部具備依賴關係的對象(視圖、函數、過程、包)以及其餘能夠進行replace的對象,2-導出全部job、調度
  pDROPTABLE    IN  NUMBER:=1,      --是否刪除表:0-不刪除,其餘-刪除,默認-刪除
  pSQLTEXT      OUT CLOB
)
--當前須要導出的對象按照順序以下:
--1:表
--2:序列
--3:類型
--4:目錄
--5:同義詞
--6:JAVA SOURCE
--7:實體化視圖
--8:視圖、函數、過程、包
--9:觸發器
--10:JOB
--11:調度程序
AS
  pSQLTEXT0 CLOB;
BEGIN
  IF pOBJTYPE=0 THEN
    --1:對比表
    COMPARE_TABLE(pSOURCEUSER,pTARGETUSER,NULL,pDROPTABLE,pSQLTEXT0);
    IF pSQLTEXT0 IS NOT NULL THEN
      pSQLTEXT:=pSQLTEXT0;
    END IF;

    --2:對比序列
    COMPARE_SEQUENCE(pSOURCEUSER,pTARGETUSER,NULL,pSQLTEXT0);
    IF pSQLTEXT0 IS NOT NULL THEN
      pSQLTEXT:=pSQLTEXT||CHR(10)||pSQLTEXT0;
    END IF;

    --3:處理觸發器形成的異常等
    COMPARE_TRIGGER(pSOURCEUSER,pTARGETUSER,pSQLTEXT0);
    IF pSQLTEXT0 IS NOT NULL THEN
      pSQLTEXT:=pSQLTEXT||CHR(10)||pSQLTEXT0;
    END IF;

  ELSIF pOBJTYPE=1 THEN
    --4:目錄

    --4:導出類型
    PKG_GET_DDL.GET_DDL(pSOURCEUSER,pTARGETUSER,0,NULL,6,pSQLTEXT0);
    IF pSQLTEXT0 IS NOT NULL THEN
      pSQLTEXT:='EXECUTE PKG_DBMANAGE.DROP_ALL_OBJECT(USER,''5'');'||CHR(10)||pSQLTEXT0;
    END IF;

    --5:同義詞
    PKG_GET_DDL.GET_DDL(pSOURCEUSER,pTARGETUSER,0,NULL,10,pSQLTEXT0);
    IF pSQLTEXT0 IS NOT NULL THEN
      pSQLTEXT:=pSQLTEXT||CHR(10)||pSQLTEXT0;
    END IF;

    --6:JAVA SOURCE
    PKG_GET_DDL.GET_DDL(pSOURCEUSER,pTARGETUSER,0,NULL,11,pSQLTEXT0);
    IF pSQLTEXT0 IS NOT NULL THEN
      pSQLTEXT:=pSQLTEXT||CHR(10)||REPLACE(pSQLTEXT0,'CREATE JAVA SOURCE','CREATE OR REPLACE JAVA SOURCE');
    END IF;

    --7:實體化視圖
    PKG_GET_DDL.GET_DDL(pSOURCEUSER,pTARGETUSER,0,NULL,12,pSQLTEXT0);
    IF pSQLTEXT0 IS NOT NULL THEN
      pSQLTEXT:=pSQLTEXT||CHR(10)||pSQLTEXT0;
    END IF;

    --8:導出全部具備依賴關係的對象(視圖、函數、過程、包)
    PKG_GET_DDL.GET_DEPEND_DDL(pSOURCEUSER,pTARGETUSER,pSQLTEXT0);
    IF pSQLTEXT0 IS NOT NULL THEN
      pSQLTEXT:=pSQLTEXT||CHR(10)||pSQLTEXT0;
    END IF;

    --9:導出全部觸發器
    PKG_GET_DDL.GET_DDL(pSOURCEUSER,pTARGETUSER,0,NULL,4,pSQLTEXT0);
    IF pSQLTEXT0 IS NOT NULL THEN
      pSQLTEXT:=pSQLTEXT||CHR(10)||pSQLTEXT0;
    END IF;
  ELSIF pOBJTYPE=2 THEN
    --10:JOB
    COMPARE_JOB(pSOURCEUSER,pTARGETUSER,1,pSQLTEXT0);
    IF pSQLTEXT0 IS NOT NULL THEN
      pSQLTEXT:=pSQLTEXT||CHR(10)||pSQLTEXT0;
    END IF;

    --11:調度程序
    COMPARE_SCHEDULER(pSOURCEUSER,pTARGETUSER,1,pSQLTEXT0);
    IF pSQLTEXT0 IS NOT NULL THEN
      pSQLTEXT:=pSQLTEXT||CHR(10)||pSQLTEXT0;
    END IF;
  END IF;
END;
END;
/
CREATE OR REPLACE PACKAGE "PKG_SESSION" 
AS
--功能:設置上下文
PROCEDURE SET_CONTEXT(
  KEY   IN VARCHAR2,
  VALUE IN VARCHAR2
);

--功能:查詢當前會話的詳細信息
PROCEDURE GET_SESSION(pCURSOR OUT SYS_REFCURSOR);

--功能:建立審計用戶操做表
PROCEDURE CREATE_AUDIO_TABLE;

--功能:獲取審計表DDL操做的觸發器文本(根據主鍵列修改,注意標識符不能超過30個字符)
PROCEDURE CREATE_AUDIO_TRIG(
  pTBNAME   IN 	VARCHAR2,						--表名,多個表以','分隔
  pSQLTEXT  OUT CLOB					      --返回審計表的觸發器文本
);
END;
/
CREATE OR REPLACE PACKAGE BODY "PKG_SESSION" 
AS
PROCEDURE SET_CONTEXT
--功能:設置上下文
--參數:KEY-屬性名,VALUE-屬性的值
--調用:
/*
  --首先必須建立一個context,名稱與存儲過程當中SET_CONTEXT的第一個參數名稱相同
  CREATE OR REPLACE CONTEXT DBCONTEXT USING PKG_SESSION;
	EXEC PKG_SESSION.SET_CONTEXT('NAME','郭君');
*/
--日期:2015-08-8
(
  KEY   IN  VARCHAR2,
  VALUE IN  VARCHAR2
)
AS
BEGIN
  DBMS_SESSION.SET_CONTEXT('DBCONTEXT',KEY,VALUE);
END;

PROCEDURE GET_SESSION
--功能:查詢當前會話的詳細信息
--參數:pCURSOR-返回數據集
--調用:
/*
DECLARE pCURSOR SYS_REFCURSOR;
BEGIN
	PKG_SESSION.GET_SESSION(pCURSOR);
END;
*/
--日期:2018-08-8
(
  pCURSOR OUT SYS_REFCURSOR
)
AS
BEGIN
  OPEN pCURSOR FOR SELECT
    SYS_CONTEXT('USERENV','TERMINAL') terminal,
    SYS_CONTEXT('USERENV','IP_ADDRESS') ip_address,
    SYS_CONTEXT('USERENV','LANGUAGE') language,
    SYS_CONTEXT('USERENV','SESSIONID') sessionid,
    SYS_CONTEXT('USERENV','INSTANCE') instance,
    SYS_CONTEXT('USERENV','ENTRYID') entryid,
    SYS_CONTEXT('USERENV','ISDBA') isdba,
    SYS_CONTEXT('USERENV','NLS_TERRITORY') nls_territory,
    SYS_CONTEXT('USERENV','NLS_CURRENCY') nls_currency,
    SYS_CONTEXT('USERENV','NLS_CALENDAR') nls_calendar,
    SYS_CONTEXT('USERENV','NLS_DATE_FORMAT') nls_date_format,
    SYS_CONTEXT('USERENV','NLS_DATE_LANGUAGE') nls_date_language,
    SYS_CONTEXT('USERENV','NLS_SORT') nls_sort,
    SYS_CONTEXT('USERENV','CURRENT_USER') current_user,
    SYS_CONTEXT('USERENV','CURRENT_USERID') current_userid,
    SYS_CONTEXT('USERENV','SESSION_USER') session_user,
    SYS_CONTEXT('USERENV','SESSION_USERID') session_userid,
    SYS_CONTEXT('USERENV','PROXY_USER') proxy_user,
    SYS_CONTEXT('USERENV','PROXY_USERID') proxy_userid,
    SYS_CONTEXT('USERENV','DB_DOMAIN') db_domain,
    SYS_CONTEXT('USERENV','DB_NAME') db_name,
    SYS_CONTEXT('USERENV','HOST') host,
    SYS_CONTEXT('USERENV','OS_USER') os_user,
    SYS_CONTEXT('USERENV','EXTERNAL_NAME') external_name,
    SYS_CONTEXT('USERENV','NETWORK_PROTOCOL') network_protocol,
    SYS_CONTEXT('USERENV','BG_JOB_ID') bg_job_id,
    SYS_CONTEXT('USERENV','FG_JOB_ID') fg_job_id,
    SYS_CONTEXT('USERENV','AUTHENTICATION_TYPE') authentication_type,
    SYS_CONTEXT('USERENV','AUTHENTICATION_DATA') authentication_data
  FROM DUAL;
END;

PROCEDURE CREATE_AUDIO_TABLE
--功能:建立審計用戶操做表
--參數:
--調用:EXEC PKG_SESSION.CREATE_AUDIO_TABLE;
--日期:2018-08-8
AS
	pCOUNT 	NUMBER;
	pSQL 		VARCHAR2(4000);
BEGIN
  SELECT COUNT(1) INTO pCOUNT FROM SYS.DBA_TABLES WHERE OWNER=USER AND TABLE_NAME='AUDIT_DDL_SQL';
  IF pCOUNT=0 THEN                                         --用戶操做表不存在則建立
    pSQL:=q'{CREATE TABLE AUDIT_DDL_SQL
          (
            ID NUMBER,
            SQL VARCHAR2(4000),
            ADDDATE DATE,
            TERMINAL VARCHAR2(200),
            IP_ADDRESS VARCHAR2(30),
            HOST VARCHAR2(200),
            OS_USER VARCHAR2(200),
            DB_NAME VARCHAR2(30),
            PROGRAM VARCHAR2(200),
            MODULE VARCHAR2(200),
            LANGUAGE VARCHAR2(200),
            NETWORK_PROTOCOL VARCHAR2(200),
            CONSTRAINT "PK_AUDIT_DDL_SQL" PRIMARY KEY ("ID")
          )}';
    EXECUTE IMMEDIATE pSQL;
    EXECUTE IMMEDIATE q'{COMMENT ON COLUMN AUDIT_DDL_SQL."ID" IS '自增ID'}';
    EXECUTE IMMEDIATE q'{COMMENT ON COLUMN AUDIT_DDL_SQL."SQL" IS '執行的DDL語句'}';
    EXECUTE IMMEDIATE q'{COMMENT ON COLUMN AUDIT_DDL_SQL."ADDDATE" IS '執行日期時間'}';
    EXECUTE IMMEDIATE q'{COMMENT ON COLUMN AUDIT_DDL_SQL."TERMINAL" IS '終端'}';
    EXECUTE IMMEDIATE q'{COMMENT ON COLUMN AUDIT_DDL_SQL."IP_ADDRESS" IS 'IP地址'}';
    EXECUTE IMMEDIATE q'{COMMENT ON COLUMN AUDIT_DDL_SQL."HOST" IS '主機名'}';
    EXECUTE IMMEDIATE q'{COMMENT ON COLUMN AUDIT_DDL_SQL."OS_USER" IS '系統登陸用戶名'}';
    EXECUTE IMMEDIATE q'{COMMENT ON COLUMN AUDIT_DDL_SQL."DB_NAME" IS '數據庫名稱'}';
    EXECUTE IMMEDIATE q'{COMMENT ON COLUMN AUDIT_DDL_SQL."PROGRAM" IS '調用程序名'}';
    EXECUTE IMMEDIATE q'{COMMENT ON COLUMN AUDIT_DDL_SQL."MODULE" IS '調用程序名'}';
    EXECUTE IMMEDIATE q'{COMMENT ON COLUMN AUDIT_DDL_SQL."LANGUAGE" IS '字符集'}';
    EXECUTE IMMEDIATE q'{COMMENT ON COLUMN AUDIT_DDL_SQL."NETWORK_PROTOCOL" IS '鏈接方式(TCP/IPC)'}';
  END IF;
  SELECT COUNT(1) INTO pCOUNT FROM SYS.DBA_SEQUENCES WHERE SEQUENCE_OWNER=USER AND SEQUENCE_NAME='DDL_SQL_SEQ';
  IF pCOUNT=0 THEN                                         --序列不存在則建立該序列
    EXECUTE IMMEDIATE 'CREATE SEQUENCE  DDL_SQL_SEQ MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 1 CACHE 10 NOORDER  NOCYCLE';
  END IF;
  COMMIT;
  EXCEPTION
    WHEN OTHERS THEN
      SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'執行錯誤:' ||SQLERRM);
END;

PROCEDURE CREATE_AUDIO_TRIG
--功能:獲取審計表DDL操做的觸發器文本(根據主鍵列修改,注意標識符不能超過30個字符)
--參數:pTBNAME-表名,多個表以','分隔,pSQLTEXT-返回審計表DDL操做的觸發器文本
--調用:
/*
DECLARE pSQLTEXT CLOB;
BEGIN
	PKG_SESSION.CREATE_AUDIO_TRIG('DEV_BASETAB',pSQLTEXT);
	DBMS_OUTPUT.PUT_LINE(pSQLTEXT);
END;
*/
--日期:2015-08-8
(
  pTBNAME   IN 	VARCHAR2,						--表名,多個表以','分隔
  pSQLTEXT  OUT CLOB					      --返回審計表的觸發器文本
)
AS
  pSTR1     VARCHAR2(4000);
  pSTR2     VARCHAR2(4000);
  pSTR3     VARCHAR2(4000);
  pSTR4     VARCHAR2(4000);
  pSTR5     VARCHAR2(4000);
  pSTR6     VARCHAR2(4000);
  pSTR7     VARCHAR2(4000);
  pSTR8     VARCHAR2(4000);
  pSTR9     VARCHAR2(4000);
  pINSERT   VARCHAR2(4000);
  pUPDATE   VARCHAR2(4000);
  pDELETE   VARCHAR2(4000);
BEGIN
  /*
    --針對單表的的審計操做,經過觸發器捕捉用戶操做,並將操做的DDL語句錄入到審計表中供分析,觸發器的格式以下:
    CREATE OR REPLACE TRIGGER 觸發器名稱
    BEFORE INSERT OR UPDATE OR DELETE ON 表名
    FOR EACH ROW
    DECLARE
      v_ID       VARCHAR2(64);
      v_NAME     VARCHAR2(64);
      v_AGE      VARCHAR2(30);
      v_BIRTHDAY VARCHAR2(30);
      v_SQLTEXT VARCHAR2(4000);
    BEGIN
      SELECT    DECODE(:NEW."ID",NULL,'NULL',''''||:NEW."ID"||''''),
        DECODE(:NEW."NAME",NULL,'NULL',''''||:NEW."NAME"||''''),
        DECODE(:NEW."AGE",NULL,'NULL',:NEW."AGE"),
        DECODE(:NEW."BIRTHDAY",NULL,'NULL','TO_DATE('''||TO_CHAR(:NEW."BIRTHDAY",'YYYY-MM-DD HH24:MI:SS')||''',''YYYY-MM-DD HH24:MI:SS'')')
        INTO v_ID,v_NAME,v_AGE,v_BIRTHDAY FROM DUAL;
      IF INSERTING THEN
        v_SQLTEXT:=INSERT語句;
      ELSIF UPDATING THEN
        v_SQLTEXT:=UPDATE語句;
      ELSE
        v_SQLTEXT:=DELETE語句;
      END IF;
      --錄入到審計表中
      INSERT INTO LDAPSYNCCMDCACHE VALUES(LDAPSYNCCMDCACHE_SEQ.NEXTVAL,v_SQLTEXT,SYSDATE);
    END;
  */
  FOR TB IN
  (
    SELECT TABLE_NAME FROM SYS.DBA_TABLES WHERE OWNER=USER AND (INSTR(','||pTBNAME||',',','||TABLE_NAME||',',1)>0)
  )
  LOOP
    FOR X IN
    (
      SELECT A.COLUMN_NAME,CASE WHEN DATA_TYPE LIKE '%CHAR%' THEN DATA_LENGTH ELSE 30 END AS CHARLEN,MAX(LENGTH(A.COLUMN_NAME)) OVER(ORDER BY 1) AS COLNAMELEN,COUNT(A.COLUMN_NAME) OVER(ORDER BY 1) AS CN,A.COLUMN_ID,
        CASE WHEN DATA_TYPE LIKE '%CHAR%' THEN 'DECODE(:NEW."'||A.COLUMN_NAME||'",NULL,''NULL'',''''''''||:NEW."'||A.COLUMN_NAME||'"||'''''''')'
        WHEN DATA_TYPE='NUMBER' THEN 'DECODE(:NEW."'||A.COLUMN_NAME||'",NULL,''NULL'',:NEW."'||A.COLUMN_NAME||'")'
        WHEN DATA_TYPE='DATE' THEN 'DECODE(:NEW."'||A.COLUMN_NAME||'",NULL,''NULL'',''TO_DATE(''''''||TO_CHAR(:NEW."'||A.COLUMN_NAME||'",''YYYY-MM-DD HH24:MI:SS'')||'''''',''''YYYY-MM-DD HH24:MI:SS'''')'')'
        ELSE NULL END AS VAL,
        CASE WHEN B.COLUMN_NAME IS NULL THEN 0 ELSE 1 END ISPRIMARY FROM SYS.DBA_TAB_COLUMNS A
        LEFT JOIN (
          SELECT TA.OWNER,TA.TABLE_NAME,TA.COLUMN_NAME FROM SYS.DBA_CONS_COLUMNS TA
            JOIN SYS.DBA_CONSTRAINTS TB ON (TA.OWNER=TB.OWNER AND TA.TABLE_NAME=TB.TABLE_NAME AND TA.CONSTRAINT_NAME=TB.CONSTRAINT_NAME)
            WHERE TB.CONSTRAINT_TYPE='P'
        ) B ON (A.OWNER=B.OWNER AND A.TABLE_NAME=B.TABLE_NAME AND A.COLUMN_NAME=B.COLUMN_NAME)
        WHERE A.OWNER=USER AND A.TABLE_NAME=TB.TABLE_NAME AND A.DATA_TYPE NOT LIKE '%LOB' AND A.DATA_TYPE NOT LIKE '%LONG'
        ORDER BY A.COLUMN_ID
    )
    LOOP
      pSTR1:=pSTR1||'  v_'||X.COLUMN_NAME||LPAD(' ',X.COLNAMELEN-LENGTH(X.COLUMN_NAME)+1,' ')||'VARCHAR2('||X.CHARLEN||');'||CHR(10);
      SELECT pSTR2||'    '||X.VAL||DECODE(X.CN,X.COLUMN_ID,'',','||CHR(10)),
        pSTR3||'v_'||X.COLUMN_NAME||DECODE(X.CN,X.COLUMN_ID,'',','),
        pSTR4||X.COLUMN_NAME||DECODE(X.CN,X.COLUMN_ID,'',','),
        pSTR5||'v_'||X.COLUMN_NAME||DECODE(X.CN,X.COLUMN_ID,'','||'',''||')
        INTO pSTR2,pSTR3,pSTR4,pSTR5 FROM DUAL;
      IF X.ISPRIMARY=0 THEN
        pSTR6:=pSTR6||X.COLUMN_NAME||'=''||v_'||X.COLUMN_NAME||'||'',';
      ELSE
        pSTR7:=pSTR7||X.COLUMN_NAME||'=''||v_'||X.COLUMN_NAME||' AND ';
        pSTR8:=pSTR8||X.COLUMN_NAME||'=''''''||:OLD.'||X.COLUMN_NAME||'||'''''''' AND ';
      END IF;
    END LOOP;
    pSTR9:='  SELECT'||pSTR2||CHR(10)||
           '    INTO '||pSTR3||' FROM DUAL;';
    pINSERT:='    v_SQLTEXT:=''INSERT INTO '||TB.TABLE_NAME||'('||pSTR4||') VALUES(''||'||CHR(10)||
             '                '||pSTR5||'||'')'';';
    pUPDATE:='    v_SQLTEXT:=''UPDATE '||TB.TABLE_NAME||' SET '||SUBSTR(pSTR6,1,LENGTH(pSTR6)-4)||'||'||CHR(10)||
             '               ''  WHERE '||SUBSTR(pSTR7,1,LENGTH(pSTR7)-5)||';';
    pDELETE:='    v_SQLTEXT:=''DELETE FROM '||TB.TABLE_NAME||' WHERE '||SUBSTR(pSTR8,1,LENGTH(pSTR8)-5)||';';
    pSQLTEXT:=pSQLTEXT||
             'CREATE OR REPLACE TRIGGER '||TB.TABLE_NAME||'_AUDIT'||CHR(10)||
             'BEFORE INSERT OR UPDATE OR DELETE ON '||TB.TABLE_NAME||' --審計用戶對該表的增刪改操做'||CHR(10)||
             'FOR EACH ROW'||CHR(10)||
             'DECLARE'||CHR(10)||
             pSTR1||'  v_SQLTEXT VARCHAR2(4000);'||CHR(10)||
             'BEGIN'||CHR(10)||
             pSTR9||CHR(10)||
             '  /*'||CHR(10)||
             '    插入時往歷史表存放的新插入的數據'||CHR(10)||
             '    修改時往歷史表存放的修改後的數據'||CHR(10)||
             '    刪除時往歷史表存放的刪除以前的數據'||CHR(10)||
             '  */'||CHR(10)||
             '  IF INSERTING THEN'||CHR(10)||
             pINSERT||CHR(10)||
             '  ELSIF UPDATING THEN'||CHR(10)||
             pUPDATE||CHR(10)||
             '  ELSE'||CHR(10)||
             pDELETE||CHR(10)||
             '  END IF;'||CHR(10)||
             '  INSERT INTO AUDIT_DDL_SQL(ID,SQL,ADDDATE,TERMINAL,IP_ADDRESS,HOST,OS_USER,DB_NAME,PROGRAM,MODULE,LANGUAGE,NETWORK_PROTOCOL)'||CHR(10)||
             '    SELECT DDL_SQL_SEQ.NEXTVAL,v_SQLTEXT,SYSDATE,SYS_CONTEXT(''USERENV'',''TERMINAL''),SYS_CONTEXT(''USERENV'',''IP_ADDRESS''),SYS_CONTEXT(''USERENV'',''HOST''),SYS_CONTEXT(''USERENV'',''OS_USER''),'||CHR(10)||
             '      SYS_CONTEXT(''USERENV'',''DB_NAME''),PROGRAM,MODULE,SYS_CONTEXT(''USERENV'',''LANGUAGE''),SYS_CONTEXT(''USERENV'',''NETWORK_PROTOCOL'') FROM v$session WHERE AUDSID=SYS_CONTEXT(''USERENV'',''SESSIONID'');'||CHR(10)||
             'END;'||CHR(10)||
             '/'||CHR(10);
  END LOOP;
  --DBMS_OUTPUT.PUT_LINE(pSQLTEXT);
END;
END;
/
CREATE OR REPLACE PACKAGE "PKG_SELECT" 
AS
--定義表、列記錄類型
TYPE TBCOL IS RECORD
(
  TABLENAME   VARCHAR2(60),   --表名
  COLUMNNAME  VARCHAR2(60),   --列名
  SELECTSQL   VARCHAR2(2000)  --查詢語句
);

--定義表、列記錄集合類型
TYPE TBCOLLIST IS TABLE OF TBCOL;

--功能:查詢整個數據庫中某個特定值所在的表和字段
FUNCTION FINDVALUEINDB(
  pVAL    IN VARCHAR2,        --查找的特定值
  pMODEL  IN NUMBER:=0        --匹配模式,0-精確匹配,1-左匹配,2-左右模糊匹配,默認精確匹配
)
RETURN TBCOLLIST PIPELINED;
END;
/ 
CREATE OR REPLACE PACKAGE BODY "PKG_SELECT" 
AS
FUNCTION FINDVALUEINDB
--功能:查詢整個數據庫中某個特定值所在的表和字段
--參數:
--調用:SELECT * FROM TABLE(PKG_SELECT.FINDVALUEINDB('管理',1))
--日期:2014-12-10
(
  pVAL    IN VARCHAR2,        --查找的特定值
  pMODEL  IN NUMBER:=0        --匹配模式,0-左匹配,1-左右模糊匹配,其餘--精確匹配,默認左匹配
)
RETURN TBCOLLIST PIPELINED
IS
  pSQL    VARCHAR2(200);      --保存要執行的SQL語句
  pREGSTR VARCHAR2(200);      --保存左右匹配的綁定變量值
  pCOUNT  NUMBER;             --統計表列的值等於傳遞特定值的數量
  INFO  TBCOL;                --保存的記錄類型
  BEGIN
    FOR X IN
    (
      SELECT A.TABLE_NAME,A.COLUMN_NAME FROM SYS.USER_TAB_COLUMNS  A JOIN SYS.USER_TABLES B ON A.TABLE_NAME=B.TABLE_NAME
        WHERE A.DATA_TYPE='VARCHAR2' AND A.CHAR_LENGTH>=LENGTHB(pVAL) AND B.TEMPORARY='N'
        ORDER BY A.TABLE_NAME,A.COLUMN_NAME
    )
    LOOP
      pSQL:='SELECT COUNT(1) FROM "'||X.TABLE_NAME||'" WHERE "'||X.COLUMN_NAME||'" LIKE :1';
      SELECT DECODE(pMODEL,1,'%','')||pVAL||DECODE(pMODEL,0,'%',1,'%','') INTO pREGSTR FROM DUAL;
      EXECUTE IMMEDIATE pSQL INTO pCOUNT USING pREGSTR;
      IF pCOUNT>=1 THEN
        INFO.TABLENAME:=X.TABLE_NAME;
        INFO.COLUMNNAME:=X.COLUMN_NAME;
        INFO.SELECTSQL:='SELECT "'||X.COLUMN_NAME||'" FROM "'||X.TABLE_NAME||'" WHERE "'||X.COLUMN_NAME||'" LIKE '''||pREGSTR||'''';
        PIPE ROW(INFO);
      END IF;
    END LOOP;
    RETURN;
  END;
END;
/
CREATE OR REPLACE PACKAGE "PKG_BACKUP" 
AS
--功能:備份指定用戶下的表數據
PROCEDURE EXPORT_DB
(
  pUSER     IN VARCHAR2 := USER,
  pDIR      IN VARCHAR2 := 'DATA_PUMP_DIR',
  pFILENAME IN VARCHAR2 := NULL
);
END;
/ 
CREATE OR REPLACE PACKAGE BODY "PKG_BACKUP" 
AS
PROCEDURE EXPORT_DB
--功能:備份指定用戶下的表數據
--參數:
--調用:
/*
EXEC PKG_BACKUP.EXPORT_DB;
*/
--日期:2016-03-11
(
  pUSER     IN VARCHAR2 := USER,
  pDIR      IN VARCHAR2 := 'DATA_PUMP_DIR',
  pFILENAME IN VARCHAR2 := NULL
)
AS
  l_backname        VARCHAR2(200);
  l_dp_handle       NUMBER;
BEGIN
  SYS.DBMS_OUTPUT.ENABLE(999999);
  l_backname := 'TBS1-'||TO_CHAR(CURRENT_DATE,'YYYYMMDDHH24')||'.DMP';
  DBMS_OUTPUT.PUT_LINE(l_backname);
  --version={COMPATIBLE|LATEST|version_string}
  --version:爲COMPATIBLE時,會根據初始化參數COMPATIBLE生成對象元數據;爲LATEST時會根據數據庫的實際版本生成對象元數據;version_string用於指定數據庫版本字符串
  l_dp_handle :=  DBMS_DATAPUMP.open (operation     => 'EXPORT'
                                    , job_mode      => 'TABLE'
                                    , remote_link   => NULL
                                    , version       => 'LATEST');

  DBMS_DATAPUMP.add_file (handle      => l_dp_handle
                        , filename    => l_backname
                        , directory   => pDIR
                        , filetype    => 1
                        , reusefile   => 1);  --爲1表示覆蓋更新

  DBMS_DATAPUMP.add_file (handle      => l_dp_handle
                        , filename    => 'empdp.log'
                        , directory   => pDIR
                        , filetype    => 3);

  --若是非當前賬戶,使用下面的過濾條件,即特定schema下的特定表,如爲當前賬戶,此過濾條件可省略
  DBMS_DATAPUMP.METADATA_FILTER (HANDLE => l_dp_handle
                              ,  name   => 'SCHEMA_EXPR'
                              ,  value  => 'IN ('''||pUSER||''')');

  DBMS_DATAPUMP.set_parameter(handle       => l_dp_handle
                              ,name        => 'KEEP_MASTER'
                              ,value       => 0);

  DBMS_DATAPUMP.set_parameter(handle       => l_dp_handle
                              ,name        => 'INCLUDE_METADATA'
                              ,value       => 1);

  DBMS_DATAPUMP.set_parameter(handle       => l_dp_handle
                              ,name        => 'DATA_ACCESS_METHOD'
                              ,value       => 'AUTOMATIC');

  DBMS_DATAPUMP.set_parameter(handle       => l_dp_handle
                              ,name        => 'ESTIMATE'
                              ,value       => 'BLOCKS');
  --設定並行度
  DBMS_DATAPUMP.set_parallel (l_dp_handle, 2);

  DBMS_DATAPUMP.start_job (handle          => l_dp_handle
                            ,skip_current  => 0
                            ,abort_step    => 0 );

  DBMS_DATAPUMP.detach (l_dp_handle);
END;
END;
/
CREATE OR REPLACE PACKAGE PKG_MAIL
AUTHID CURRENT_USER IS
--功能:用oracle發送郵件
PROCEDURE SEND_EMAIL( 
  P_SENDOR      VARCHAR2,                 --發送人郵件地址
  P_RECEIVER    VARCHAR2,                 --接收人郵件地址,能夠同時發送到多個地址上,地址之間用","或者";"隔開
  P_SUB         VARCHAR2,                 --郵件標題
  P_CONTENT     VARCHAR2,                 --郵件正文,能夠爲文本或者HTML。
  p_CONTENTTYPE VARCHAR2,                 --郵件正文類型,1或者txt-表示文本,2或者html表示爲html
  P_FILENAME    VARCHAR2 DEFAULT NULL,    --附件名稱,必須包含完整的路徑,如"d:\temp\a.txt"。能夠有多個附件,地址之間用","或者";"隔開
  P_ENCODE      VARCHAR2 DEFAULT 'bit 7', --附件編碼轉換格式,其中 p_encode='bit 7' 表示文本類型附件,p_encode='base64' 表示二進制類型附件
                                          --注意:
                                          --    一、對於文本類型的附件,不能用base64的方式發送,不然出錯
                                          --    二、對於多個附件只能用同一種格式發送
  P_SERVER      VARCHAR2,                 --郵件服務器地址,能夠是域名或者IP
  P_PORT        NUMBER DEFAULT 25,        --郵件服務器端口,默認國內未加密的SMTP端口爲25
  P_NEED_SMTP   INT DEFAULT 0,            --是否須要smtp認證,0表示不須要,1表示須要
  P_USER        VARCHAR2 DEFAULT NULL,    --smtp驗證須要的用戶名
  P_PASS        VARCHAR2 DEFAULT NULL     --smtp驗證須要的密碼
);
END;
/
CREATE OR REPLACE PACKAGE BODY PKG_MAIL
AS
PROCEDURE SEND_EMAIL
--功能:用oracle發送郵件
--參數: 
--調用:
--日期:2017-03-05
( 
  P_SENDOR      VARCHAR2,                 --發送人郵件地址
  P_RECEIVER    VARCHAR2,                 --接收人郵件地址,能夠同時發送到多個地址上,地址之間用","或者";"隔開
  P_SUB         VARCHAR2,                 --郵件標題
  P_CONTENT     VARCHAR2,                 --郵件正文,能夠爲文本或者HTML。
  p_CONTENTTYPE VARCHAR2,                 --郵件正文類型,1或者txt-表示文本,2或者html表示爲html
  P_FILENAME    VARCHAR2 DEFAULT NULL,    --附件名稱,必須包含完整的路徑,如"d:\temp\a.txt"。能夠有多個附件,地址之間用","或者";"隔開
  P_ENCODE      VARCHAR2 DEFAULT 'bit 7', --附件編碼轉換格式,其中 p_encode='bit 7' 表示文本類型附件,p_encode='base64' 表示二進制類型附件
                                          --注意:
                                          --    一、對於文本類型的附件,不能用base64的方式發送,不然出錯
                                          --    二、對於多個附件只能用同一種格式發送
  P_SERVER      VARCHAR2,                 --郵件服務器地址,能夠是域名或者IP
  P_PORT        NUMBER DEFAULT 25,        --郵件服務器端口,默認國內未加密的SMTP端口爲25
  P_NEED_SMTP   INT DEFAULT 0,            --是否須要smtp認證,0表示不須要,1表示須要
  P_USER        VARCHAR2 DEFAULT NULL,    --smtp驗證須要的用戶名
  P_PASS        VARCHAR2 DEFAULT NULL     --smtp驗證須要的密碼
) 
AS
  /* 
    主要功能:一、支持多收件人。
            二、支持中文
            三、支持抄送人
            四、支持大於32K的附件
            五、支持多行正文
            六、支持多附件
            七、支持文本附件和二進制附件
            八、支持HTML格式 
    注意:若是不是sys用戶操做,需開啓ACL權限,步驟以下:
    BEGIN
      DBMS_NETWORK_ACL_ADMIN.CREATE_ACL (
                                          acl          => 'email_server_permissions.xml',
                                          description  => 'Enables network permissions for the e-mail server',
                                          principal    => 'PKGTEST',--進行操做的數據庫用戶且用戶要大寫
                                          is_grant     => TRUE,
                                          privilege    => 'connect');
    END;
    
    BEGIN
      DBMS_NETWORK_ACL_ADMIN.assign_acl (
                                         acl         => 'email_server_permissions.xml',
                                         host        => 'smtp.mxhichina.com',      
                                         lower_port  => 25,
                                         upper_port  => NULL);
      COMMIT;
    END;
    
    SELECT host, lower_port, upper_port, acl FROM sys.dba_network_acls; 
    
    BEGIN
      dbms_network_acl_admin.add_privilege(
                                           acl        => 'utlpkg.xml',
                                           principal =>'PKGTEST',--進行操做的數據庫用戶且用戶要大寫                                                                        
                                           is_grant   =>  TRUE,
                                           privilege  => 'connect');
    END;
    
    SELECT acl,
           principal,
           privilege,
           is_grant,
           TO_CHAR(start_date, 'DD-MON-YYYY') AS start_date,
           TO_CHAR(end_date, 'DD-MON-YYYY') AS end_date
      FROM sys.dba_network_acl_privileges; 
  /*
  /*
    調用示例:測試採用新浪郵箱發送已經過
    declare phtml varchar2(4000);
    begin
      phtml:=q'[
      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      <html xmlns="http://www.w3.org/1999/xhtml">
      <head>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
      <title>Oracle導出HTML郵件</title>
      <style type="text/css">
      *{margin:0;padding:0}
      body{width:867px; margin:0 auto;background:#2c383e url(images/bgindex.jpg) repeat-x;} 
      h2{text-align:center;height:50px;line-height:50px;letter-spacing:2px;}
      #content{ width:580px; height:850px; float:left; background:#fff url(images/weline.gif) repeat-y left top; padding-left:20px;}
      #content h1{background:url(images/job.gif) no-repeat left 20px;  height:60px;text-indent:-9999px;} 
      #content table{width:540px;line-height:30px;font-size:12px; background:#ccc; border-collapse:collapse}
      #content table tr {text-align:center; background:#fff}
      #content table tr th{font-weight:normal; background:#eee;border:1px solid gray}
      #content table tr:hover{background:#CC0}
      #content table tr td{border:1px solid gray}
      #content table tr td a{ text-decoration:none}
      #content table tr td a:hover{ text-decoration:underline}
      #content .contentp1{text-align:center; margin-top:30px; font-size:12px;margin-bottom:30px} 
      #content .contentp2{width:540px;font-size:12px;text-align:right;height:25px;line-height:25px}
      </style>
      </head> 
      <body> 
      <div id="content">  
        <h2>數據表格展現</h2>
        <table>
              <tr><th>序號</th><th>職位名稱</th><th>招聘人數</th><th>工做地點</th><th>有效時間</th><th>職位描述</th></th>
              <tr><td>1</td><td>保安人員</td><td>3至4人</td><td>武漢</td><td>2016.12.08</td><td><a href="#">查看</a></td></tr>
              <tr><td>2</td><td>項目技術人員</td><td>18人</td><td>北京</td><td>2016.10.08</td><td><a href="#">查看</a></td></tr>
              <tr><td>3</td><td>總經理助理</td><td>3人</td><td>溫州</td><td>2016.07.11</td><td><a href="#">查看</a></td></tr>  
              <tr><td>4</td><td>銷售表明</td><td>40人</td><td>溫州</td><td>2016.07.11</td><td><a href="#">查看</a></td></tr>   
              <tr><td>5</td><td>客服</td><td>15人</td><td>溫州</td><td>2016.07.11</td><td><a href="#">查看</a></td></tr>      
          </table>
          <p class="contentp1">共計:5 條記錄 頁次:1/1 每頁:5 條 上一頁/下一頁</p> 
        <p class="contentp2">來源:Oracle數據庫</p>
        <p class="contentp2">記錄人:dkgll</p> 
      </div>  
      </body>
      </html>
      ]'; 
      PKG_MAIL.SEND_EMAIL('dkgll@sina.com','xx@qq.com,xx@126.com,xx@sina.com','Oracle導出HTMl郵件',phtml,2,'C:\index.html,E:\XXXX.txt','bit 7','smtp.sina.com',25,1,'yy@sina.com','****');
    END;
  */
  L_CONTYPE       VARCHAR2(20);
  L_CRLF          VARCHAR2(2) := UTL_TCP.CRLF;
  L_SENDORADDRESS VARCHAR2(4000);
  L_SPLITE        VARCHAR2(10) := '++';
  BOUNDARY            CONSTANT VARCHAR2(256) := '-----BYSUK';
  FIRST_BOUNDARY      CONSTANT VARCHAR2(256) := '--' || BOUNDARY || L_CRLF;
  LAST_BOUNDARY       CONSTANT VARCHAR2(256) := '--' || BOUNDARY || '--' ||
                                                L_CRLF;
  MULTIPART_MIME_TYPE CONSTANT VARCHAR2(256) := 'multipart/mixed; boundary="' ||
                                                BOUNDARY || '"';
  /* 如下部分是發送大二進制附件時用到的變量 */
  L_FIL                 BFILE;
  L_FILE_LEN            NUMBER;
  L_MODULO              NUMBER;
  L_PIECES              NUMBER;
  L_FILE_HANDLE         UTL_FILE.FILE_TYPE;
  L_AMT                 BINARY_INTEGER := 672 * 3; /* ensures proper format;  2016 */
  L_FILEPOS             PLS_INTEGER := 1;          /* pointer for the file */
  L_CHUNKS              NUMBER;
  L_BUF                 RAW(2100);
  L_DATA                RAW(2100);
  L_MAX_LINE_WIDTH      NUMBER := 54;
  L_DIRECTORY_BASE_NAME VARCHAR2(100) := 'DIR_FOR_SEND_MAIL';
  L_LINE                VARCHAR2(1000);
  L_MESG                VARCHAR2(32767);
  /* 以上部分是發送大二進制附件時用到的變量 */

  TYPE ADDRESS_LIST IS TABLE OF VARCHAR2(100) INDEX BY BINARY_INTEGER;
  MY_ADDRESS_LIST ADDRESS_LIST;
  TYPE ACCT_LIST IS TABLE OF VARCHAR2(100) INDEX BY BINARY_INTEGER;
  MY_ACCT_LIST ACCT_LIST;
  -------------------------------------返回附件源文件所在目錄或者名稱--------------------------------------
  FUNCTION GET_FILE(P_FILE VARCHAR2,
                    P_GET  INT) RETURN VARCHAR2 IS
    --p_get=1 表示返回目錄
    --p_get=2 表示返回文件名
    L_FILE VARCHAR2(1000);
  BEGIN
    IF INSTR(P_FILE,
             '\') > 0
    THEN
      --windows
      IF P_GET = 1
      THEN
        L_FILE := SUBSTR(P_FILE,
                         1,
                         INSTR(P_FILE,
                               '\',
                               -1) - 1);
      ELSIF P_GET = 2
      THEN
        L_FILE := SUBSTR(P_FILE,
                         - (LENGTH(P_FILE) - INSTR(P_FILE,
                                                  '\',
                                                  -1)));
      END IF;
    ELSIF INSTR(P_FILE,
                '/') > 0
    THEN
      --linux/unix
      IF P_GET = 1
      THEN
        L_FILE := SUBSTR(P_FILE,
                         1,
                         INSTR(P_FILE,
                               '/',
                               -1) - 1);
      ELSIF P_GET = 2
      THEN
        L_FILE := SUBSTR(P_FILE,
                         - (LENGTH(P_FILE) - INSTR(P_FILE,
                                                  '/',
                                                  -1)));
      END IF;
    END IF;
    RETURN L_FILE;
  END;
  ---------------------------------------------刪除directory------------------------------------
  PROCEDURE DROP_DIRECTORY(P_DIRECTORY_NAME VARCHAR2) IS
  BEGIN
    EXECUTE IMMEDIATE 'drop directory ' || P_DIRECTORY_NAME;
  EXCEPTION
    WHEN OTHERS THEN
      NULL;
  END;
  --------------------------------------------------建立directory-----------------------------------------
  PROCEDURE CREATE_DIRECTORY(P_DIRECTORY_NAME VARCHAR2,
                             P_DIR            VARCHAR2) IS
  BEGIN
    EXECUTE IMMEDIATE 'create directory ' || P_DIRECTORY_NAME || ' as ''' ||
                      P_DIR || '''';
    EXECUTE IMMEDIATE 'grant read,write on directory ' || P_DIRECTORY_NAME ||
                      ' to public';
  EXCEPTION
    WHEN OTHERS THEN
      RAISE;
  END;
  --------------------------------------------分割郵件地址或者附件地址-----------------------------------
  PROCEDURE P_SPLITE_STR(P_STR         VARCHAR2,
                         P_SPLITE_FLAG INT DEFAULT 1) IS
    L_ADDR VARCHAR2(254) := '';
    L_LEN  INT;
    L_STR  VARCHAR2(4000);
    J      INT := 0; --表示郵件地址或者附件的個數
  BEGIN
    /*處理接收郵件地址列表,包括去空格、將;轉換爲,等*/
    L_STR := TRIM(RTRIM(REPLACE(REPLACE(P_STR,
                                        ';',
                                        ','),
                                ' ',
                                ''),
                        ','));
    L_LEN := LENGTH(L_STR);
    FOR I IN 1 .. L_LEN LOOP
      IF SUBSTR(L_STR,
                I,
                1) <> ','
      THEN
        L_ADDR := L_ADDR || SUBSTR(L_STR,
                                   I,
                                   1);
      ELSE
        J := J + 1;
        IF P_SPLITE_FLAG = 1
        THEN
          --表示處理郵件地址
          --先後須要加上'<>',不然不少郵箱將不能發送郵件
          L_ADDR := '<' || L_ADDR || '>';
          --調用郵件發送過程
          MY_ADDRESS_LIST(J) := L_ADDR;
        ELSIF P_SPLITE_FLAG = 2
        THEN
          --表示處理附件名稱
          MY_ACCT_LIST(J) := L_ADDR;
        END IF;
        L_ADDR := '';
      END IF;
      IF I = L_LEN
      THEN
        J := J + 1;
        IF P_SPLITE_FLAG = 1
        THEN
          --調用郵件發送過程
          L_ADDR := '<' || L_ADDR || '>';
          MY_ADDRESS_LIST(J) := L_ADDR;
        ELSIF P_SPLITE_FLAG = 2
        THEN
          MY_ACCT_LIST(J) := L_ADDR;
        END IF;
      END IF;
    END LOOP;
  END;
  ------------------------------------------------寫郵件頭和郵件內容------------------------------------------
  PROCEDURE WRITE_DATA(P_CONN   IN OUT NOCOPY UTL_SMTP.CONNECTION,
                       P_NAME   IN VARCHAR2,
                       P_VALUE  IN VARCHAR2,
                       P_SPLITE VARCHAR2 DEFAULT ':',
                       P_CRLF   VARCHAR2 DEFAULT L_CRLF) IS
  BEGIN
    /* utl_raw.cast_to_raw 對解決中文亂碼問題很重要*/
    UTL_SMTP.WRITE_RAW_DATA(P_CONN,
                            UTL_RAW.CAST_TO_RAW(CONVERT(P_NAME || P_SPLITE ||
                                                        P_VALUE || P_CRLF,
                                                        'ZHS16GBK')));
  END;
  ----------------------------------------寫MIME郵件尾部-----------------------------------------------------

  PROCEDURE END_BOUNDARY(CONN IN OUT NOCOPY UTL_SMTP.CONNECTION,
                         LAST IN BOOLEAN DEFAULT FALSE) IS
  BEGIN
    UTL_SMTP.WRITE_DATA(CONN,
                        UTL_TCP.CRLF);
    IF (LAST)
    THEN
      UTL_SMTP.WRITE_DATA(CONN,
                          LAST_BOUNDARY);
    END IF;
  END;

  ----------------------------------------------發送附件----------------------------------------------------

  PROCEDURE ATTACHMENT(CONN         IN OUT NOCOPY UTL_SMTP.CONNECTION,
                       MIME_TYPE    IN VARCHAR2 DEFAULT 'text/plain',
                       INLINE       IN BOOLEAN DEFAULT TRUE,
                       FILENAME     IN VARCHAR2 DEFAULT 't.txt',
                       TRANSFER_ENC IN VARCHAR2 DEFAULT '7 bit',
                       DT_NAME      IN VARCHAR2 DEFAULT '0') IS
  
    L_FILENAME VARCHAR2(1000);
  BEGIN
    --寫附件頭
    UTL_SMTP.WRITE_DATA(CONN,
                        FIRST_BOUNDARY);
    --設置附件格式
    WRITE_DATA(CONN,
               'Content-Type',
               MIME_TYPE);
    --若是文件名稱非空,表示有附件
    DROP_DIRECTORY(DT_NAME);
    --建立directory
    CREATE_DIRECTORY(DT_NAME,
                     GET_FILE(FILENAME,
                              1));
    --獲得附件文件名稱
    L_FILENAME := GET_FILE(FILENAME,
                           2);
    IF (INLINE)
    THEN
      WRITE_DATA(CONN,
                 'Content-Disposition',
                 'inline; filename="' || L_FILENAME || '"');
    ELSE
      WRITE_DATA(CONN,
                 'Content-Disposition',
                 'attachment; filename="' || L_FILENAME || '"');
    END IF;
  
    --設置附件的轉換格式
    IF (TRANSFER_ENC IS NOT NULL)
    THEN
      WRITE_DATA(CONN,
                 'Content-Transfer-Encoding',
                 TRANSFER_ENC);
    END IF;
  
    UTL_SMTP.WRITE_DATA(CONN,
                        UTL_TCP.CRLF);
  
    --begin 貼附件內容
    IF TRANSFER_ENC = 'bit 7'
    THEN
      --若是是文本類型的附件
      BEGIN
        L_FILE_HANDLE := UTL_FILE.FOPEN(DT_NAME,
                                        L_FILENAME,
                                        'r'); --打開文件
        --把附件分紅多份,這樣能夠發送超過32K的附件
        LOOP
          UTL_FILE.GET_LINE(L_FILE_HANDLE,
                            L_LINE);
          L_MESG := L_LINE || L_CRLF;
          WRITE_DATA(CONN,
                     '',
                     L_MESG,
                     '',
                     '');
        END LOOP;
        UTL_FILE.FCLOSE(L_FILE_HANDLE);
        END_BOUNDARY(CONN);
      EXCEPTION
        WHEN OTHERS THEN
          UTL_FILE.FCLOSE(L_FILE_HANDLE);
          END_BOUNDARY(CONN);
          NULL;
      END; --結束文本類型附件的處理
    
    ELSIF TRANSFER_ENC = 'base64'
    THEN
      --若是是二進制類型的附件
      BEGIN
        --把附件分紅多份,這樣能夠發送超過32K的附件
        L_FILEPOS  := 1; --重置offset,在發送多個附件時,必須重置
        L_FIL      := BFILENAME(DT_NAME,
                                L_FILENAME);
        L_FILE_LEN := DBMS_LOB.GETLENGTH(L_FIL);
        L_MODULO   := MOD(L_FILE_LEN,
                          L_AMT);
        L_PIECES   := TRUNC(L_FILE_LEN / L_AMT);
        IF (L_MODULO <> 0)
        THEN
          L_PIECES := L_PIECES + 1;
        END IF;
        DBMS_LOB.FILEOPEN(L_FIL,
                          DBMS_LOB.FILE_READONLY);
        DBMS_LOB.READ(L_FIL,
                      L_AMT,
                      L_FILEPOS,
                      L_BUF);
        L_DATA := NULL;
        FOR I IN 1 .. L_PIECES LOOP
          L_FILEPOS  := I * L_AMT + 1;
          L_FILE_LEN := L_FILE_LEN - L_AMT;
          L_DATA     := UTL_RAW.CONCAT(L_DATA,
                                       L_BUF);
          L_CHUNKS   := TRUNC(UTL_RAW.LENGTH(L_DATA) / L_MAX_LINE_WIDTH);
          IF (I <> L_PIECES)
          THEN
            L_CHUNKS := L_CHUNKS - 1;
          END IF;
          UTL_SMTP.WRITE_RAW_DATA(CONN,
                                  UTL_ENCODE.BASE64_ENCODE(L_DATA));
          L_DATA := NULL;
          IF (L_FILE_LEN < L_AMT AND L_FILE_LEN > 0)
          THEN
            L_AMT := L_FILE_LEN;
          END IF;
          DBMS_LOB.READ(L_FIL,
                        L_AMT,
                        L_FILEPOS,
                        L_BUF);
        END LOOP;
        DBMS_LOB.FILECLOSE(L_FIL);
        END_BOUNDARY(CONN);
      EXCEPTION
        WHEN OTHERS THEN
          DBMS_LOB.FILECLOSE(L_FIL);
          END_BOUNDARY(CONN);
          RAISE;
      END; --結束處理二進制附件
    
    END IF; --結束處理附件內容
    DROP_DIRECTORY(DT_NAME);
  END; --結束過程ATTACHMENT

  ---------------------------------------------真正發送郵件的過程--------------------------------------------
  PROCEDURE P_EMAIL(P_SENDORADDRESS2   VARCHAR2, --發送地址
                    P_RECEIVERADDRESS2 VARCHAR2) --接受地址
   IS
    L_CONN UTL_SMTP.CONNECTION; --定義鏈接
  BEGIN
    /*初始化郵件服務器信息,鏈接郵件服務器*/
    L_CONN := UTL_SMTP.OPEN_CONNECTION(P_SERVER,
                                       P_PORT);
    --使用UTL_SMTP.HELO有可能會提示「ORA-29279: SMTP 永久性錯誤: 503 5.5.2 Send hello first.」,改爲使用UTL_SMTP.EHLO就行了
    --UTL_SMTP.HELO(L_CONN, P_SERVER);
    UTL_SMTP.EHLO(L_CONN,
                  P_SERVER);
    /* smtp服務器登陸校驗 */
    IF P_NEED_SMTP = 1
    THEN
      UTL_SMTP.COMMAND(L_CONN,
                       'AUTH LOGIN',
                       '');
      UTL_SMTP.COMMAND(L_CONN,
                       UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(UTL_RAW.CAST_TO_RAW(P_USER))));
      UTL_SMTP.COMMAND(L_CONN,
                       UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(UTL_RAW.CAST_TO_RAW(P_PASS))));
    END IF;
  
    /*設置發送地址和接收地址*/
    UTL_SMTP.MAIL(L_CONN,
                  P_SENDORADDRESS2);
    UTL_SMTP.RCPT(L_CONN,
                  P_RECEIVERADDRESS2);
  
    /*設置郵件頭*/
    UTL_SMTP.OPEN_DATA(L_CONN);
  
    WRITE_DATA(L_CONN,
               'Date',
               TO_CHAR(SYSDATE,
                       'yyyy-mm-dd hh24:mi:ss'));
    /*設置發送人*/
    WRITE_DATA(L_CONN,
               'From',
               P_SENDOR);
    /*設置接收人*/
    WRITE_DATA(L_CONN,
               'To',
               P_RECEIVER);
    /*設置郵件主題*/
    WRITE_DATA(L_CONN,
               'Subject',
               P_SUB);
  
    WRITE_DATA(L_CONN,
               'Content-Type',
               MULTIPART_MIME_TYPE);
    UTL_SMTP.WRITE_DATA(L_CONN,
                        UTL_TCP.CRLF);
    UTL_SMTP.WRITE_DATA(L_CONN,
                        FIRST_BOUNDARY);  
                        
    SELECT DECODE(lower(p_CONTENTTYPE),'1','plain','txt','plain','2','html','html','html','plain') INTO L_CONTYPE FROM DUAL;
    WRITE_DATA(L_CONN,
               'Content-Type',
               'text/'||L_CONTYPE||';charset=gb2312');
    --單獨空一行,不然,正文內容不顯示
    UTL_SMTP.WRITE_DATA(L_CONN,
                        UTL_TCP.CRLF);
    /* 設置郵件正文
      把分隔符還原成chr(10)。這主要是爲了shell中調用該過程,若是有多行,則先把多行的內容合併成一行,並用 l_splite分隔
      而後用 l_crlf替換chr(10)。這一步是必須的,不然將不能發送郵件正文有多行的郵件
    */
    WRITE_DATA(L_CONN,
               '',
               REPLACE(REPLACE(P_CONTENT,
                               L_SPLITE,
                               CHR(10)),
                       CHR(10),
                       L_CRLF),
               '',
               ''); 
    END_BOUNDARY(L_CONN);
  
    --若是文件名稱不爲空,則發送附件
    IF (P_FILENAME IS NOT NULL)
    THEN
      --根據逗號或者分號拆分附件地址
      P_SPLITE_STR(P_FILENAME,
                   2);
      --循環發送附件(在同一個郵件中)
      FOR K IN 1 .. MY_ACCT_LIST.COUNT LOOP
        ATTACHMENT(CONN         => L_CONN,
                   FILENAME     => MY_ACCT_LIST(K),
                   TRANSFER_ENC => P_ENCODE,
                   DT_NAME      => L_DIRECTORY_BASE_NAME || TO_CHAR(K));
      END LOOP;
    END IF;
  
    /*關閉數據寫入*/
    UTL_SMTP.CLOSE_DATA(L_CONN);
    /*關閉鏈接*/
    UTL_SMTP.QUIT(L_CONN);
  
    /*異常處理*/
  EXCEPTION
    WHEN OTHERS THEN
      NULL;
      RAISE;
    
  END;

  ---------------------------------------------------主過程-----------------------------------------------------

BEGIN
  L_SENDORADDRESS := '<' || P_SENDOR || '>';
  P_SPLITE_STR(P_RECEIVER); --處理郵件地址
  FOR K IN 1 .. MY_ADDRESS_LIST.COUNT LOOP
    P_EMAIL(L_SENDORADDRESS,
            MY_ADDRESS_LIST(K));
  END LOOP;
  /*處理郵件地址,根據逗號分割郵件*/

EXCEPTION
  WHEN OTHERS THEN
    RAISE;
END;
END;
/ 
相關文章
相關標籤/搜索