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; /