Oracle DBA管理包脚本系列

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Oracle DBA管理包脚本系列相关的知识,希望对你有一定的参考价值。

该系列脚本结合日常工作,方便DBA做数据管理、迁移、同步等功能,以下为该系列的脚本,按照功能划分不同的包。功能有如下:

1)数据库对象管理(添加、修改、删除、禁用/启用、编译、去重复、闪回、文件读写、会话管理、表空用、用户/权限管理);

2)数据库分析;

3)数据库备份;

4)数据库同步;

5)数据库数据导出;

6)获取数据库对象源码;

7)数据库对比智能升级;

......

更多功能请自行体验。

 

本系列包依赖于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, 				--源表名,如果为远程链接表,类似为[email protected]的格式,如:[email protected]_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-只比较基础数据类型,如VARCHAR2、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:=‘[email protected]‘||pLINKNAME||‘ A JOIN [email protected]‘||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(‘[email protected]‘,‘USR_INFOTAB‘,pCURSOR);
END;
*/
--日期:2014-05-8
(
	pSOURCETB 	IN  VARCHAR, 				--源表名,如果为远程链接表,类似为[email protected]的格式,如:[email protected]_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-只比较基础数据类型,如VARCHAR2、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-只比较基础数据类型,如VARCHAR2、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 [email protected]‘||pTARGETLINK||‘ A ‘||CHR(10)||
             ‘  JOIN [email protected]‘||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 [email protected]‘||pTARGETLINK||‘ A ‘||CHR(10)||
            ‘     JOIN [email protected]‘||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-只比较基础数据类型,如VARCHAR2、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 [email protected]‘||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 [email protected]‘||
			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 [email protected]‘||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 [email protected]‘||pLINKNAME||‘
									WHERE OWNER=‘‘‘||pUSER||‘‘‘ AND ‘‘‘||pTBLIST||‘‘‘ IS NULL AND TEMPORARY=‘‘N‘‘
						)
				) TB LEFT JOIN [email protected]‘||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 [email protected]‘||pLINKNAME||‘ A
				JOIN [email protected]‘||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‘ 表示二进制类型附件
                                          --注意:
                                          --    1、对于文本类型的附件,不能用base64的方式发送,否则出错
                                          --    2、对于多个附件只能用同一种格式发送
  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‘ 表示二进制类型附件
                                          --注意:
                                          --    1、对于文本类型的附件,不能用base64的方式发送,否则出错
                                          --    2、对于多个附件只能用同一种格式发送
  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
  /* 
    主要功能:1、支持多收件人。
            2、支持中文
            3、支持抄送人
            4、支持大于32K的附件
            5、支持多行正文
            6、支持多附件
            7、支持文本附件和二进制附件
            8、支持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(‘[email protected]‘,‘[email protected],[email protected],[email protected]‘,‘Oracle导出HTMl邮件‘,phtml,2,‘C:\index.html,E:\XXXX.txt‘,‘bit 7‘,‘smtp.sina.com‘,25,1,‘[email protected]‘,‘****‘);
    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;
/ 

  

以上是关于Oracle DBA管理包脚本系列的主要内容,如果未能解决你的问题,请参考以下文章

oracle系列5:权限管理

Oracle内核系列3-揭秘ASM磁盘头信息

oracle系列高级DBA必知的Oracle的备份与恢复(全录收集)

Oracle DBA 必须掌握的 查询脚本:

如何在 Toad for Oracle 中使用自定义代码片段?

oracle的dba是啥意思