該系列腳本結合平常工做,方便DBA作數據管理、遷移、同步等功能,如下爲該系列的腳本,按照功能劃分不一樣的包。功能有以下:css
1)數據庫對象管理(添加、修改、刪除、禁用/啓用、編譯、去重複、閃回、文件讀寫、會話管理、表空用、用戶/權限管理);html
2)數據庫分析;java
3)數據庫備份;linux
4)數據庫同步;sql
5)數據庫數據導出;shell
6)獲取數據庫對象源碼;數據庫
7)數據庫對比智能升級;c#
......windows
更多功能請自行體驗。服務器
本系列包依賴於Oracle DBA管理包腳本系列系列(一)的腳本。
EXEC PKG_DBMANAGE.DROP_OBJECT(USER,'CHECKTABLELIST'); EXEC PKG_DBMANAGE.DROP_OBJECT(USER,'CHECKTABLE'); CREATE OR REPLACE TYPE CHECKTABLE IS OBJECT ( TABLENAME VARCHAR2(40), WHERESTR VARCHAR2(2000) ); / CREATE OR REPLACE TYPE CHECKTABLELIST IS TABLE OF CHECKTABLE; / EXEC PKG_DBMANAGE.DROP_OBJECT(USER,'TEMP_TAB_COLUMNS'); EXEC PKG_DBMANAGE.DROP_OBJECT(USER,'TEMP_COLUMN_EXPRESSION'); CREATE GLOBAL TEMPORARY TABLE "TEMP_TAB_COLUMNS" ( "OWNER" VARCHAR2(64 BYTE), "TABLE_NAME" VARCHAR2(64 BYTE), "COLUMN_NAME" VARCHAR2(64 BYTE), "DATA_TYPE" VARCHAR2(64 BYTE), "ORACLETYPE" VARCHAR2(64 BYTE), "NULLABLE" CHAR(10 BYTE), "DATA_DEFAULT" CLOB, "COLUMN_ID" NUMBER ) ON COMMIT PRESERVE ROWS ; CREATE GLOBAL TEMPORARY TABLE "TEMP_COLUMN_EXPRESSION" ( "INDEX_OWNER" VARCHAR2(64 BYTE), "INDEX_NAME" VARCHAR2(200 BYTE), "INDEX_TYPE" VARCHAR2(64 BYTE), "UNIQUENESS" VARCHAR2(64 BYTE), "COMPRESSION" VARCHAR2(64 BYTE), "TABLE_NAME" VARCHAR2(64 BYTE), "TABLE_TYPE" VARCHAR2(64 BYTE), "COLUMN_NAME" VARCHAR2(64 BYTE), "COLUMN_EXPRESSION" CLOB, "COLUMN_POSITION" NUMBER, "DESCEND" VARCHAR2(64 BYTE) ) ON COMMIT PRESERVE ROWS ; COMMENT ON TABLE "TEMP_COLUMN_EXPRESSION" IS '保存索引列的詳細信息'; EXEC PKG_DBMANAGE.DROP_OBJECT(USER,'TEMP_DIRLIST'); CREATE GLOBAL TEMPORARY TABLE "TEMP_DIRLIST" ( "DIR" VARCHAR2(255 BYTE), "FILENAME" VARCHAR2(255 BYTE), "FILESIZE" NUMBER, "FILEDATE" DATE ) ON COMMIT PRESERVE ROWS ; COMMENT ON COLUMN "TEMP_DIRLIST"."DIR" IS '文件目錄'; COMMENT ON COLUMN "TEMP_DIRLIST"."FILENAME" IS '文件名稱'; COMMENT ON COLUMN "TEMP_DIRLIST"."FILESIZE" IS '文件大小'; COMMENT ON COLUMN "TEMP_DIRLIST"."FILEDATE" IS '建立文件日期'; COMMENT ON TABLE "TEMP_DIRLIST" IS '文件列表'; CREATE OR REPLACE JAVA SOURCE NAMED "JAVA_DEL_FILE" AS import java.io.*; import java.sql.*; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.io.File; import java.lang.String; public class JAVA_DEL_FILE { /** * 刪除目錄下全部文件(按時間排序) * * @param path * @return */ public static String delAllFile(String Directory,String Filter) throws SQLException { List<File> list1 = getFileSort(Directory,Filter); for (int i = 1;i< list1.size();i++) { list1.get(i).delete(); } return "0"; } /** * 獲取目錄下全部文件(按時間排序) * * @param path * @return */ public static List<File> getFileSort(String path,String filter) { List<File> list1 = getFiles(path, new ArrayList<File>(),filter); if (list1 != null) { if(list1.size() > 0) { Collections.sort(list1, new Comparator<File>() { public int compare(File file, File newFile) { if (file.lastModified() < newFile.lastModified()) { return 1; } else if (file.lastModified() == newFile.lastModified()) { return 0; } else { return -1; } } }); } } return list1; } /** * 獲取目錄下全部文件 * * @param realpath * @param files * @return */ public static List<File> getFiles(String realpath, List<File> files,String filter) { File realFile = new File(realpath); if (realFile.isDirectory()) { File[] subfiles = realFile.listFiles(); for (File file : subfiles) { if (file.isDirectory()) { getFiles(file.getAbsolutePath(),files,filter); } else { if(file.getName().toUpperCase().indexOf(filter)!=-1) { files.add(file); } } } } return files; } } / CREATE OR REPLACE JAVA SOURCE NAMED "JAVA_DIRLIST" AS import java.io.*; import java.sql.*; public class JAVA_DIRLIST { public static void getList(String directory) throws SQLException { File path=new File(directory); String[] fileList=path.list(); String fileName; long fileSize; long fileDate; for (int i=0;i<fileList.length; i++) { fileName=fileList[i]; File fpath=new File(directory+'/'+fileName); fileSize=fpath.length(); fileDate=fpath.lastModified(); #sql{insert into TEMP_DIRLIST(DIR,filename,filesize,filedate) values(:directory,:fileName,:fileSize,to_date('1970-01-01 08:00:00','YYYY-MM-DD HH24:MI:SS')+:fileDate/(24*60*60*1000))}; } } } / CREATE OR REPLACE PROCEDURE "EXEC_JAVA_DIRLIST" --功能:執行Java程序獲取文件列表 --參數:見下方說明 --調用: /* DELETE FROM TEMP_DIRLIST; EXEC EXEC_JAVA_DIRLIST('E:\'); select * from TEMP_DIRLIST; */ --日期:2014-09-16 ( p_directory in varchar2 ) as language java name 'JAVA_DIRLIST.getList( java.lang.String )'; / create or replace package PKG_GetHZPY is -- Author : ADMINISTRATOR -- Created : 2006-10-8 上午 11:51:16 -- Purpose : 得到漢字拼音編碼 -- Public type declarations TYPE THZPY_LIST is VARRAY (526) OF VARCHAR2(6); TYPE TROMA_NUM_LIST is VARRAY (94) OF VARCHAR2(2); TYPE TGREECE_ALPHABET_LIST is VARRAY (24) OF VARCHAR2(2); TYPE TPYIndex_191_list IS VARRAY(191) OF NUMBER; TYPE TPYIndex_list IS VARRAY(10) OF TPYIndex_191_list; -- Public constant declarations --<ConstantName> constant <Datatype> := <Value>; -- Public variable declarations --<VariableName> <Datatype>; -- Public function and procedure declarations function GetHzPY_by_index(p_PY_Index number) RETURN VARCHAR2; FUNCTION get_greece_alphabet_py(p_Index NUMBER) RETURN NUMBER; FUNCTION get_roma_num_py(p_Index NUMBER) RETURN NUMBER; FUNCTION get_py_index_01(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER; FUNCTION get_py_index_02(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER; FUNCTION get_py_index_03(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER; FUNCTION get_py_index_04(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER; FUNCTION get_py_index_05(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER; FUNCTION get_py_index_06(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER; FUNCTION get_py_index_07(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER; FUNCTION get_py_index_08(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER; FUNCTION get_py_index_09(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER; FUNCTION get_py_index_10(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER; FUNCTION get_py_index_11(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER; FUNCTION get_py_index_12(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER; FUNCTION get_py_index_13(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER; FUNCTION GetHzFullPY(p_String varchar2) RETURN VARCHAR2; FUNCTION GetHzFullPYLower(p_String varchar2) RETURN VARCHAR2; FUNCTION GetHzFullPYUpper(p_String varchar2) RETURN VARCHAR2; FUNCTION GetHzFullPYsubstr(p_String varchar2,s float, e float) RETURN VARCHAR2; FUNCTION GetHzPYCAP(p_String varchar2) RETURN VARCHAR2; FUNCTION GetHzPYCAPLower(p_String varchar2) RETURN VARCHAR2; FUNCTION GetHzPYCAPsubstr(p_String varchar2,s float, e float) RETURN VARCHAR2; FUNCTION F_TRANS_PINYIN_CAPITAL(P_NAME IN VARCHAR2) RETURN VARCHAR2; end; / create or replace package body PKG_GetHZPY is -- Private type declarations --type <TypeName> is <Datatype>; -- Private constant declarations --<ConstantName> constant <Datatype> := <Value>; -- Private variable declarations --<VariableName> <Datatype>; -- Function and procedure implementations FUNCTION GetHzPY_by_index(p_PY_Index number) RETURN VARCHAR2 IS v_PY_List THZPY_LIST := THZPY_LIST( 'a', 'aes', 'ai', 'an', 'ang', 'ao', 'ba', 'bai', 'baike', 'baiwa', 'ban', 'bang', 'bao', 'be', 'bei', 'ben', 'beng', 'bi', 'bia', 'bian', 'biao', 'bie', 'bin', 'bing', 'bo', 'bu', 'ca', 'cai', 'cal', 'can', 'cang', 'cao', 'ce', 'cen', 'ceng', 'ceok', 'ceom', 'ceon', 'ceor', 'cha', 'chai', 'chan', 'chang', 'chao', 'che', 'chen', 'cheng', 'chi', 'chong', 'chou', 'chu', 'chua', 'chuai', 'chuan', 'chuang', 'chui', 'chun', 'chuo', 'ci', 'cis', 'cong', 'cou', 'cu', 'cuan', 'cui', 'cun', 'cuo', 'da', 'dai', 'dan', 'dang', 'dao', 'de', 'defa', 'dei', 'deli', 'dem', 'den', 'deng', 'deo', 'di', 'dia', 'dian', 'diao', 'die', 'dim', 'ding', 'diu', 'dong', 'dou', 'du', 'duan', 'dug', 'dui', 'dul', 'dun', 'duo', 'e', 'ei', 'en', 'eng', 'eo', 'eol', 'eom', 'eos', 'er', 'fa', 'fan', 'fang', 'fei', 'fen', 'feng', 'fenwa', 'fiao', 'fo', 'fou', 'fu', 'fui', 'ga', 'gad', 'gai', 'gan', 'gang', 'gao', 'ge', 'gei', 'gen', 'geng', 'geo', 'geu', 'gib', 'go', 'gong', 'gongli', 'gou', 'gu', 'gua', 'guai', 'guan', 'guang', 'gui', 'gun', 'guo', 'ha', 'hai', 'hal', 'han', 'hang', 'hao', 'haoke', 'he', 'hei', 'hem', 'hen', 'heng', 'heui', 'ho', 'hol', 'hong', 'hou', 'hu', 'hua', 'huai', 'huan', 'huang', 'hui', 'hun', 'huo', 'hwa', 'hweong', 'i', 'ji', 'jia', 'jialun', 'jian', 'jiang', 'jiao', 'jie', 'jin', 'jing', 'jiong', 'jiu', 'jou', 'ju', 'juan', 'jue', 'jun', 'ka', 'kai', 'kal', 'kan', 'kang', 'kao', 'ke', 'keg', 'kei', 'kem', 'ken', 'keng', 'keo', 'keol', 'keop', 'keos', 'keum', 'ki', 'kong', 'kos', 'kou', 'ku', 'kua', 'kuai', 'kuan', 'kuang', 'kui', 'kun', 'kuo', 'kweok', 'kwi', 'la', 'lai', 'lan', 'lang', 'lao', 'le', 'lei', 'lem', 'len', 'leng', 'li', 'lia', 'lian', 'liang', 'liao', 'lie', 'lin', 'ling', 'liu', 'liwa', 'lo', 'long', 'lou', 'lu', 'luan', 'lue', 'lun', 'luo', 'lv', 'm', 'ma', 'mai', 'man', 'mang', 'mangmi', 'mao', 'mas', 'me', 'mei', 'men', 'meng', 'meo', 'mi', 'mian', 'miao', 'mie', 'min', 'ming', 'miu', 'mo', 'mol', 'mou', 'mu', 'myeo', 'myeon', 'myeong', 'n', 'na', 'nai', 'nan', 'nang', 'nao', 'ne', 'nei', 'nem', 'nen', 'neng', 'neus', 'ng', 'ngag', 'ngai', 'ngam', 'ni', 'nian', 'niang', 'niao', 'nie', 'nin', 'ning', 'niu', 'nong', 'nou', 'nu', 'nuan', 'nue', 'nun', 'nung', 'nuo', 'nv', 'nve', 'o', 'oes', 'ol', 'on', 'ou', 'pa', 'pai', 'pak', 'pan', 'pang', 'pao', 'pei', 'pen', 'peng', 'peol', 'phas', 'phdeng', 'phoi', 'phos', 'pi', 'pian', 'piao', 'pie', 'pin', 'ping', 'po', 'pou', 'ppun', 'pu', 'q', 'qi', 'qia', 'qian', 'qiang', 'qianke', 'qianwa', 'qiao', 'qie', 'qin', 'qing', 'qiong', 'qiu', 'qu', 'quan', 'que', 'qun', 'ra', 'ram', 'ran', 'rang', 'rao', 're', 'ren', 'reng', 'ri', 'rong', 'rou', 'ru', 'rua', 'ruan', 'rui', 'run', 'ruo', 'sa', 'saeng', 'sai', 'sal', 'san', 'sang', 'sao', 'se', 'sed', 'sei', 'sen', 'seng', 'seo', 'seon', 'sha', 'shai', 'shan', 'shang', 'shao', 'she', 'shei', 'shen', 'sheng', 'shi', 'shike', 'shiwa', 'shou', 'shu', 'shua', 'shuai', 'shuan', 'shuang', 'shui', 'shun', 'shuo', 'shw', 'si', 'so', 'sol', 'song', 'sou', 'su', 'suan', 'sui', 'sun', 'suo', 'ta', 'tae', 'tai', 'tan', 'tang', 'tao', 'tap', 'te', 'tei', 'teng', 'teo', 'teul', 'teun', 'ti', 'tian', 'tiao', 'tie', 'ting', 'tiu', 'tol', 'ton', 'tong', 'tou', 'tu', 'tuan', 'tui', 'tun', 'tuo', 'uu', 'wa', 'wai', 'wan', 'wang', 'wei', 'wen', 'weng', 'wie', 'wo', 'wu', 'xi', 'xia', 'xian', 'xiang', 'xiao', 'xie', 'xin', 'xing', 'xiong', 'xiu', 'xu', 'xuan', 'xue', 'xun', 'ya', 'yan', 'yang', 'yao', 'ye', 'yen', 'yi', 'yin', 'ying', 'yo', 'yong', 'you', 'yu', 'yuan', 'yue', 'yug', 'yun', 'za', 'zad', 'zai', 'zan', 'zang', 'zao', 'ze', 'zei', 'zen', 'zeng', 'zha', 'zhai', 'zhan', 'zhang', 'zhao', 'zhe', 'zhei', 'zhen', 'zheng', 'zhi', 'zhong', 'zhou', 'zhu', 'zhua', 'zhuai', 'zhuan', 'zhuang', 'zhui', 'zhun', 'zhuo', 'zi', 'zo', 'zong', 'zou', 'zu', 'zuan', 'zui', 'zun', 'zuo' ); BEGIN IF (p_PY_Index>0) AND (p_PY_Index<527) THEN RETURN INITCAP(v_PY_List(p_PY_Index)); ELSE RETURN ''; END IF; END GetHzPY_by_index; FUNCTION get_greece_alphabet_py(p_Index NUMBER) RETURN NUMBER IS v_greece_alphabet_list TGREECE_ALPHABET_LIST := TGREECE_ALPHABET_LIST( 'a','b','g','d','e','z','e','th','i','k','l','m','n','x','o','p','r', 's','t','u','ph','kh','ps','o' ); BEGIN IF (p_Index>0) AND (p_Index<95) THEN RETURN v_greece_alphabet_list(p_Index); ELSE RETURN ''; END IF; end get_greece_alphabet_py; FUNCTION get_roma_num_py(p_Index NUMBER) RETURN NUMBER IS v_rom_num_list TROMA_NUM_LIST := TROMA_NUM_LIST( '1','2','3','4','5','6','7','8','9','10','','','','','','', '1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20', '1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20', '1','2','3','4','5','6','7','8','9','10','','', '1','2','3','4','5','6','7','8','9','10','','', '1','2','3','4','5','6','7','8','9','10','11','12','','' ); BEGIN IF (p_Index>0) AND (p_Index<95) THEN RETURN v_rom_num_list(p_Index); ELSE RETURN ''; END IF; end get_roma_num_py; FUNCTION get_py_index_01(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER IS v_list01 TPYIndex_list := TPYIndex_list( TPYIndex_191_list(483,389,458,273,262, 50,395, 88,350,232,482, 24,182,172,178,213, 42,517,144,180, 117,477,477,456,182,157,508,161,394,478,471,121,182,146,158, 90,395,279,190,201, 437,269,311, 29,469,472,326,386,276,341,410,103, 65, 39,507,141,122,243,235,477, 186,249,507, 0,483,408,415,128,471,499,471, 68,475,460,180,475,482,500,231, 97, 451,172,355,456, 7, 24,115,423,102,459,503,159,147, 25, 44,501,389,361,108,263, 341,455,474,112, 55,450, 81,508,320,483, 84, 96,456,477,463,172, 3,478,328,393, 117,422,522,487,184,459,470,463,494,459,301,291,462,467,509,522, 17,328,477,408, 477,506,147,250,510, 26,351, 18,502, 59,473,500, 18,459,351,395, 13,166,151,460, 125,107,266, 24,155,168,141,352, 59,464,393,445,145,220,477,140,478,261,467, 4, 242,106,245, 40, 48,470,509,366,175,408, 69), TPYIndex_191_list(418,297,179,181,435,505,526, 50,247,184,399,435,393,445, 25,278,461,443,483,457, 467,140,209,456,477,117,232,167,479,459,376,320,457,262,458,466, 81,184,507,220, 408,168,461,175, 21,431,110,471, 15,483,463,161,506,507, 24,182,474,522,232,449, 234, 55,520, 0,125,432,399,258,421,515,464,333,339,122,232,415,346,109,507,520, 245,411,236,167, 89,518, 16,456,184,277, 28,175,475,386,346,479, 47,341,368,508, 57,451,483, 24,431,472,112,422,455, 98, 45,394,191, 81, 40, 15,498,165,474,500, 521,472,482,467,498, 59,117,117,507,262,172,477,462,470,408, 92,499,505,440, 15, 491,346,451,412,507,413,458,484,364,301,487,176,249, 83,422,149,178,457,388,341, 353, 46, 51,376, 15,461,481,474,421,417,473,107, 24,460,490,136,376,225,481,493, 520,322,411,513,483,499,522,389, 55,180,147), TPYIndex_191_list(501,348,478, 81,462,241, 15,330,179,231,242,251,341,459,421,479, 89,525,388,345, 181,443,525,337,223, 43,140,339,427,513,451,172, 25,166, 57,434,388,474,111,459, 483, 98,235, 25,136,459,459,265,475,179,340,345,112,509, 3,374,477,187,299,421, 477, 71,211, 0,175, 51,177,386,490, 30, 23, 4,420, 72, 41,221,477,179,341,259, 456,297,349,291, 43,234,247,213, 13,483, 21,491,507,408,482,149,348,347,229,427, 451,240, 51, 42,460,433,462,229,246,491,306,422,472,246,279,491,465,369,369,441, 43,291,291,179,472,395,396,343, 0,150,393, 90, 9,134,165,456,369,232,483,147, 432,336,172,477,254,357,472,254,498,181,137,181,254,509,135,467,482,191,477,261, 395,259,184,208,265,117,462,261,420,123,161,317,117,265,340,175,412,257,441,136, 180,348, 89,122,478, 3,229, 31,266,516, 65), TPYIndex_191_list(408, 97,179,235,457, 91,108,108,184, 51,506,112,271,507,112,112,189,122,333,211, 147,361, 55,172,341, 66,172, 70,449,186,229,117,351, 84,265,236,508, 22,178,178, 388, 42,128, 55,214, 97,106,178, 59,180, 90,246,494,484, 67,194,386, 55, 67,229, 110, 42,339, 0, 55,518,123,337, 97,348,517,175,172,472,168, 97,507,456,137,394, 175,498,189,342, 54, 42,513,242,229,322,388,208,137,162,498,517,231,184,237,141, 177,141,175,175,439,172,175,175,507, 42,523,268,229,510,471,180,199,462,507,477, 510,268,223,185,208,473,447,461,270,213,178,234,194,180,124,265, 48,222,481,194, 185,348,242, 26,220,189,262, 89,467,456,477,470,473,394,233,242,330,395,172,342, 177,352,460,477,469,108,185,439,184, 70,250,470,470,247,229, 45,460,352,487,182, 13,253, 18,121,121,477,322,184,474,125, 98), TPYIndex_191_list(133, 68,182,133,280,182,477,176,192,161,351,108,346,492,213,161,483,141,166, 70, 214,231,231,414, 91,182,351,457,194,472,351,470,292,522,395,457,449,449,462,388, 172,401,213,457,462,357,473,349,390, 48,467,457,214,172, 98,457,376,472,503,147, 471, 81,499, 0,318, 2,346,471,507,252,431,391,435,524,110,494,484,229, 83,347, 6,141,472,229, 43,341,229,472,472,484,159,262,365,351,204,225, 91,513,393,393, 393,477, 69,398,186, 7,371,395,517,458,461,172,487,369, 61,137,350, 48, 93,159, 264,252,468,518, 97,475,313,168,477, 50,347,462,335,162,159,483,306,469,366,313, 124,187,247,125,452,339,456,177,487, 48,394,444,452, 98,395,185,321,452,270,357, 81,395,509,434,457,477,339,333,518,467,477,461,471,351,459,445,335, 22,117,473, 168,420, 68,447,526, 26,418,459,168,339,106), TPYIndex_191_list( 98,507,510,470,461,210,395,433,275,468,448,223,439,465,482,261,292,464,336,149, 487,240,335,252,522,151,459,223,334,232, 7,264,247,415,117,147,485,482,136,136, 15,147,477,341,441,472,449,229,350, 45,493,471, 90,339, 81,347,255,159,428,203, 232,222,386, 0,519,455,478,339,447,342, 4,494,292,483,432,220,457, 3,300,517, 499,488,461,460,516,456,452,431,136,339,339, 70,475,518,441, 65,151,471,339,503, 232,459,479,137,494,143,246,290, 81,352,445,130,422, 4, 70,483,503,509, 41,448, 483,491,474,262,161,487,164,484,172,508,451,386,467,165,498,472,232,483,377,189, 345,472,388,321,416,480,451,479,327, 15,131,493,168,431,474,461,342,379,481,159, 462,249, 40,145,366,447,172,318,456,459,518,242,447,174,417, 60,374,132,276,342, 18, 6,231,524,510,268,421,177, 49,177,189), TPYIndex_191_list(421,393, 3,461,241,461,161,166,143,467,459,494, 43,334, 73,249,161,119,422,475, 374,177,461,162,250,357,461,461,172,214,461,149,248,345,467,445,421,470,456,525, 108,189,166, 30, 55,488, 70,483,444,457,339,149,231,467,166,478,470,474,408,472, 479, 68,500, 0,517,299,485,462,345,484, 3,481,451,483,321, 72,463, 96, 71,463, 328,478,524,297, 81,221,418,455,458,475, 97,466,509,499,179, 43,470,256,507,242, 166,319,482,474,478,480,257,159,503,229,237,145,279,268,472,229,242,240,268, 70, 46,332,328,460,256,457, 97,209,472, 42,479, 86,219,418,461, 58,164,168,513,503, 461,498,229, 42, 41,229,477,246,491,413,156,496,175,488,510,221,295,356,239,166, 478,296,442,192,484,181,329,487, 61,166, 98,143,439,441,143,354,363,143,420,143, 478,167,147,245,143, 56,451,484,352,209,337), TPYIndex_191_list(484,484,471,442,441,441,442,244,166,477,243,243,471,441,435,337,242,211,471,516, 413,413,517, 71,340,458,388,295,268,173,507,470,477,347,257,364,444,111, 18,464, 221,180,172, 81,464,317,422,351,517,137,420,181,473,115,242,350,135,469, 7,236, 510,117,161, 0,507, 6, 69,319,265,172,151,247, 59, 48,478,160, 94,502,117,140, 474, 97,141, 40,473,462,398, 24,159, 68,188, 71,148, 4,464,459, 12,335, 15,477, 478,147,467,515,347,112,109,353,481,187,458, 81,222,185,347,503,234,162, 26,181, 475, 81,471,352,415,506,449,184,245,506,206,389, 89,421, 28,440, 17,459, 97,477, 507,516,339,184,291,194,215,291,175,123,483,471,136,228,109,471,215, 4,393,280, 441, 47,164, 18,231,455,513, 13,483,456,178,368,475,128,520,483,165, 98,474,117, 172,257,389,445,478,112,508,178,179,155,123), TPYIndex_191_list( 57,459,333,225,464,165, 92,449,468,457,172,211,479,481,189,413,395,261,453, 47, 441,353,508,229,322, 12,492, 94,505,456,506,470,505, 3,133,472,191,452,462,237, 145,222,389,322, 17, 46,242,242,313,341,257,268,513,403,241, 21, 33,507,501,191, 83, 46,517, 0,172,143,342,347, 81, 65,472,418,497,341,451,515,345,388,388,110, 337,443,442,108,353, 96,525, 81,394,166, 97,421, 79,456,111,165,421, 68,475,510, 175,483,342,345,198,477,328, 83,176,475,469,421,221,184,163, 71,358,341,470,459, 457, 3,471, 72,368,179,247,213,242,472,421,451,166,240,240,369,229,235, 42,470, 472,225, 7,449,376,514,477,250,510,514,161,215,161,467,215,398,252, 96,398,477, 479,176,318,499, 20,415,354,236, 67,468,462,280,458,484,449,507,348,310,135,339, 259,259, 46,494,186,124,423,420,472, 18,169), TPYIndex_191_list(487,462, 7,100,431,319,185,462, 83,473,164,189,498, 16,165,110, 84,470,199, 6, 453,420,456, 6,176,231, 97,487,176,395,111,168, 18,243, 97,435,341,182,302, 40, 459,108,172,159, 70,482,180,178,452,508,314,199,508,487,328, 48,485,514,472,278, 463,111,112, 0,484, 91, 25,517,502,291,484,440,468,507, 98,268, 18,393, 98,151, 467,107,506,265, 11,117,236,518,357,459,473,251,518,184,361, 89,172,121,460,168, 185,135,175,175,292,507,505,459,155,140,470,210,472,266,234,320,471,482,472,459, 431,447,352,411,159,459,390,394,462,252,117,456,194,220, 63,435,464,278,483,334, 415,507,147,514,333,443,459,483,472,456,457,472,483,408,229,184,515,339,459,517, 89,242, 98, 98,247,262, 61,335,184, 28,236,461,399,339,166,117,455,455,421,110, 110,432,291,352,180,180,341, 83,464,161,449) ); BEGIN IF (p_Index>0) AND (p_Index<192) THEN RETURN v_list01(p_Index1)(p_Index); ELSE RETURN 0; END IF; end get_py_index_01; FUNCTION get_py_index_02(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER IS v_list02 TPYIndex_list := TPYIndex_list( TPYIndex_191_list(220,478,509,280,117,245, 4,215,478,471,184,229, 83,459,162,162,473,474,278,371, 173,483,483,451,431,365,257, 70,368,348,166,455,341, 57,263,117,178, 92,477,508, 165,262,472,479,468,178,451,506,350,507,462,445,231,254,357,408,329,451,447, 63, 161,346, 13, 0,467,483,141,521,474,484,364,366,237,257,317,487,249,214,393,505, 484,417,364,266,479,413,294,423,318,222,280, 13,328,477,483,468,484,477,192,481, 291,524,179,513,494,278,223,503,161,161, 6,368,249,331,136,456,345,445,500,263, 459,459,268,233,231,162,141, 79,507,467,477,162,457,214,474,472, 42,177,257,117, 108,472,477,152,177,117,395,415,342,231,468,463,294, 89,477, 30, 3,293,297,249, 433, 50,179, 59,483,332,364,366,291,472,420,479,341,485,262, 18,393,464,291, 91, 237,484,221,472,236,177,358,221,459,479,403), TPYIndex_191_list(462,352,261,229,243,472,510,221,186,518,463,408,420,482,513,470,264, 61,449,471, 477,518,229,469, 25,277,295,479,243,364,349,441,365,474,477,180,516,510,159,395, 477,433,457, 47,354,133,461,498,395,393,165,261,208, 28,491,484,350,151,505,175, 297, 24,164, 0,347,395,297,179,297,507,483, 13,212,297,247,347,161,507,297,393, 451,462,212,166,187,477,477, 13,347,240, 13,112,247, 94,334,513,334,194,473,513, 470,510, 94, 72,178,261,261,399,389,268,233,459,459,215,482,294,318,450,450,450, 474, 97,214,508,122,136,512,122,122,457, 18,178,432, 84,395,505,462,291,457,446, 251,241,333,462,110,462,247, 35,462,184,186,233,186,510,462,334,447,459,229,472, 72,166,240,361,456,147,393, 51,476,485, 11,474, 5,456,178,172,111,449,341,339, 178,526,526,473,184,123,469,334,229,433,522), TPYIndex_191_list(117,445,328, 6,213,351,334,433,236, 48,333, 37, 12,439,469, 20,151,194,246, 98, 295, 85,242,100,106,121,352,477,271,395, 4,451,164,261,229,172,439,451,482,136, 234,474,177, 98,475, 26,354,112,280,229,482,459,364, 72,393, 47,441,128,124,458, 478,483,279, 0,191,472,353, 49,418,235,162,184,220,265,215,215,522,136,471,123, 245,245,236, 97,506,478, 89,147,506,451,328,178,522,209, 89,478,518,494,165,483, 473,112,350,473,431,477,507,395, 98,510,500,247,472,257,147,172,164,435,456,483, 520,221,194,472,472,451,520, 40,417,194,347,431,441, 94,457,453, 31,422,479,178, 189,237,456,345, 17, 83,341,481,295, 67,395,371,411,520,176,233,192, 42, 85, 34, 87,441,241,500,500, 6, 32,351,342,524,524, 72, 72,457,483,328,240,460,506, 25, 347,177,472,223,500,233,233,347, 97,525,345), TPYIndex_191_list(186,474,177,474,186,500,477,469,280,475,475,477,295,472,172,462,194,457, 81, 6, 524,451,364, 72,236,178,483,485,478,366,178,234,457,240,240,479,457,184, 42,479, 451,472,280,352, 44, 64,243, 83, 83,295,472,472,472,280,472,211,165,464, 44,234, 200,337,337, 0,350,507,502,477,179,416,352,324,334,488, 87,295,111,314,507,161, 70, 69,447,117,268,477,477,333,340,185,366,401,404,345,505,395,354, 69,141,333, 501,376,449, 69,386,339, 91,160,506,467,451,477, 12,333, 85,133,317,423,261,173, 427,166,508,393, 21,143,494,271, 12,180, 42,507,456, 18, 18,501,261,345, 42,111, 259, 12, 72,264, 51,178,459,221,175, 24,122,172,435,494,140,256,347,444,471,463, 178,514,471, 59,439,477,507,433,507,461,441,141,209,259,482, 26, 24, 47,220,172, 411,399,348,483,263,412,494,460,110,182, 98), TPYIndex_191_list(451,237,458,412,507, 26,348,182,182,241,478,457,242,477, 51,441,408,463,263, 43, 456,110,213,207,211, 18,379,235,233,247,172,479,459,435,481,229,435,472, 81,334, 166,277,166,111,351,472,492,477,106,376,106,395, 84,161,456,443,176, 7,393,501, 423,117, 81, 0, 44,505,477,352,390,484,180, 84,501,176,342,322, 18,391,421,175, 125,107, 18,208,175, 22,461,421,143,342,159,291,143,449,186,172,242,166,166,477, 477,477,485,485,452,472,483, 48, 84,481,330, 48,517,477,172,508,450, 81,236,117, 450,457,450,506,507,180, 61,507, 61,446,172,507,520,509,220,462,178,175,431,458, 329,117,451,318,457,506,330,431, 73,507, 22,508, 45,474,166,257,240,460, 13,351, 224,361,435,121,361,147,477,420,457,108,479,452,452,456,172,457,178,449, 61,483, 395, 65,420,516,347,167,465,450,459,192,184), TPYIndex_191_list(477, 13,265,320,208, 11,298,500,161,522,482, 81,443,482,117,457, 18,482,468, 61, 24,165,469,328,399,457,421,481,268,205,395,457,223,155,213,270,507,462,474, 85, 149,451,467,461,408,210,350,166, 48,477,465,138,235, 48,389,513,485,322, 73,166, 461,252,481, 0,484,328,485,483,483,194,503,235,177,346,431, 26,341,457,258,477, 155, 47,456,229,232, 61,477,229,280, 98,456, 61, 73, 43,258,229,139,139,339,206, 432,245,457,191,142,291, 96,143,500,484,179,172,235,483,151,352,421,431,295, 58, 258,463,456,417,520,175,481, 73,280,487,434, 57,349, 33, 20,167,520,431, 15,468, 451,125,451, 18,468,164,262,481,339,422,478,463,254,340,194, 3,346,472,368,520, 408,479,353,159,487,413,339,474,411,165,172,136,184, 55,291,462,189,506,481, 32, 470,393, 25,457,462,167,481,473,229,378,423), TPYIndex_191_list(478,467,420,487,266,133, 61,330,271,143, 48, 30, 30, 30, 65,265,501,439, 6,403, 139,353,493,182,231,313,411,347,478,247,389,442,251,459,391,348, 81,507,247,185, 339,339,483,333,233,411,482, 49,507,439, 47,339,351,322, 15,349,177, 48,231,333, 214,166,506, 0,478,478,457,457, 70,421, 97,444,413,186, 33,461,108,111,223,223, 459,265,233,456, 30,186, 63,459,421,394,328,477,459,299, 70,421,180,411,177,451, 468,347,347,184,378,198,479,477,235,379,187,163, 3,475,216,458, 48,483,478, 69, 259,291,259, 94,339,268,459,258, 50,507,306, 51,473, 25,507,213,213,482,117,237, 264, 47,166, 42,221,163,468,358, 42,172,184,164,391,231,278,268,422,186,514,514, 485,125,175, 89, 85, 28,173,507,214,500,342,125,175,483,482,457,500,457,457,351, 161,161, 98,477,431,254, 83,389,477,477,472), TPYIndex_191_list(350,229,108,366,490,501,485,483,456,147,393,498,477,339,456, 78,361,457,347,173, 483, 6,503,507,507, 78,472,450, 20,184,452,161,485,347,393,506,487,449,369,335, 335, 7,298,494,487, 24,507,278,337,474,505,498,473,340,291,475, 48,328,173,257, 351, 51,471, 0,500,319,276,341,445, 8,507,184,216,340,341,154,296,133,525,477, 462,379,166, 8,507,216, 97, 97,299,505,151,177, 89,366,234,498,242,391,186,234, 184,471,459,483,472, 25,128,431, 47,417,341,257,299,184,322,175,472,415,462,498, 112,209,350,168,441,335,494,412,483,517,449,507,525,512,499,242,412,472, 12,451, 449,347,391,265,258,117, 72,455,352,485,520,432,441, 16,455,526,458,339, 47,378, 245,348,123, 81,167,339,399,449,236,471,506,232,137,477,467,472,506, 28, 24,431, 521,198,398,178,266,128,259,378,322,306,175), TPYIndex_191_list(506,482,341,472,278,468,328,451,374,295,395,520,505,470,481, 20,473,164,472,523, 467,340,172,431,219,219, 46,182,441,167,127, 89,461,462,341,498, 15,474,451, 77, 456,520,127,135,347,364,353,521,416,416,364,322,194,474, 72,507,306,462,350,459, 179,264,477, 0, 94,388,418,498,334,229,423,209,507,447,458,452,342,432,505, 98, 306,352,498,456,503,192,364,387,416,417,233, 49, 55,143,322,507,339,412,231, 47, 48,139,242,241,520,457,161,511,342,422,162,507,342,141,479,345,507,295,251, 42, 313, 51,413,513,177,388,341,330,176,474,135,341,172,331,223, 96,459,371,141,496, 477,470, 47,461,159,140,418,292,235,506,451,193,172, 32,463,421,107, 45,186,461, 16,268,517,451,337,347, 96,162,177,418,474,511,231,481,279,242,517,499,337, 58, 457, 71,379,348,178,211,388,462,498, 6,184), TPYIndex_191_list(475, 98,259,261,172,420, 72,221,184,475,366,475,475,291,455,178, 23,297,125,507, 507,422,268,175,462,234,421, 8,412,242,485,359,507,473,225,372,399, 64,292,459, 320,229,220,164,479,246,240,341,341,341,221,459,479,257,388,479, 64,462,503,246, 257,268, 48, 0,523,243,421,387, 83,447,422,177,221,246,141,141,339,470,193,477, 147, 11,334, 83,208,265,456,151, 33,398,143,467,177, 46,505, 97,483, 8,467, 97, 295, 83,353,477,194,472,339,440,461, 97,473,458,265,510, 3, 81,505,399,233,351, 465,477,177,388,177,517,477,231, 18,420,461,461,469,339,339,186,499,446, 11,483, 221,451,394,173,173,483,177,440, 90,507,342,351,500,517,517,517,347,235,517, 51, 92,510,178,148,320,482,272,339,328,237,117,109,180,502,477,390,175,105,507,108, 330,108,500,211,415,483,172,172,168,462,433) ); BEGIN IF (p_Index>0) AND (p_Index<192) THEN RETURN v_list02(p_Index1)(p_Index); ELSE RETURN 0; END IF; end get_py_index_02; FUNCTION get_py_index_03(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER IS v_list03 TPYIndex_list := TPYIndex_list( TPYIndex_191_list(479, 81,467, 42,473,395,265,265,516, 57,456, 15, 11,178,394,161,109,181,468,111, 347,161,472,494,109,393,184,473,109,468,334,505,236,149,268, 20,467,167,520,458, 110,477,452, 89, 3, 24, 5,240,213,433,395,165,468,214,467,177,179,507,439,159, 121,460,147, 0,187,459,215,509,457,394,503,503,147,149,449,432,517,524,509,388, 291,457,339,506,477,472,449,235, 43,450,461,110,468,477,487,166,467,265,475,479, 399,451,348,254,278,221,473, 57,474,417,337,177,189,149,453, 43,339,149,472,229, 172,258,491,462,149,268, 61,291,501,166,147,468, 54,233,421,180,331,235,457,477, 178,165, 69,475,475,229,421,439,461,110,393,502,149,477,460,464,388,177, 13,180, 472, 3,475,366,259,229, 46,213, 85,446,474,168,247,364,240,246,243,387,422,472, 510,485,477,161,399, 32,394,497,341,467,216), TPYIndex_191_list(478,346,111,328,111,236,209,446,307,433,222,524,266,450,444,339,479,520,450,439, 222,223,240,332,399,429,361, 7, 97,433,229,350,182, 18,505, 59,366,341,483,456, 470,108,518,361,503, 97,252, 48,477,125,133,507,176,388,449,182,252,507,484,110, 89,459, 57, 0,399,162,463,298, 50,411,485,179,172,254,328, 5,111,477,117,278, 161,475,510,463,474, 98,502,487,524,394, 97,242,411,278,505,420,457,138,117,268, 477,475,475,395,295, 18,477,291,219,151,317,108,508, 69, 59,479,117,399,390,411, 393,357,481,507,522, 70,136,337, 6,117,117,526, 22,498,408,510,320,395,138, 40, 474,182,237,257,229,364,493,373,481,470,339,505,477,460,505,229,379,191, 24,361, 8,361, 24,518, 50,477, 59,525,524,106,106,483,107,133,500,229,478,507,395,117, 366,477,209,349,377,469, 97, 56,483,491,446), TPYIndex_191_list(479,178,237,500,470,372,505, 15,479,216,180,334, 16,369,457,222,237,112,339,452, 187,147,478,350,482,240,322,514, 81,469,441,493,482, 18, 81,147,507,361, 15,459, 164,449,306,173,433,172,461,247,212, 34,111,411,408, 90,347,479,184,215,517, 42, 451,180,229, 0, 24,458,115,423,507,220,231,517,229,339, 24,245,411,341,339, 28, 42,503,110,320,335,167, 47,493,234,483,483,136,142, 89,123,450, 67,108, 47,500, 339,484,472,483,352,477,393,457,517,413,220,521,521,111, 46,348,295,449,242,149, 346,509,184,184, 47,526,342,471,328,517,518, 23,322, 87, 51, 43,258,162,175,141, 457, 72,141, 83,507,352,274,117,128,322,388,477,393, 97,117,451,451,173,520,175, 477,457,472,472,500,483,151,455,329, 18,474,210,467,371,473,219,472, 16,166,214, 178,214,408,112,445,507,271,254,209,161,435), TPYIndex_191_list(483,482,411,484,473,505,329,475,340,475,405,483,451,257,431,172,178,365,165,224, 352,460,395,421,487,393, 51,328,173,477,505,117,306,261,136,179,418,474,462,484, 518,266,413,173,474,178,165,147,341,249,484,364,395,507,452,435,364,422,499,408, 394,194,457, 0,136,339,193,416,317,423,125, 57,505,300,172,178,342,459,257,467, 123,517,445,345,473, 83,173,507, 72,240,377,457,172,231,166,481,341,143,121,121, 442,162,393,524,322,482,176,161,164,141,477,477,124,192,141,141,449,507,514,487, 222, 46,520,229,466,348,403,439,139,494,413,225,242,232,261,247,177,413,194, 21, 242,233,503,498,399,251,294,473,433,322,510,386,352,175, 61,172,472,469,507,470, 507,524, 61,337,399,162,214,505,388,457, 57, 83,110,268,456,359,235,237,345,459, 370,108,500,223,487,405,443, 47,422,259,461), TPYIndex_191_list(186,463,166,172,306,445,297,369,439,497,111,349,472,155,347,136,237,223,124,457, 394,518,376,172, 90,180,175, 51, 68,399,176,235,280,478,166,388,524,468, 47,122, 184,524,477,337,112,166, 71,172,415,333, 47, 51,511,166,172,178,173,499,175,342, 72,477, 21, 0,411,391,229,478,423,420,262,339,442, 24,168,172,341,291,297,477, 124,191,478,368,348,472,339,261,502,141, 57,172,214,334, 79, 51,125,262,482,507, 165,341,225,234,372,242,229, 64,247,264,166,313,247,507,124, 91,484,485,110,517, 412,231,176, 51,348,510,247,472,229,510,347,178, 98,413,163,295,483,240,220,177, 459,141,184,466,236,479,388,478,482,479,460,299, 25,500,231,184,403,391,524, 61, 352,351, 31,183,483,246,229,523,243,422,186,472,221,221,510,246,229, 7,279,483, 236,140,477,459,467, 44,457,339,194,478,186), TPYIndex_191_list(457,467,458,214,222,463,412,462,467, 53,478,341,463,341, 54,137,478,483,461,475, 473,421,354,313,161,461,164,467,321,477,461,467,446,231, 51,477, 98,483, 58,164, 26, 26,184,341,507,379, 48,379,508,417,415,229,494,483,229,214, 98,503,452,268, 474,394,467, 0,186,340,350,413,348,477,475,475, 30,258, 85,505,487,452, 50,431, 179,389,478, 84,182,214, 64, 70, 91,176,231, 23, 91,175,175,510,394,477,462,353, 345,474,470,166,353,339,351,166, 92,477,461,139,257, 3,178,328, 42,446,446,328, 234,173,374,271,445,470,106,364,459,184,350,306,446,320,184, 97, 18,376,254,415, 399,445,194,418,376,399,271,254,439,364,500,378,500,259,242, 85,186,339,473,282, 23,393,457,457,348,471, 89,473,487,506, 24, 71,404,224,291,108,350,314,494,262, 84,517, 54,449,108, 69,445,252,482,332,341), TPYIndex_191_list(483,483,441,182,507,507,341,180,180,444,187,159,352, 20,147,508,318,469,165,482, 467,467,487,472, 70,482,161,168,307,268,456, 49,318, 18,507,317,518,488,237,494, 112,257,488,445,505,505,477,107,432,408,213,479,184,477,173,508,166, 16,494,510, 482,136,161, 0,333,518,507,413, 47,408,184,469,394,469,117,172,139, 70,478,509, 475,166,490, 47,451,160,175,408,106,464,117,518,507,478,456,193,446,472,431,270, 225,477,261,352,334,461,477,413,213,346,184,333,465,507,165,266,456,351,477,180, 395,323, 42,179,234,350,451,147,252,482, 25, 90,159,477,506,221,147,229,128,231, 57,159,477,439,223,458, 49,181,415, 47,320,459,393,215,333,147,348,361,441,461, 435, 98,487,229,404,408,225,404, 91,487,155,464,423, 58,501,279,484,445, 89,455, 184,391,232,167,418,346, 73,185,161,143,472), TPYIndex_191_list(509,322,149, 43,341,109, 48,242,184,229,503,333,432,483,291,242,261,180,236,245, 351,483,393,161,161,484,220,348,341,507,478,334, 16,484,452,371,110,484,194,339, 391,379,339,328,457,484,365,164,175,302,456,435,112,455,431,451,368, 33,151,472, 159,261,254, 0,479,472,348,394,257,490,167,277,141, 48, 98,231,339,339,257,432, 62,451, 30,265,334,467,172,175,112,477,478,395,462,506,421,483, 18,265,395,441, 394,481,184,439,442,350,350,473,240,168,484,278,317,482,352,514,232, 42,472,516, 151,518,258,479,219,112,241,451,458,479,334,179,472,417,484,459,474,259,517, 47, 420,418,447,208,378,498,395,245,249,451,490,456,452,342,494,395, 3,487,478,413, 417,395, 3,317,467,453, 31,264,125,469,165,462, 81,507,479,178,125,415,177,166, 478,494,403, 57,461,483,466,161, 18, 21,507), TPYIndex_191_list(176,208,393,389,261, 6,242,467,482, 42,108,481,142,258,348,483,172,471, 44,457, 172,242,240,179,143,411,507,121,342,177, 61, 57,513,313,427,475,457,261,422,422, 421,231,447,420,122,322,518,192,322,501,514,467,216,341,472,403,461, 65,431,176, 520,479,159, 0,463,399,164,520,215,467,507,331,399,345,334,473,166,178,456,314, 172,451,461,341,471,457,416, 96,265,370,413,505,520,477,507,449,421,478,462,475, 498,376,152, 18, 42,399,337,235,451,379,379, 47,181,162,280,223, 66,159,147,487, 237,159,117,149,151,459,175,388,457,483,242,297,483,235,394, 71,164,494,462,483, 395,469,236,449,518,481,211, 30,231, 83,475,468,505,251, 70,477,415,328,184,418, 347,517,299,455,347,321,379,386,451, 51,418,411,435,379,510,231,291,457,399,261, 297,479,479,259,179,339,339,524,455,423,478), TPYIndex_191_list(478, 94, 59,168,348,221,470,194,451, 23,136,341,479, 23,216,110, 31,256,491,451, 334,491,242,229,482,473,242,408,507,479, 91,450,166,462,317,393, 21, 42,268,237, 175,379, 47,136, 23,168,459,242,347,364,229,180,461,479,415,451,448,469,510,403, 220, 94,108, 0,161,220,399,236,479,291,172,231,525,479,235,477,175, 42, 69,358, 175,221,108,403,484,517,112,391,225,221, 61,351,481,341,107,186,472,479,459,491, 243,472,229,261,388,421, 71,177, 42,479,149,510,221,221,279,449,243,470,459,472, 122,472,483,140,461,461,166,159,513,498,462, 48,490,339,508,111,298,452,337,477, 328,189,317,472,318,271,233,140,463,140,140, 20, 68,458,506,510,194,502,117, 7, 462,462,236,517,319,420,473,439,388,451,165,509,474,467,155,352,164,466,466,459, 478,471,509,474,395,451,439,469,490,189,458) ); BEGIN IF (p_Index>0) AND (p_Index<192) THEN RETURN v_list03(p_Index1)(p_Index); ELSE RETURN 0; END IF; end get_py_index_03; FUNCTION get_py_index_04(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER IS v_list04 TPYIndex_list := TPYIndex_list( TPYIndex_191_list(468,506,334,166,140, 45,166, 46,446,234,117,181,462,337,435,517,435,145,222,472, 467, 48,364,161,457,399,168,470,209,485,461,457,514,351, 81,462,339,446,247,472, 184,235,215,167,444,457, 65,456,159,184,117,455, 61,112,333,349,371,477,349,463, 477,345,483, 0,123,328,479,450,394,137,390,446,283,128,451, 46,151,214,508,458, 487,112,231,464,177, 18,479,510,451,442,388,457,468,302, 42,472,181,181,257,451, 498,179,349,365,164,108,350,415,473,234,178,493,137,487,278,395,232,135,422, 44, 487, 25,475,462,457,456,487,151,461,477,487,277,388,349,474,261,341,479,456,133, 472,342, 18, 21,520,242,175,241,322,415,477,439,186,520,161,477,507,451,237,357, 313,360,181,215, 64,497,175,457,457,477,461, 48,165, 70,475,470,472,470,461,187, 79,444,393,345,111,457,483,235,439,390,111), TPYIndex_191_list(470,221,257,422,477,181,258,180,446,479,477,469,221,420, 30,457,353,520,341,166, 510,236,483,477,462,502,166, 68,305, 24,368,461,470,179, 50,423,474,151,221, 21, 364,234,268,371,247,234, 6,470,213,485,233,229,242,186,233,472,457,462,240,475, 30,358,485, 0,221, 61,439,139,184, 45,261,422,221,510,221,236,483,502,506,319, 47,451,147,186,475,522,261, 55,194,492, 85,342,481,342,317, 44,175, 55,483,498, 262,317, 25, 55,482, 91, 47,298,224,445,361,252,109,123,472,492, 15,408,482,125, 271,499,352,352,518,252,199,341,229,335,123,507, 16,352, 57,173,112,194,184, 51, 457, 15,246,178,249,376,451,254, 96,439,345,457,229, 91,234,315,330, 25,457, 50, 451,359, 50, 7,172, 41,517,151,192,320,160,471,478,164,514,213,508,271,328,184, 477,464,477,236,328,291,474,482,469, 70, 25), TPYIndex_191_list( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), TPYIndex_191_list( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), TPYIndex_191_list( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 98, 0, 0, 0,171, 0, 0, 0,248,275,309, 0,338, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 98, 0, 0, 0,171, 0, 0, 0,248,275,309, 0,338, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), TPYIndex_191_list( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), TPYIndex_191_list( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), TPYIndex_191_list( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 98, 0, 98, 0,171, 0, 0,248,275, 0,309, 0, 0, 0, 0, 0, 0, 0, 0, 309, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 98, 0, 98, 0,171, 0, 0, 248,275, 0,309, 0, 0, 0, 0, 0, 0, 0, 0,309, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), TPYIndex_191_list( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), TPYIndex_191_list( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) ); BEGIN IF (p_Index>0) AND (p_Index<192) THEN RETURN v_list04(p_Index1)(p_Index); ELSE RETURN 0; END IF; end get_py_index_04; FUNCTION get_py_index_05(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER IS v_list05 TPYIndex_list := TPYIndex_list( TPYIndex_191_list( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), TPYIndex_191_list(209,459,468,268,502,178,470,388,418,439,223,517,457,458, 15,507,472,386,147,180, 315,110,461,328,339, 21,478,220,175,342,215,472,520,507,506,471,234, 38,520,118, 112,455,484,388,442,471,462,173,329,482,474,416,334,266,412,249,484, 69,483,395, 149,342,477, 0,505, 31,149,251,176,271, 42, 6,124, 65,111, 18, 18,165,337,235, 483,514,474,457,461,398, 96,177,125,468, 91,166,211,459,459,297, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), TPYIndex_191_list(168,366,259,234,482,180,398,242,418,459,261,358,280,246,459,339,186,474,518,242, 413,350,119,224, 7,159, 81, 54,122,483,339,483, 43,159,456,117,178,471,258, 12, 485,186,487,186,478, 70,332,342,477,122,333,117,468, 62,135,173,390, 59,357,394, 393,477,522, 0,237, 18,505,179,177,175,229,140,459,509,472,466,473,467,413,347, 478,470, 13,460,458,141, 49,467,320,223, 71,479,452, 98,435,431,456, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), TPYIndex_191_list(456, 47,187,257, 15,435,459, 51,147,468,472,468,466,117,457,236,229,179,417,112, 449, 83,332,500,379,265,483,220,265,450,483,432, 51,320, 47, 98, 43, 17,242,352, 84,320,342,517,347,107,179, 91,178,167,483,257, 57,468,431,464, 69,365,265,175, 451,368,164, 0,462, 54,175,513,473,231,352, 92,471,165,237,395,364,417,474,452, 456,505,179,479,249,423,237,229,222,432,342, 67,186,502, 23,441, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), TPYIndex_191_list(215,513, 61,477,339,180,493,350, 6,231,258,478,162,451,456, 79,466,497,470,351, 71,235,233,349,413,141,180,108,179,237,172,166,180, 3,493, 71,177,142,421,211, 164,379,415,432, 51,483,179,242,329,399,524,221,457,518,468,368,455,121,225, 91, 229,507,365, 0,229,491,468,431,141,415,219,240,242,229,221,479,457,460,451,139, 72,491,475, 25,319,507,229,397,460,344, 11,321,109, 70,113, 0,447, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), TPYIndex_191_list(161,477, 10,185, 43, 48,238, 71,259,515,333, 20,509,238, 59,479,339,459,241, 81, 313,513,235,456, 70,453,479,472,432,147, 43,348,393, 42, 42,369,413,393,242,112, 498,117,333, 87,516,259, 18,237,416,237,271,487,117,128,178,117,432,271,424,176, 447,117,278, 0,271,271,172,432,121, 18, 68,507,244,317,477,162,483,483,271,187, 477,237, 85,162, 71,515,176, 47, 43,444,225, 40,237, 85,235,176, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), TPYIndex_191_list(328, 85, 85,346, 70,399,507,277, 18,123,509,458,467, 46,469,339,471, 65, 18,520, 469,507,107,507,110,184,388,295,427,439,178,483,166,421, 48,257,180,461,441,252, 461,414,337, 97,398,477,322,501,139,249,235,172,432,475, 48,328,265, 94,194,471, 63,393,508, 0,507,483,112,473, 46,441,143,452,164,209,478,186,457,139,477, 55, 225,308, 83,501,393, 63,477,520,412,379, 84,241,247,347,117,406,345, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), TPYIndex_191_list(237,223,459,110,421,478,151,459,139,451,299,483,451,481,225,229,399, 70,235,235, 22,172, 48,473,178,506,256,229,168,220,172,468,479,478,481,421, 83,246,243,243, 25,446, 7,107,107,346,172,493,254,314, 59,236,268,172,322,124, 98,147, 18, 50, 341, 3,461, 0,149,165,149,494, 65,149,461,475,149,177, 3,464,165,246,330,151, 177,122,319,350,353,498,136,187,187,509,498,446,502, 91,339,479, 15, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,314, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13), TPYIndex_191_list(502,151,151, 25,449,483,108,117,350, 72,242,500,229,179,467,191,468, 4,247,467, 509, 71, 4,136,229,122,450,339,484,459,463,457,112,265,266,395,487,317,109,257, 459,395,479,506,474,393,168, 68,505,213,467,393,257,268,510,505,395, 85,291,518, 44,109,317, 0,240,439,507, 81,281,266,470,505,473,268,508,268,257,461,147,164, 47,512,185, 98,251,459,457,215,388,432,245,449,228,395,349,234,506, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,328, 18, 18, 18, 18, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24), TPYIndex_191_list(229,220,524,185,328,167,242,494,509,483,167,249,458,464,166,142,490, 57,175,257, 160,468,432,467,107,455,141,261,453,208, 71,432,349,268,111,494,501,477, 90,208, 268,405, 61,247, 48,258,141,164,405,457,337,393,233, 45,459,475,469,456,451,175, 475, 3,166, 0,175,502,257, 50,378,297,470,474,485,259,262,332,262,225,213,468, 262,168,242,259,240,352,251,457,422,191,510,347,483,406,517,186,393, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 35, 35, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 43, 43) ); BEGIN IF (p_Index>0) AND (p_Index<192) THEN RETURN v_list05(p_Index1)(p_Index); ELSE RETURN 0; END IF; end get_py_index_05; FUNCTION get_py_index_06(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER IS v_list06 TPYIndex_list := TPYIndex_list( TPYIndex_191_list(160,479,509,177,497,485, 7, 87,339,518,456,503,340,342, 70,186,229,117,452, 98, 192,507,178,332, 98,503,415,447,179,268,522,483,246,445, 98,271,510,301,333,236, 337,224, 98,334,481,213,199,352,510,213, 98,340,242,451, 3,478,472,333,223,159, 348,451,345, 0, 36,348,353, 42,222,159,483,461,458,252,246,481, 45, 45,472,386, 215,136, 36,162,242, 46,303,411,517,199,472,515,206, 47,339,520,348, 43, 43, 43, 501, 43, 43, 43, 43, 43, 43, 43, 44, 44, 44, 44, 44, 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 48, 48, 48,395, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 49, 49, 49, 49, 49, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51), TPYIndex_191_list(235,187,317,265,500,151,457,228,478,456,339,245,280,368,472, 87,445,479,194,451, 406,505, 92,458, 71,431,280,432,339, 96,112,353,353,249,133,462, 98,237,431,422, 194,328,451,432,471,339,231,451,487,515,219,316,474,513, 42,339,345,322,237,242, 191, 55, 46, 0,478,225,330,339,510, 65,520, 58,245,172,388,223,497,175,457, 87, 83,317,488,345, 81,229,175,457,501,345,459,483,515,345,194,494,225, 51, 51, 51, 51, 51, 51, 53, 54, 54, 54, 54, 54, 54, 54, 55, 55,514, 55, 55, 55, 56, 56, 56, 56, 56, 57, 57, 57, 57, 57, 57, 57, 58, 44, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 61, 61, 61, 61, 61, 62, 63, 63, 63, 63, 64, 64, 64, 65, 65, 65, 65, 65, 65, 65, 65, 66, 66, 66, 67, 67, 67, 67, 67, 67, 68, 68, 68, 68, 68, 68, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69), TPYIndex_191_list(178, 51,475,353, 71,477,328,328,483,332,339,477,194,175,483,368,319, 59, 25,473, 249,463,213,225,225,507,229,246,108,353,319,479,229,240,240,268,403,139,221, 27, 472,362,485,418,249,462,474,507,109, 94,508,446,477,395,482,507,433,117,261,414, 257, 41,247, 0,483,456,510,141,458,507,124,124,404,179,393,121,215, 81,423,136, 139,524,236,242, 72,507, 18, 51,166,482,478,518,168,505,484,456,459, 69, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 71, 71, 71, 71, 71, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 73, 73, 73, 79, 79, 79, 79, 79, 79, 79, 81, 81, 81, 81, 81, 81, 81, 81,499, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 84, 84, 84, 84, 84, 84, 84, 84,433, 85, 85, 85, 85, 85, 85, 85), TPYIndex_191_list(473,507,477,257,408, 81, 15,505,481,172,124,422,408,249,418,117,468,339,483,339, 408,421, 70,141,415,229,299,459, 72,229,485,507,491,225,365,462,441,361,518,276, 507,459,292,350,111,254,487,507,180,507,483,209, 11,328,291,229,482,328, 25,236, 292,526,507, 0,184,168,439,507,216,151,478,518,507,361, 91,510,299,337,124,494, 445,215,122,180,431,441,471,245,242,136,526,516, 12,339,507,215,228, 87, 87, 87, 87, 87, 87, 87, 87, 87, 88, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 90, 90, 90, 90, 90, 90, 90, 90, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 92, 92, 92, 92, 92, 92, 94, 94, 94, 94, 96, 96, 96, 96, 96,444, 96, 96, 96, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,100,106,106,106,106,106,106,106), TPYIndex_191_list(322,235,524,483,413,446,477,457, 20,172,117,328,306,178,508,520,467, 47, 72,459, 518,483,467,507,193,136,364,415,364,172,192,388,261,507,172,242,413,172,479,452, 350,217,477,165,346,172,461,337,177,517,508,524,247,415,299,379,166,358,306,483, 332,518,443, 0,452, 47,168,213,247,319,379,517,229,491,471,483,393,180,474,223, 474, 13, 24,447,510,319, 84,456,447, 55,474,461, 47,208, 70,517,467,106,107,107, 107,107,107,107,107,107,108,108,108,108,108,108,108,108,108,108,108,108,108,108, 108,108,108,109,109,109,109,109,109,109,109,109,109,109,110,110,110,110,110,110, 110,110,110,110,110,110,111,111,111,111,111,111,111,111,111,111,111,111,111,111, 111,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,115,116,117,117, 117,117,117,117,117,117,117,117,117,117,117), TPYIndex_191_list(413,139,517,455,447,475,349,474,474,433, 44,432, 84,241,233,457,456,214, 55,502, 212,212, 47, 65,233,493, 64,345,349, 91,493,240,346, 51,395,117,341, 51,159,339, 149,394,111,263,351,510,236,285, 24, 8,408,159,505, 84,477,399,180,351,333,229, 513, 35, 79, 0, 66,448,180,191,180,224,322, 48,252,510,449,177,414,347,471,515, 484,148,179,328,477, 89,388,458,510,276,136,346,265, 13,388,320,236,117,117,117, 117,117,117,117,117,117,117,117,337,117,117,117,117,117,117,117,117,117,117,117, 117,117,117,117,117,117,117,117,117,119,119,121,121,121,121,121,121,122,122,122, 122,122,122,122,122,122,122,122,123,123,123,123,123,123,123,123,123,124,124,124, 124,124,124,124,124,124,124,125,125,125,125,125,125,125,125,125,125,125,144,125, 125,125,125,125,126,127,127,128,128,128,128), TPYIndex_191_list(301,117,108,122,108,395,254,461,349,265,246,141,351, 48,478,474, 18,216,177,487, 366,172,148,508,220, 71, 33,117,441,229,222,184,139,459,147,481,458,507, 47,414, 510,526,435,173,124,122,213,487,309,461,337,220,521,315,328,125,420,138,483,175, 502,161,506, 0,498,509,242,235,354,117,498,136,341,187,515, 33,522, 25,468, 20, 416,459,333,464,161,477,485, 57,247,456, 89,461,172,178,464,257,108,128,128,128, 133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,135,135,135,135,135, 135,135,135,135,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, 136,136,137,137,137,137,137,137,138,138,138,139,139,139,139,139,139,139,139,139, 139,139,140,140,140,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, 141,142,142,142,143,143,143,143,143,143,144), TPYIndex_191_list( 92,112,510,159,346,350,263,341,136,395,487,151,422,485, 50,371,506,295,341,461, 240,322, 91,517, 51,395,510,342,240,175, 26,166, 18,510, 61,472,491,523,328,330, 483,513,499,387,143,477,161, 42,208,333,493,172,247,172,292,417, 64, 84,417,224, 232,461, 25, 0,261,408,422,233, 70,117,175,265,214, 69,177,513,223,461,242,395, 491,339,315,339,328,122,184,242,242,472, 71,374,511,135,341,231,395,145,145,145, 145,145,145,145,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, 147,147,147, 16,148,148,149,149,149,149,149,149,149,149,149,151,151,151,151,151, 151,151,151,151,151,268,151,151,151,151,151,151,151,152,152,154,154,154,154,155, 155,155,155,155,159,159,159,159,159,159,159,159,159,160,160,160,160,160,160,160, 161,161,161,161,161,161,161,161,161,161,161), TPYIndex_191_list(221,214,483,485,149,505,420,431,295,423,477,339,427,513,509,317,412,509,341,517, 427,242,242,175,445,479,483,220,240,346,231,221,341,485,508,351,231, 20, 92,523, 229,395,246,479,485,517,483,108,393,503,393,307,151,291, 66,501,341,499,328, 11, 456,386,192, 0,365, 18,415,478,503,261,420,161,122,184,268,509,229,413,159,439, 379,235,514, 8,223,106,351,151,459,117,229,485,242,184,339, 8,501,161,161,161, 161,161,161,161,162,162,162,162,162,162,162,162,162,163,163,163,163,163,164,164, 164,145,164,164,164,164,164,164,164,164,164,164,165,165,165,165,165,165,165,165, 165,165,165,165,165,165,166,166,166,166,166,166,166,166,166,166,166,166,166,166, 166,166,166,166,166,166,166,167,167,167,167,167,167,168,168,168,168,168,168,168, 168,168,168,172,172,172,172,172,172,172,172), TPYIndex_191_list(162,162,376,422, 20,262,520,175,229,462,117,306, 15,136,466,173,514,422,376,111, 176,268,376,376,306,457,232,211, 25,164,399,172,459,442,295,229,526, 81,295,433, 221,408,182,133,506,182,482,172, 40,509,470,485,176,483,178,449,361,452,350,276, 518,440,298, 0,116,178,399,516,328,505,386,159,507,172,111,487,361, 70,179,109, 522,182,498, 7,117,507,339,509,159,498,457,117,477,393, 25,510,351,172,172,172, 172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, 172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, 172,172,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,175, 175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, 175,175,175,191,175,175,175,175,175,175,175) ); BEGIN IF (p_Index>0) AND (p_Index<192) THEN RETURN v_list06(p_Index1)(p_Index); ELSE RETURN 0; END IF; end get_py_index_06; FUNCTION get_py_index_07(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER IS v_list07 TPYIndex_list := TPYIndex_list( TPYIndex_191_list(236,510,390,122,473,117,445,505, 69, 51,395,508,468,522,181, 11,351,268,399,524, 213,180,361,148,477,178,510, 50,210,268,186,213,161, 59,164,128,423,462,209,461, 352,121,246,470,322,459,117,458,439,364,433,478,225,462,185,145, 85,439,408,176, 460,166,186, 0,175,468,507,452,505,247, 47,350,399, 12,439,461,449,459,128,466, 431,466,462,159,457,117,435,415, 94,215,117,180,161,507,472,181,112,175,175,175, 175,175,175,175,175,176,176,176,176,176,176,176,176,176,176,176,176,176,177,177, 177,177,177,177,177,177,177,177,177,177,177,177,474,177,177,177,177,177,177,177, 177,177,177,177,177,177,178,178,178,178,178,178,178,178,178,184,178,178,178,178, 178,178,178,178,178,172,178,178,178,178,178,178,178,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179,179,179,179), TPYIndex_191_list(172,467,361,520,393, 97,234,247,232,423,352,390,339,516,339,449,506,459,398,477, 423,449,123,450, 17,515, 28,143,522,245,237,477,500, 18, 58,236,262,339,346,432, 520,167,521,457,518,464,232,179,110,369,265,483,520,108,247,467,479,389,339,467, 460,175,194, 0,459,368,262,339, 92,508, 81,265,263,484,475, 13,408,350, 20,164, 128,520,262,451,117,451,467,135,263,462,231,520,329,487,478,431,137,179,179,180, 180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, 180,180,180,180,181,181,182,182,182,182,182,182,182,182,182,182,182,182,182,182, 182,182,182,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, 184,184,184,184,184,184,184,184,185,185,185,185,185,185,185,186,186,186,186,186, 186,177,186,186,186,187,187,187,187,187,187), TPYIndex_191_list(507,487, 47, 42, 69,458,484,520,467,479,451,128,385,479,179,477,515,291, 12,161, 317,509,175,417,352,403,487,458,415,457,364,423,117,487,505,124,366,161,497,427, 468,413,505,520,423,165, 28, 18,112, 63,229,417,478,457,520,225,513,341,251,507, 247,271,330, 0,231,468,520,172,461,415,247, 17,477,493,271,342,167,459,172,386, 466,357,468,415,345,497,526,507,388,376,235,483,108,359, 58,525,175,187,187,187, 187,187,188,188,188,125,189,189,189,189,189,191,191,191,191,191,191,192,192,192, 192,192,192,192,193,193,193,193,194,194,194,194,194,194,194,194,194,194,194,194, 194,194,194,198,198,198,198,199,199,206,206,206,206,208,208,208,208,209,209,209, 209,209,209,209,210,210,210,210,210,211,211,211,211,212,212,213,213,213,213,213, 213,213,213,214,214,214,214,214,214,214,214), TPYIndex_191_list(359, 42,369,466,166,162,523,457,342,487, 68,479,166,457,379,175,176,164,493, 61, 462,517, 18,421,477,299,415,477,387,467,172, 23,341,221,337,470,339,322,474,268, 225,462,523,213,482,467,225,459, 42,177,242, 42,479,388,460,459,524,523,246,457, 221,225,231, 0,159,361,510,505, 85,457,479,423,487,459,415,462,116,116,339, 25, 333,460,502,123,479,139,525,421, 31,339,453,479,225,421,242,408,123,214,214,214, 215,215,215,215,216,216,216,216,219,219,219,219,219,219,219,220,220,220,221,221, 221,221,221,221,221,221,221,221,221,221,221,221,221,222,222,222,222,222,222,222, 223,223,223,223,223,223,223,223,223,224,224,225,225,225,225,225,225,225,225,225, 225,225,228,228,228,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, 229,229,229,229,229,229,229,229,229,229,229), TPYIndex_191_list(355,393,136,510,184,259,265,137,431,185,117,393,138,517,483, 4,107,408,249,237, 328,107, 44,451, 18,172, 49,237,185,261,502,246,328,172,172,243,261, 68,473,482, 482,111, 7,473,136,482,492,257,477,510,477,364,354,342,164,477,477,473,342,459, 483,222,484, 0,108,388,111,388,231,300,342,159, 49,111,159, 48, 65,117,458,321, 219,334,242,507,483,457,462,457,194,166,166,461,386,159,176,509,386,229,229,229, 229,229,229,229,229,232,231,231,231,231,231,231,231,231,231,231,231,231,231,231, 232,232,232,232,232,232,232,232,232,232,232,233,233,233,233,233,233,233,233,224, 233,233,233,233,234,234,234,234,234,235,235,235,235,235,235,235,235,235,235,235, 235,236,236,236,236,236,236,236,236,236,236,236,236,236,236,237,237,237,237,237, 237,237,237,237,237,237,240,240,240,240,240), TPYIndex_191_list( 48,468, 48,520,449,166,160,151,330,231,351, 6,235,321,345, 6,166,468, 72,446, 135,135,135, 85,368,277,513,435,328,477,351,173,184, 51,245,178,498,241,172,223, 168,482,163,477,347,487, 70,159,507,446,505, 45,506,482,517,433,307,471,503,381, 149,394,234, 0,180, 18, 81,143,452,467,333, 61, 87,446,435,184, 61,214,231,231, 453,214,231,231, 61,394,411,435,214,503,507, 70,297,346,291,435,435,240,240,240, 240,241,241,241,241,241,241,242,242,242,242,242,242,242,242,242,242,242,242,242, 242,242,242,242,242,242,242,247,247,247,247,247,247,247,247,247,247,247,247,247, 247,243,243,243,243,243,243,244,244,245,245,245,245,245,245,245,246,246,246,246, 246,246,246,246,246,246,246,246,249,249,249,249,249,249,249,249,249,250,250,250, 250,250,250,251,251,251,251,251,251,251,251), TPYIndex_191_list(240,502,408,413,502,477,350,198, 32,339, 81,164, 48,361,366,484, 40,347,111,320, 318,482,357,452,339,328,457,457,198, 85,110, 7, 25,467,432,518,209,507,291,333, 518,509,459,271,351,194, 48,473,318,507,465,106,155,518,214,506,433, 65,257,462, 462,250,462, 0,296,452,452,466,199,482,155,319,388,435,257, 57,393,351,425,524, 172,482,463,445, 47,443, 90,280,328,136,229,501,415,178,232,404, 21,251,252,252, 252,252,252,252,254,254,254,254,254,254,254,254,254,254,254,254,256,257,257,257, 257,257,257,257,257,257,257,257,257,257,257,257,257,258,258,258,259,259,259,259, 259,259,259,259,261,261,261,261,261,261,261,261,261,261,261,261,261,261,262,262, 262,262,262,262,262,262,262,263,263,263,263,263,263,263,263,264,264,265,265,265, 265,265,265,266,266,266,266,266,266,267,268), TPYIndex_191_list(245,329,225,352,160, 70,282,277,361,393,515,184, 89,328,168,455,257,368,513, 48, 246,313, 81, 4,280,402,487,508,365,441,451,186,173, 92, 18, 43,472,447,398,422, 413,515,477,233,172,328,462,247,313, 43,242,168,318, 53,176,242,513,242,177,479, 247,469, 34, 0,439,291,233, 65,214,461,444,317,507,177,456, 65,476,460,415,111, 511, 70,211,299,186, 51,185,219,231,444,339, 65, 23,470,366,485,492,268,268,268, 268,268,268,268,268,268,268,268,268,268,268,268,268,270,270,270,271,271,271,271, 271,271,271,271,271,271,271,271,271,271,271,276,276,276,276,276,276,276,277,277, 277,277,277,278,278,278,279,280,280,280,280,280,281,282,282,284,285,291,291,291, 291,291,291,291,291,291,291,291,292,292,292,292,292,292,292,293,293,294,294,295, 295,295,295,295,295,295,296,297,297,297,297), TPYIndex_191_list(459, 21,464,215,234,472,242,168,488,246,351,492,243,291,491,459,455,181,235,181, 177,172,149,466,262,295,125,175,507,507,466,420,459, 40,457,483,464,184,182,463, 391,182,432,395,421,337,337,139,339,432,458, 72,108,314,420,108,108,242,236,458, 349,318,210, 0,117,493,112,229,483,222,446, 25,341,184,165,520, 20,271, 85, 90, 12, 40,477, 31,241, 69,469,474, 79, 71,342,242,477,172,175,455,339,297,297,298, 298,298,298,299,299,299,299,301,301,301,307,302,303,303,306,306,306,306,309,313, 313,313,313,313,313,313,314,314,314,314,314,314,315,315,315,315,315,315,317,317, 317,317,317,317,317,317,318,318,318,318,318,319,319,319,319,319,319,319,320,320, 320,320,320,320,320,320,320,321,321,322,322,322,322,322,322,322,322,322,322,322, 322,322,322,328,328,328,328,328,328,328,328), TPYIndex_191_list(242,242, 42,403,175,333,472,472, 32,224,435,433,177,322,477, 40,262,122,483,458, 518,166,415,507,444,451,339,452,361,117,510,162,186,172, 6,521,254,362,148,478, 482,477,346,328,431, 81,229,481, 15,477,510,291,314, 24,466,474,459,159,526, 89, 85,295,161, 0,257,394,137,261,451,117,518,507,172, 61,446,469,246,229,364,507, 46,483,466,518,234,456,172,141, 59,135,140,294,483,518,320,271,508,328,328,328, 328,328,328,328,328,328,329,329,329,329,330,330,330,330,331,331,332,332,332,332, 332,333,333,333,333,333,333,333,333,333,334,334,334,334,334,334,334,334,335,337, 337,337,337,337,337,337,337,337,337,337,337,337,337, 13,339,339,339,339,339,339, 339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339, 339,339,339,339,339,339,339,339,339,339,340) ); BEGIN IF (p_Index>0) AND (p_Index<192) THEN RETURN v_list07(p_Index1)(p_Index); ELSE RETURN 0; END IF; end get_py_index_07; FUNCTION get_py_index_08(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER IS v_list08 TPYIndex_list := TPYIndex_list( TPYIndex_191_list(341,510,164,117,121,418, 54,180,106, 4,345, 48,333,341,223,399,514, 68, 33,483, 91,451,229, 90,117,361,478,337,487,415, 47,299,456, 22,457,128,510,268,514,526, 445,350,417, 46,322,457,464,479, 45,187,472, 67,147, 67,173,450,482,365,461,459, 452,178,278, 0,271,441,286,252, 59, 81,351, 89,521,219,242,451,361,215,337,518, 124,143,245, 50, 56,500,258,229, 13,347,185,347, 81,386,179,502,507,340,340,341, 341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341, 341,342,342,342,342,342,342,342,342,345,345,345,345,345,345,345,345,345,345,345, 345,345,345,345,346,346,346,346,346,347,347,347,347,347,347,347,347,347,347,347, 348,348,348,348,348,348,348,348,348,348,348,348,348,349,349,350,350,350,350,350, 350,350,350,351,351,351,351,351,351,351,351), TPYIndex_191_list(128,210,347,472,450, 17,509,175,235,421,432, 72,161,151, 57, 43,164,117,220,386, 472,477,433,339,449, 33,505,494,182, 18,477,259, 14,319, 87,350,194,460,449,483, 483,117,231,468,278, 33,455, 57,461,329,271, 4,479,216,216,176,262,526,526,522, 365,457,475, 0,472,351,175,117,247,175,321,159,159,160,472,441,518,348,261,165, 393,121,509,341,451, 25,451,172, 92,474,417,352,505,470,395,221,520,351,351,351, 351,351,352,352,352,352,352,352,352,352,352,352,352,353,353,353,353,353,353,353, 353,354,354,357,357,357,357,358,358,358,358,358,359,359,359,360,360,361,361,361, 361,361,361,361,361,361,361,362,362,363,364,364,364,364,364,364,364,364,364,364, 365,365,365,366,366,366,366,366,366,366,366,366,366,368,368,369,369,369,370,370, 371,371,372,372,372,374,374,374,374,376,376), TPYIndex_191_list(474,484,257,487,399,513,139,357,469,446,451,482,412,478,395, 57,395,487,505,366, 229,353,484,229,184,457, 51,467,441,237,455, 83,341,522,334, 67,484, 51,483,317, 337,276,457,111,487,371, 31,261,416,266,412,237,457,136,222,125, 67,422,246,468, 517,141,520, 0,142,526,433, 33,320,446,393,222,236,433,466,254,439,510, 4,231, 520,333,467,179,442,178,451,443, 32,483,477,518, 18,242, 26,501,225,376,376,377, 377,377,378,378,378,378,379,379,379,382,383,386,386,386, 40,386,386,386,386,386, 387,387,388,388,388,388,388,388,388,388,388,388,388,388,388,388,388,388,389,389, 389,389,389,389,389,389,390,390,390,390,390,390,390,390,390,390,390,391,391,391, 391,391,391,391,391,391,391,391,391,393,393,393,393,393,393,393,393,393,393,393, 393,393,393,393,393,394,394,394,394,394,394), TPYIndex_191_list(342,251,472,236,457,330,142,147, 81,242,391,389, 81,470, 25, 81,498,393,468,161, 6,261,247,508,334,176,261, 61,294,166,187,478,388,478,143, 46,161,386,208,341, 249,492,494,229,451,172,470,394,259,313, 42, 83,369,225,483,345,510,210,175,250, 487, 13,482, 0,242,474, 98,431,110,186,110,366,111,214,405,471,467,117,422,456, 89,408,461,457,372,487,390,175,416,236,483,458,408,299,468,487,483,394,394,394, 394,394,395,395,395,395,395,395,395,395,395,395,395,395,393,395,395,395,395,395, 395,395,395,395,395,395,395,395,395,395,395,395,395,395,395,395,395,395,395,395, 395,395,395,395,395,395,395,395,395,398,398,398,398,398,398,398,398,398,398,399, 399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,399, 399,399,399,399,399,399,399,399,399,399,399), TPYIndex_191_list(461,149, 3,166,166,172,518,460,449,264,228,176, 30,393,379,231,194,484, 68,507, 422,500,416,472,108, 87,462,136,510,175,193,372,470,474, 8, 94,332,484,297,509, 455,330,339,493, 46,505,106,291,479, 61,461,339,107,175,483,214, 20,517,261,221, 179,349,346, 0,446,459,413,247,477,467,462,477,219,225,177, 81,507, 15,474,268, 164,319,412,421,443,349,345,451,237,166,313,193,487, 13,229,510,510,399,400,400, 401,401,401,401,402,402,403,403,403,404,404,404,404,405,405,405,405,406,406,406, 406,408,408,408,408,408,408,408,408,408,408,408,408,408,395,408,408,411,411,411, 411,411,411,411,411,412,412,412,412,413,413,413,413,413,413,413,413,413,466,413, 413,414,414,414,415,415,415,415,415,415,415,415,415,415,415,416,416,416,417,417, 417,417,417,417,417,417,418,418,418,418,418), TPYIndex_191_list( 3,235,468,347,220,494,456,369,369,347,242,413,443,252,487,333,483,470,172,181, 468,350,413,181,112, 25,460,477,459,483,184,459,459,478,342,479,240,440,162,485, 236,474,257,221,214,221,172,422,251,225,225,166,411,507,451,214,163,229,172,225, 163,246,172, 0,214,242,175,375,427,225,352,461,477,243,258, 22,507,461,184,161, 467, 67,117,467,242,161,149,177,184, 13,472,500,500,214, 23,457,399,418,418,418, 418,420,420,420,420,420,420,420,420,420,421,421,421,421,421,421,421,421,421,421, 421,421,421,421,421,421,421,421,422,422,422,422,422,422,422,422,422,422,422,422, 422,423,423,423,423,423,423,423,423,423,423,423,425,427,427,427,427,431,431,431, 431,431,431,431,431,431,431,431,431,431,431,431,432,432,432,432,432,432,432,432, 433,433,433,433,433,434,434,434,435,435,435), TPYIndex_191_list( 84,350, 87,446,186,503,475,483,147,518,460,109, 98, 7, 48,341,452,485,485,187, 339,439,507,484,353,482,347,339,508,271,450,111,111,148,117,357,319,291,425,333, 81,184,229,117,498,467,328,328,459, 84, 22, 24,500,434,136,479,246, 59,166,252, 117,234,477, 0,459,229,477,333,346,391,477,450,268,346,141,349,223,464,178,350, 173,485, 45, 15,147,468,505,337,459,232, 18,484,482,178, 70, 83,166,435,435,435, 435,435,435,435,439,439,439,439,439,439,439,439,439,439,439,439,439,440,440,440, 440,441,441,441,441,441,441,441,441,441,441,441,442,442,443,443,443,443,443,443, 444,444,444,445,445,445,445,445,445,445,445,445,445,445,447,447,447,447,447,447, 447,448,448,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449, 450,450,450,450,450,450,450,450,450,450,451), TPYIndex_191_list(411,184,339,483,187,457,245,229, 85,423,215,147,147, 12,110,451,444,487,417,341, 451,291,451,232, 89, 98, 11,517,450, 30,261,446,219,178,435,254,467,262,178,395, 468,472,365,451,117,484,257,451,368,462,458,479,395,508,422,510,520,431,484,259, 219, 91,350, 0,457,455,487,483,479,176, 11,408, 59,457,453,231,317,364,172,456, 466,147,477,328,162,477, 91,285,458,161,166,249,477,452,479,427,508,451,451,451, 451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451, 451,451,451,451,451,451,451,451,451,452,452,452,452,452,452,452,452,452,452,453, 453,453,455,455,455,455,455,455,455,455,455,456,456,456,456,456,456,456,456,456, 456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456, 457,457,457,457,457,457,457,457,457,457,457), TPYIndex_191_list( 31,409,339,433,389, 81,242,451,507, 46,351,328,483,175,241,347,478,176,452,461, 251,503,503,249,483,237, 61,229,251,461, 43,268,524,408,350,425,507,322,345,351, 22,233,141,457,339,513,110,233,186,186,478,431,177,359,461,456,508,470,408, 51, 47, 71,229, 0,445,477,180, 68,339,172,460,391,347,479, 41,229,495,468,510,494, 462,252,462,339,364,175,149,517,178, 23,151,108,225,178,219,265,229,457,457,457, 457,457,457,457,457,457,457,457,457,457,457,457,457,457,457,459,457,457,457,457, 457,458,458,458,458,458,458,458,458,458,458,386,458,458,459,459,459,459,459,459, 459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,459, 460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, 461,461,461,469,461,461,461,461,461,461,461), TPYIndex_191_list(350,295,242, 91,461,510,240,229,240,318,475,328,389,475,479,399,457, 30,351,352, 30,251,178,510,517,165,307,320,508,250,106,194,264,457,191,484,351,236,468,399, 439,460,483,161,451, 72, 49,451, 72,516,122,483,477,117,321,178,508, 70,477,508, 178,507,462, 0,357,507,187, 41,477,357,445,236,319,474,526, 18,390,184,210,469, 505,477,314,117, 81,117,142,507,507,357,477,445,276,135,468,503,351,461,461,461, 461,461,461,461,462,462,462,462,462,462,173,462,462,462,462,462,462,462,462,462, 462,462,462,462,462,463,463,463,463,463,463,463,463,463,463,464,464,464,464,464, 464,464,464,464,148,464,464,464,464,464,465,465,465,465,465,465,465,466,466,466, 466,466,466,466,466,466,467,467,467,467,467,467,467,467,467,467,467,467,467, 51, 467,467,467,467,467,468,468,468,468,468,468) ); BEGIN IF (p_Index>0) AND (p_Index<192) THEN RETURN v_list08(p_Index1)(p_Index); ELSE RETURN 0; END IF; end get_py_index_08; FUNCTION get_py_index_09(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER IS v_list09 TPYIndex_list := TPYIndex_list( TPYIndex_191_list(483,291, 25,446,306,339,209,361,176,525,268,178,106,366,510,141,478,188,464,380, 215,294,399,462,215,229,185,393,178,505,237,172,477, 26,514,404,354,229,466,421, 215,423,484,236, 48, 43, 72,232,320,110,484,472, 91,507,477,339,143,198,339,431, 431,117,508, 0,462, 85,215,442,482,482,484,117,483,442,472,477,319, 70,487,418, 135,163,364,484,277,181,417,317,377,294,479,178,163,209,231,229,395,468,468,468, 468,469,469,469,469,469,469,470,470,470,470,470,470,470,470,470,470,470,470,470, 470,471,471,471,471,471,471,471,471,471,471,471,471,471,471,471,471,472,472,472, 472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472, 472,472,472,472,472,472,472,472,472,472,473,473,473,473,473,473,473,473,473,473, 473,473,473,473,473,473,473,474,474,474,474), TPYIndex_191_list(247,477, 85,462,459,451, 21, 32,172,388,335, 18,337,175,513,175, 67,172, 70,488, 108,110,460,470, 22,359,251,221, 6,494,166, 32,415,299, 70,231, 71,399,500, 18, 221,337,507,419,399,447,395, 15,462, 25, 46,220,240,457,459,221,503, 69,184,491, 395,175,477, 0,221,471,457,112,117,114, 7,151,172,172,459,139, 20,472,467,186, 329,254,261,261,331,395,408,172,505,186,261,433,231,474,507,187,457,474,474,474, 474,474,474,474,474,474,474,474,475,475,475,475,475,475,475,475,475,475,475,475, 475,475,475,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477, 477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477, 477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,478,478,478,478, 478,478,478,478,478,478,478,478,478,478,478), TPYIndex_191_list(388,451,457,432,483,221, 98, 91,347,318,172,266,479,135,351,500,179,139, 79,175, 246,351,175,451,186,351,246,221,393,172,139,472,432,350,179, 63,507, 44,172, 70, 507,462,352,125,395,141,462,167,350,464,291,339,242,498, 18,464,389,133,507,469, 51,457,477, 0,242,186,457,472,457,472, 87,117,350,350,177,172,108,470, 84,159, 41,423,467,178,477,361,470,478,388,339,445,172,470,478, 98,111,471,478,479,479, 479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,480,481,481,481, 481,481,481,481,481,481,481,481,481,481,481,481,482,482,482,482,482,482,482,482, 482,482,482,482,482,482,482,482,482,482,482,482,483,483,483,483,483,483,483,483, 483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, 483,467,483,483,483,483,483,483,483,483,483), TPYIndex_191_list(474,411,393,478,478,186,461,281, 46,482,507,465,109,463,263,391,472,372,516,467, 477,477,413, 48,151,393,151,467,505,510,506,135,518,500,136,117,175, 85,236,431, 473,301,317,509,122,477,184,474,498,477,477,351,502,333, 18,465,351, 25, 68,522, 423,510, 59, 0,503,481,467,470,477,165,151,395,346,461,395,154, 91,160,141,352, 166,178,162,121,473,451,393,509,439,261,266,246,166,472,465,137,106,483,483,483, 483,483,483,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, 484,484,484,485,485,485,485,474,485,485,485,485,485,487,487,487,487,487,487,487, 487,487,487,487,487,488,488,488,490,490,490,490,490,490,490,491,491,491,491,492, 492,492,493,493,493,493,493,493,493,493,493,493,493,493,493,493,494,494,494,494, 495,496,497,497, 35,497,498,498,498,498,498), TPYIndex_191_list( 24,433,477,225,510,213,351,456,172,507,361, 63,222, 98,213,477,435, 70, 15, 42, 482,199,345,347,400, 4,483,461, 47,178,459,456,456,124,411, 26,166,180,485,505, 485, 91,162, 43,404,178,194,351, 61,461,415,450,459,110,220,418,477,291,478,509, 328,517, 42, 0, 46,516,172,339,421,515,451,184,348, 89,506,526,521,341,517,232, 175,172,458,245,393, 21,162,329,483,462,467,329,395,468,395,167,162,498,498,498, 388,498,488,498,498,498,499,499,499,499,499,499,500,500,500,500,500,500,500,500, 500,500,500,500,500,500,500,500,500,501,501,501,501,501,501,501,501,501,501,501, 501,501,501,501,502,502,502,502,502,502,502,502,502,502,503,503,503,503,503,503, 503,503,503,503,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505, 506,506,506,506,506,506,506,506,506,506,506), TPYIndex_191_list( 98,508,431,462,117,337,435,221,339,483,518,513,457,166,478,440,459,278, 46,112, 510,473,472,165,468,125,306,467,270,475,451,464,427,509,388,334,443,165,168,125, 479,261,461,261,458,342,505,469,431,413, 12, 48,500,477,176,484,462,461,423,474, 474,507,483, 0,330, 61,229,268,268,389,503,267,175,494,522,231,247,493,467,142, 457,517, 6, 6,179,503,477,461,176,251,502,459,447, 70,467,497,379,505,506,506, 506,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507, 507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507, 507,507,507,507,508,508,508,508,508,508,508,508,508,508,508,509,509,509,509,509, 509,509,509,509,509,509,509,509,509,510,510,510,510,510,510,510,510,510,510,510, 510,510,510,510,510,510,510,510,510,510,510), TPYIndex_191_list(457,498, 94,506,461,221, 98,479,186,172,525,345, 25,166,513,456,496,498,507,345, 421,496,337,394,468,493,421, 71,415,459,172,177,500,300,477, 3,500,166,462,477, 477,388,358,300,341, 94,418,161,509,149,477,479,191,483,175,166, 91,503,468,491, 225,393,451, 0, 42,229,477, 20,503,472, 98, 50,451, 50,474, 42,358,478,221, 46, 462,295,164,491,477, 71,500,472, 91,445,361,465,465, 18,509,393,467,510,510,510, 510,511,502,512,513,513,513,513,523,513,514,514,514,514,514,514,514,515,515,515, 515,515,515,516,516,517,517,517,517,517,517,517,517,503,517,517,518,518,518,518, 518,518,518,518,490,518,518,518,518,518,518,520,520,520,520,520,520,520,521,521, 521,521,522,522,522,522,522,522,522,522,523,523,524,524,524,524,525,525,526,526, 526,498,526,526,526,526, 0, 0, 0, 0, 0), TPYIndex_191_list(341,159,458,172,159,147,240,457,457,233,147, 91,240,339,229, 79, 20,399,459,112, 507,507,472,472, 51,166,444,477,477,472, 7,160, 98, 51,472,215,121,184,337,457, 164,510,173,111,457,168,452,164, 81,520,111,477, 4,328,276,328,135,276,482,268, 408,164,254, 0,268, 4,483,291, 18,483,173,442,254,457,477,483, 51,421,164,186, 15,505,487,117, 28,133,425,477,148,449,332,168,108,421,449,499,507, 51,172,456, 121,292,372,328,127, 47,125,280, 98,399,483,331, 18,445,474,474,507, 81,463,478, 214,483,124,423, 83,172,277,295,172,339,261, 15,379,136,494,391, 67,472,186,408, 475,472,351,334,141,214, 20,494,137,482, 33,477,452,180,209,141,189,219,172,472, 449,211,330,186,345,168,477,439,450, 70, 87,501,224,372,477,271,361,483,328,471, 447,456, 43, 31,192,510,297,188,482,477,135), TPYIndex_191_list(106,510,395, 18,518,106,141,329,107,250,425,394,213,117,434,477, 48,254,151,111, 242,235,166,121,329,518,173,467,495,177,121,492,175,479,470,505,391, 23, 23,350, 391, 54,492,509,220,491, 59, 46,389,432,320,128,459,250,175,415,117,421, 61, 61, 507,172,501, 0, 91,179,465, 57,487, 13,490,220,112, 31,172,394,477,523,117,135, 374,494,233,477, 8, 46,449,507,515, 21,487,497, 70,491,472,337,388,439,445,291, 119,172,106,482,210,191,510,477,433, 41,177,299,270, 50,472,229,350,229,483,333, 481,408,112,341,371,315,517,399,246,455, 18,431,139,206,184,111,472,462,172,451, 520,247,422, 23,306, 48,457,180,175,177,182,439,468, 70,439,444,391,341,522,485, 64, 81,457,470,159,143, 42,214, 13,337,159,117,117,413,408,452,472, 25,142,254, 462,243,335, 24,479,246,225,232,161,234,459), TPYIndex_191_list(449,479,179,514,459,492, 18, 91,399,472,446,468,240,514,492,487, 18,509,112,487, 457,465,457, 47, 47,458,422,521,229,388,349,478,459,518,186,347, 81, 59,505,441, 81,457,500,186,178,351, 51,168,469,433, 97,122,417, 63,457,502,413,478,351,175, 353,517,451, 0,242, 71,350,518,431,351, 48,165,345,345,177,493,485,106,522,456, 194,186, 46,318,485,314,339,445,477,292,236,257,209,518,340,510,351,411,333,508, 266,472,178,159,388,313,184,281,136,151, 81,502,351,477,213,225,137,178,166,393, 135,352,506,167,467,345,124,213, 99,521,517,451,483,393, 42,415, 46,175,469,475, 98,483,468, 4, 81,518,329,268, 71,413,395,261,503,175,496,345,186,472,500, 46, 70,179,526,456,341,180, 11, 83,526, 15,464,121,507,295,521, 56,328,451,165,451, 457,147,349,213,252,456,109, 24,328, 15,475) ); BEGIN IF (p_Index>0) AND (p_Index<192) THEN RETURN v_list09(p_Index1)(p_Index); ELSE RETURN 0; END IF; end get_py_index_09; FUNCTION get_py_index_10(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER IS v_list10 TPYIndex_list := TPYIndex_list( TPYIndex_191_list(500,317,510,291,477,172, 97, 97,510,525,512,460, 85,329,507,178, 28, 68,351,399, 441, 63,199,295,461, 26,525,271,399,177,345,260,175,339,455,451,178,353,295,184, 295,245,242,228,455,352,522,346,477, 81,520,322,506,483, 96, 57,481,507,498, 46, 445,422,117, 0,522,360,498,443,342,500, 83,431,172,237,491, 18, 49,242,233,422, 507,413,457,214,172,517,342,507,317,520,231,493,357,443,184,459,508, 81,420,173, 507,510,211,346,470,487,229,479,124,457,117,328,421,472,185,472,478,501,334,388, 521,236,112, 51,164,250,351,390,151,125,259,467,462,412,462,186,175,388, 71, 43, 408, 20, 16,350, 16, 98,107,399,172,481,151,467,456,125,505,213,328,477,229,339, 11,122,240, 83,242, 45, 81,445,291,271, 6,471, 85, 89,189,388,389,280,121,478, 47,395,143,470,234,484,507, 4,477,328,292), TPYIndex_191_list( 25, 63,186,235,418,345,345,233, 96,139, 68, 18, 18,184,345, 96, 50,172,456,485, 292,507,485,507, 51, 92,451,240,235,459,451,221,358,462,295,418,351,353, 64,523, 457,214,339,235, 70,111,431, 97,133,222,361,246, 3,172,184,206,446,472,257,192, 351,247,223, 0,445,507,472,431, 72,479,483, 45,498,141,187,485,463, 69,468,108, 361,388,213,399,444,339,420, 98,276,339,254,368,213,341,513,159,161,322,441,378, 69,209, 85,478,228,160,125,484,251,481,232, 48,463,328,477, 32,177,277, 91,341, 172,449,465,339,460,117,484,487,110,172,229, 98,184,328,507,369,459, 43, 61,347, 456,341,339,388, 20,510,208,477,268,122,331,240, 7,271,184,357,348, 48,117,236, 294,478,254,479,349,265,433,341,477,359, 18, 59,184,439,166,510,435,345,117,361, 464,352,166,470,266,339,177, 49,176,246,479), TPYIndex_191_list(351,213, 81,236, 69, 6,505,108,213,473,322, 15,136,136,319,510,364, 98, 7,509, 507,474,194,503,507,395,333,106,133,184,461,140,471,189,352,509,518,507,391,232, 483,390,482,484,478,503,449,117,348,509,477,236,503,500,232,518,166,450, 58,166, 191,477,322, 0,341,142,292,333,139, 15,245,315,232,368,365,172,473,459, 54, 62, 405,471,482,159,399,117,518,117,487, 16,500,483,487,423,136,505,458,470,127,179, 250,416,159,509,191, 18,395,455,482, 98,257,482,229,441,459,117,415,482, 81,393, 139,232,479, 57,180,339,457,411,179,277,339, 7,399, 43,434,483,164, 18,117,441, 70, 65,472,522, 71,175,449,479,136,147,340,112,393,460,451, 42,189,339,214,457, 98, 13,314,435,241,315,468,173,505,395,366,268,100, 15,453,149,172,229, 12,175, 406,222,479,483,413,259, 90,457,231, 63,235), TPYIndex_191_list(484,242,461, 44,513,451,468,469,503,177,500, 26,233,111,108,235,125,379,191,164, 477,172,515,106,483,175,159,225,320,229,229,242,235, 69,509,232,487, 59,524, 20, 219, 59,477, 20, 20,446, 11, 59, 20,329,299,299,505, 58,477,362,108,395,366, 42, 122,483,477, 0,339,498,450,441,516,431,460,431, 98,508, 45,291,507,505,510,423, 477,351,166, 89,482,277,477,178,234,470, 96,181,482,350, 81,180,477,351,208,467, 233,166,470,186,369,524,172,259,108,339,159,462,159,451,477,453,412, 18,149,420, 366,470,459,124,229,168,351,155,108,295,261,299,477,213,231, 68,477,457,492,319, 482,233,119,122,431,258,442, 46,117,332,298,178,177,488,477,247,187,432,475, 3, 276,172,143, 8,184,335,234,341,139, 85,498,471,347,483, 4,468, 24,214,484,399, 100, 53,175,406,500,306,377,246,479,507,147), TPYIndex_191_list(472,456,231,417,166,136,220, 16, 67,510,322,482,509,179,483, 58,431,418,484,306, 422,415,472, 48,431,395,505,482,487, 98,168,418,451,278,474, 50,470,418,395,507, 484,413,249,139,501,503, 27, 48,413, 96,395,241,507, 67,359,341,468,483,477, 98, 233,395,250, 0,468,500,427,106, 20, 20,229,484,482,246,229,435,339,388,483,366, 449,117,192, 23,463,393,484, 66,168, 12,184, 20,447,213,141,395,209,503,462,242, 525, 64,122,164,328,464,517,168,523,279,477,443, 69,395, 26, 48,172,208, 72,224, 498, 1,474,117,271,477,420,229, 98, 18, 15,143,347,478,488,188,119,137,236, 89, 297, 97,280,482,408,213,172,393,166, 68,234,477,461, 18, 59,140,166,466,477,315, 211, 97,172,264,261,498,299,127,270,250, 48,223,128,100,498,417,493,457,526,172, 112,494,306,263,235,513,509,423,161, 65,386), TPYIndex_191_list(145,458,172,160,464,457,141,306,222,472, 47, 90,247,117,483,222,173,128, 25,457, 351,461,339,348,509,521,333,225,291,482,335,460,184,481,345,477,257,371, 15,399, 483,487,160,214,460,460,412,422,266,457,366, 51,518,521,475,456,460,487,345,481, 254, 44,242, 0,233,513,161,345,449,345,467, 79, 18,470, 18,497,451,506,254,235, 97,259,475,378,211,112,259,216,231,491, 42,482,339,472, 42,491,352,480, 70, 25, 87,222,229,400, 58,498, 68,278,229,214,178,481,214,182,412,478, 48,178,241,209, 455,166,347, 6,413, 91,194,295,151, 46,417,125, 1,100,149, 82, 3, 3,417,152, 439, 48,320,225, 32,330,339,479, 17,412, 81,261,322,186,233,337, 53,177,309,347, 242, 35, 79,149,179,469,477,374,328,366, 40,168,279,451,175,278,245,161,236,482, 483,348,483,164,451,507,320,422, 50,494,143), TPYIndex_191_list(457,491,507,483,478,524,254,505, 90,505,484,117,432,340,334, 50,524, 58,482,478, 337,524,145,515,242,221,472,423,500,421,515,459, 91,421,350, 57,487,107,194,412, 50, 67,487,481, 5,498,176,330, 46,483,229,493,477,176,421,334,299,477,472,477, 293,366,398, 0,472,236,261,261,293,463,177,395,261,472, 20,395,477,457,179,350, 477,233, 72,502,236,334,350, 7,505,507, 7,243,117,277, 84,459,345,451,455,251, 501,117,108,172,339,341,339,351,471,459, 6, 34,221, 7,161,194, 89,173,466, 69, 135,254,265,477, 89,345,470,506,223,220,411,472,136,461,143,206,186,364,474,448, 490,451,483, 67,241,518,257,394,411,172,501,235, 79, 23,477, 83, 48,318, 63,470, 473,160,220,457, 43,165,474,507,177,351,376,108,350, 4,140,249,298,487,458,319, 110,364,211,398,416, 18,185,229,483,459,478), TPYIndex_191_list(208, 54,518,108,483,456,147,123,339,252,363, 81,408,457,477, 41,477,441,457,307, 341,350,175,502,475,478,314,109,505,464, 90,485,508,117,328,369,463, 98,186, 96, 135,478,341, 11,457,361, 44,298,111,487,477,347,328,143,159,478,187, 84,477,508, 457,121,363, 0,168,420,192,484,242,288,452, 97,518,291,441,395,265,328,194,236, 24,420,161, 25,328,483,408,526, 26,509,432,173,505,395,522,507,184,414,477,143, 246,291,391, 63,261,161, 40,451,451,257,280,501,180,186,233,462,470,164, 54,168, 416,478, 89,395,422,444,457,361,483, 48,477,460, 25,483,167, 40,412,268,466,179, 376,513,279,328,456,141,319,466,460,445, 4,483, 18,128, 6,179, 42,462,235,479, 399, 72, 66, 42,456,507,313, 49,456,189, 43, 55,411, 20,298,161, 51,322, 68,473, 526,291,117, 44,477,477,439,472, 33,189,470), TPYIndex_191_list(434,477,477,468,502,319,151,379,394,522,522, 25,510, 48,488,334,439,341,117,499, 254,472,117,229,485,328,473, 11, 25,178,351,467,506,271,457,457, 81,173,271,421, 393,477,408,213,188, 15,517,464,159,177, 48,199,246,333,395,270,194,478,187,509, 49,460,439, 0,268,225,172,483,467,361,525,507,406,229,459,464,352,328,477,510, 460,266,210,474,459,459,466,187, 40,223,172,328,366,261,477,478,140,194,487, 15, 411,341,214,215,477,431,352,346,464,110, 43,450, 50,161, 65,487,214, 98,228,515, 345, 18,413,341,481,180,345, 49, 51,235,259,432,166,402,472,451,159,265,192,418, 247,215,182,222,483, 43,457,452,167, 98,351,353,151,432,353,191,514,317,342,376, 339,408, 40,112,484,271,262, 96,261,136, 20,452,148,451,224,122,399,240,242,473, 408, 97,236,254,246,468,317,445,159,265,180), TPYIndex_191_list( 4, 88,482,379,193,341,408,289, 84,147,485,507,199,350,461,503,482,492,431, 67, 137,159,508,441,247,259,222,449,518,487, 15,413,483, 42,435, 25,147,173,159,185, 112, 42,449,507,445,468,456,483,433,213,517,244,464,347,393,147,244,475,184,497, 184,459,434, 0,252,337,229,317,485, 47,124,229,425, 24,510,505,441,237,524,184, 43,484,175,123, 84,423, 43,245,210,236,328,242,229,342,335,185,265,164,451,234, 173,505,478,166,510,172,467,166,423,470,176,237,161,470,366,413,456,220,451,517, 185, 34, 12,457,257,164,510,339,457,411, 91,517,328,262,122,110, 61,393,139,242, 402,462,472,262,350,412,165,467,321,175,468,455,257,472,347,194,391,252,479,337, 229,366,418,167, 18,466,117,422,318,266,165,479,461,221, 32,161,246,164,231,510, 477,242,468,122,399,408,388,390,439, 42,220) ); BEGIN IF (p_Index>0) AND (p_Index<192) THEN RETURN v_list10(p_Index1)(p_Index); ELSE RETURN 0; END IF; end get_py_index_10; FUNCTION get_py_index_11(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER IS v_list11 TPYIndex_list := TPYIndex_list( TPYIndex_191_list(524,322, 4,328,459,471,515,229,194,206,418,215, 91,515, 56,518,506, 16,295,520, 97,472, 87,477,341,515,172,483,179,139,254, 43,444,457,231,423,136,457,399,505, 247,259,242,162, 21,119,220,198,109,456,277,449,161, 73,459,446,168,232,107,258, 189,473,395, 0,231,143,459, 91,441,451,449,117,365,172, 98,187,505,431,498,161, 473, 92,458,483,199,394,165,451,117,502, 40,346,395,159,214,432,345,415,229, 70, 42,231,366,337, 18,149,517,147,462,479,485,111,149, 7, 13,141, 71,261,482, 46, 297,341,341,456,233,341,164,175,175,521,471,456,181,494,477,106,173,180, 69,160, 318, 26,229,350,461,431,354,214,451,164,242, 54,165,350,458, 6,135,418,237,459, 235,184,462,263,415,219,470,166,442,507,193,507,172, 98, 42,457,184, 42,180,301, 261,117, 18,483, 51,406,110,472,456,483, 18), TPYIndex_191_list(345,160,440,520,164,475,265,175, 92,175,411,214,161,468,503,178,505, 20,508,518, 466,475,257,315, 3,121,341,257,417,418,318,458,231,417,189,522,475,300,453,364, 422,417,342,229,406,515, 25,317,372,328,377,123,518,456,479,165,433,237,189,416, 395,412,449, 0,149,505,505,246,477,484,422,295,457,173,125,249,185,411,522,417, 446,112,452,276,242,417,313,522,442,466,139,468,231,412,251,268,246,179,518,141, 298,483,408, 68,509,388,346,471,359,399,243,177,332, 40,229,333,447,459,417, 81, 451, 98,180, 21,178, 43, 18, 42,301, 6,484,435,456,135,268,328, 3,332, 48,229, 472,342,330, 43,225,501,457,388, 18,294,268,403,119,119,117,301,518,178,186, 13, 492,408,117,521,477,301,420,461,162,329,229,339,194,515, 30,507,456, 6,237,388, 21, 61, 42,172,460,177,483,509,125,449,213), TPYIndex_191_list( 18,451,237, 81,376,520,477,242,199,342, 65,339, 43,422,251,481, 42,112,180, 21, 399,247,466, 61,240,491,491, 32,229,458,457,192,403, 17,501,341, 47,242,162,172, 337,415,342,334,235,379,466,459, 47,214,408,237,280,165,331,415,108,345,352,473, 422,460,483, 0,177,525,233,346,223, 96,463,491,339,175,508, 79,471,479, 96,186, 300,491,337,434,446,501, 87,388,189,175,110,415,242,185,166,483,231,487,328,399, 122,462,117,509,117, 51, 69,209,148,176,128,461,431,236,339,110,389,142, 97,398, 237,352,449,518,194,460,431,263,166,408, 20,135,515,265,179,505,366,124,229,477, 175, 23,330,251,225,267,378,462,233,497,176,341,345,164,523,474,172, 54,490,481, 87,172,451, 23,265,186,194,240, 83, 69,334,265,173,106,133,467,471,155,474,246, 457,166,231,339,479,339,161,215,472, 61,449), TPYIndex_191_list(517,378,341,517,225, 18,434,468,475, 97,143,422,351,111, 68,477, 3,520,470, 84, 510,155,515,172,295,151,168,348, 23,479,214,297,467,175,175,341, 40,507,264,229, 225,172,523,213,389,322,219, 91,485, 58,247, 21, 13,242,459,212,240, 98,242,175, 221, 25,341, 0,474, 42,460,175,457,139, 31,295,225, 64,351,317,246,523,243,526, 477,186,422,510,221,457,473,464,319,464,252,471,507,459,483,477, 43, 46,184,254, 483,484,458,280, 3,422,179,165,479, 65, 61,468,501,337, 30,351,242, 18,491,452, 451,487,423,456,390,339, 40,249,229,328,263,474,369,175, 51, 47, 61,461,109,314, 510,277,507,503,240,182,333,242,458,461,482,507,445,507,236,135, 81,229,445, 47, 193,223,471,359,507,505,140,339,435,216,182,162,155,141,178,243,185, 4,467,108, 136,117,186,518,417,236, 51,111, 91,341,502), TPYIndex_191_list(507,479,165,518, 25,422,364, 17,237,468,219, 42,501,501,182, 6, 85,186,233,291, 258,249,402,388,388,258,472, 18,147, 18,388,341,192, 17,159,370,376,459,459,175, 265,458,404, 90,498,280,500,322,458,236,139, 18,370,151,449,125,125,107, 51,460, 141,265,384, 0,215,232,247,435,386,184,485,485, 42,351,235,422,387,215,472,452, 472,483,167,483,452,460, 13,460,351,474,452,317,478,451,478,216,353,246, 56,232, 143,175, 81,184, 62,393,278,498,231,221,172,332,184,350, 92, 56, 46,247, 40,184, 468,257,479,505,110,418,416,462,124, 65,124,406, 23,364,510,462,179,342,339, 51, 422,510,161,122,485,348,445,186,345,347,242,525,457,184,484,225,472,235, 25, 40, 482, 6,268, 63,389,432,487,231,330, 70,172, 23,477,361, 98,136,194,242,507,477, 505,161,229,474,395,507,352,242,503,292,450), TPYIndex_191_list(221,391,352,325,432,295,418,189,151,353, 55,449, 90,339,214,422,449,330,459,457, 166, 42,328,422,164,418,452,446,147,189,391,166,418,164,224,463,477,507,478,473, 90, 98,394,320,199,487,507,328, 47, 98,351, 81,236,507, 24, 97,399,415,106,141, 483,187,345, 0,464, 57,456,458,388,394,337,505,459, 72,320,477, 94,245,478,184, 505,242,394,459,478,510,473,362,458, 49,472,478,483, 81,451,295,515, 58,518, 62, 242,235,451,175,342,173,172,172,191, 79,121,175,492,313,236, 26, 17,497,328,334, 119,219,122,149,421,124,494,463,487,141,151,491,254,483, 43,291,339,394,475, 44, 472,166, 26,147,141,468,214, 3,266,444,470,474,457,279, 16,395,213,477,507,518, 121,179,505,220,350,172, 70,117, 42,172,457, 81,483,135,179,351,175,176,332,254, 136,456,136,172,184,175,329,193,346,417, 8), TPYIndex_191_list( 4,178,339,472,166,487,456,422,172, 72, 6,457,478,372,359,235,443, 79,328,415, 483,472,111,291,106,172, 72,478,507,240,457,229,229,353,507,477,347,341,164,135, 524,161,488,483, 50,415,147,455,403,164,184,488,481,172,457,237,229,306,469,488, 172,172,276, 0,116,457,271,111,318,487, 48,473, 4,456, 83, 71,161, 84,271, 46, 498,236,339,509,159,500,478,510,444,236, 89,479,456,236,236,159,478,125, 25,254, 271, 65,175,376,399, 43,242,337,351,331, 72,459, 54, 89,471,478,194,487,108, 48, 177, 91, 85,482,484,143,485,455,364,165,180,368,420,133,516,276,474,341,240, 89, 188,242,173,393,509,526,137,505,351,507,180,140, 89,472,211,372,145,329,505,261, 444,246, 67,319,449,294,180,472,110,483,520, 87,175, 62,278,262,447, 98,399, 47, 479,125,247, 23,427,507, 53,136,259,378,388), TPYIndex_191_list(250,250,487,237,259, 23,456,451,216,457,477, 70,427,483,240, 69,172,318,473,451, 446,457,172,456,259,225,229,417, 3,110, 69,240,236,477,112,229, 13,151,151,151, 24,348,432,505, 47,348,232,180,432,110,262, 13,432,166,475, 87, 40,341,361, 81, 91,456,361, 0,347,298,478,372,276,447,522, 11,477,474,423, 18,178,159,319, 24, 478,418,423,178, 4,154,133,340,435,479,415,433,468,206, 17,418,501,231,235,483, 457,477,386,463,457, 21,372,184,412, 21, 21,399,135,136,161,110,172,221,483,320, 254,500,180,291,237,477,473,451, 96,342,395,161,510,468,420,475,473,456,147,258, 44,472,161,483,451, 92, 13,468, 20,443,237,251,389,487,477,483,108,415,459,186, 64,408,423,467,457,229,161,181,161,110,395,408,459,507,351,161,117,526,261,507, 59,505,433,339, 42,457,517,457,358,425,421), TPYIndex_191_list(328,216,219,498, 12,101,350,350,391,390,271,175, 81,312,423,418,462,317,125, 24, 216,422,241,166,345,469,172,175,176, 42,418,161,459,341, 91,447,175,221,451,361, 117,447,352,125,451,390,147, 43,216,365,487,391,451,125,117,423,135,487,124, 18, 469,415, 91, 0,447, 91,117,182,459,462,459,172,488,224,322,479,479,487,322, 4, 478,460,161,475, 87,348,214,460,405,147,467,477,467,136,411,214,339, 94,173,166, 307,296,473,518,353,341,265,425,339, 94,254,258,123,483,483,418,469,263,172,122, 71,162, 45, 96,471,517, 20,112,107, 3,229,240,498,439, 81,219,445,117,464,252, 458,345,499, 89,280,125,455,339, 94, 15, 87, 46,509,178, 81,468, 20,503,142,377, 348,351, 96, 79,176, 27,259, 25,191,507,117,117,467,262,208, 96,263, 70,394,484, 477,415,518, 48,270,220,175, 81,417,471,291), TPYIndex_191_list(148,483,449,111, 96, 81, 83,317,334,236, 45,180,225,347,345, 98, 98,451,462,216, 393,477,477,194, 94,483,333,225,433,173,440,166,214,173,246,435, 47,479,487,161, 147,180,443,443,332,220,443,518,518, 56, 87,220,421,147,341,212,522,459,347,477, 374,431, 98, 0, 98,472,452,472,483,513,472,459,463,477,484,377,432,432,176,214, 225,223,330,512,251, 63,474,149,345,136,470,472,166,388,366,259, 23,415,328,369, 412,214,254,194,266,330, 47,191,235,136, 87, 18,352,432,108,505,391,449,442,117, 123,136,229,472,328,221,229,172,497,151,139,185,179,119,477,334,502,233,441, 54, 388,258, 41,307, 26,420,184, 11,341,109,192,440,168,314,483,506,136,194,334, 26, 25,485,271,421, 83,406,395,468,418, 18,291,328, 97,193,223,106,482, 47,173,280, 475, 47, 84,478,189,510, 87, 88,162,352,144) ); BEGIN IF (p_Index>0) AND (p_Index<192) THEN RETURN v_list11(p_Index1)(p_Index); ELSE RETURN 0; END IF; end get_py_index_11; FUNCTION get_py_index_12(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER IS v_list12 TPYIndex_list := TPYIndex_list( TPYIndex_191_list(459,332,242,235,295,352,435,181,335,479,483,225,112, 88,137,117,458,500,319,372, 117,420,234,172,468,461,184, 21,408,451,473,474,412,189,412,108,237,457,237,330, 330,237, 21, 21, 21,233, 21,379,112,466,473,500,408,474,237,110,108,110,395, 30, 172, 87,408, 0,445,500,516,361,483,473,395,478,108,108,416,478,510,477,526, 18, 178,423, 13, 59,434,408, 13,395, 97,145,361,432,177,173, 24,474,439,386, 84,506, 379, 49,422, 4,366,223,220,425,199,497,229,124, 98, 67,244,237,189,175,222,347, 184, 1,342,306, 16, 73,194,215,136,168,320,185,421,518,346,189,408, 98, 40,412, 164, 3,241,342,110,257,268,125,185,276,237,477,173, 23, 21,422,251,246,481,522, 468, 81, 42,186,337,242, 96,221,337, 64,342, 79,168,517,477, 40, 21,508,393, 67, 507, 18,518,268,399,247,172,117,222,194,361), TPYIndex_191_list( 59,460,473,185,106,224,457, 25,282, 98, 26,187, 90,413,483,457,474,215,143,395, 175,515, 24,459, 26,475,421,110,501,451,139, 98,302,487,161,165,166,500,160,151, 464,111,451,136, 40,411,422, 25,124,457,214,237,412,459,475,452,268,422,251, 18, 483,466,179, 0,376,443,513,388, 48, 70,477,339,359, 47,451,460,500,111,145,259, 472,268, 42,460,246,491,279, 87,445, 97,173,224,457, 90,187,143,136,505,172,379, 292,117,358,141,177,149,457,334, 85,161,481,182,484, 13,505,136, 89,242,351, 48, 408,106,507,137,466,243, 25,229,161,483,459,431,456,263, 4, 15, 57,161, 98, 59, 257,456,474,175,479,503,237,233,177,182,483,161,242,139, 24, 87,178,229,388,229, 482,122,194, 70,498,319,510,468,173,471,477,507,223,456, 67,459,386,510,110,136, 451,483,483, 70,219,477,160, 67,241,173,378), TPYIndex_191_list(475, 25,111, 25,291, 18,334,441,147,110,175, 4, 3,459,487,111,332,463,249,483, 333,341, 81,445,503, 48,470,510,507,320,463,363,372,487,452,507, 70,247,482, 25, 13,211,445,477,351,337,351,181,334,502,484,322,509,184,510,301,184,328,522,173, 236,505,499, 0,117,473,395, 18,445,445,408,237,249,329,423,507,364,427, 89,470, 352,393,181,106,145, 25,510,478,246,509, 70,145,237,184,411,347,252, 48,268, 11, 172,165, 21,246,479,499,240,478, 50, 11,220,477, 83,328, 83,351,477,411,457,349, 516, 20,474,433, 90,194,483,470,184,483,477, 40,276,361,179,257,317, 71,340,125, 198,231, 47,231,175, 21, 51,431, 18,184, 97, 68, 15, 13,247, 20,221, 48,503,342, 366,317,399,467,187, 66,179,225,518, 44,408,168,223,422,313,241,176,300,268, 85, 87, 70,236,297,143,214, 6,421,147,339,148), TPYIndex_191_list(232,147,441,468,443,187, 98, 47,464,408,242,515,509,391,329,215,423,220,520,194, 339,339,472,110,378,472,125,474,456,329, 61,329,341,110,165,341,168,483,431,352, 458,520,214,365,408,137,445,443,412,341, 47,507,237,322,427,457, 32, 91,472,484, 521,461,388, 0,339,507,403,242,457,246,501,268,474, 30,330, 61,351, 18,507,483, 467,162, 25,413,461,235,500, 96,237,445, 35, 83,461,434,472,246,500,178,151,479, 194,147, 98,513,295,251,377,149,366,332,161,341,350,172, 41,166,125,259,117,328, 369,459,149,178,133, 90,478, 48,147,136,194,229,482,357,498,350,236, 47,482,349, 173,280,507,408,351,435,216,339,177,473,270,393,503,390,456,229, 51,117,342,348, 339,457,483,110,143,143,477,328,433,352,449,222,259, 57,364,278,117,214,194,117, 412,483,482,241,350, 20,270,347, 6,251,252), TPYIndex_191_list(180,477,475,503,332,509,472,492,247,427,460,172,403,184,457,164,229,330,363,478, 330,464,347,520,413,214,403,451,451,451,483,122,477,192, 13, 15,499,431,461,210, 443,128,329,483,415,334,461,318,186, 67,268,233,241,461,492,431, 23,212,242,124, 345,193,345, 0,223,378,215,431,109,466,357, 70,215, 23,107,328,107,431, 13, 18, 365,117,106,364,351,133,485,322,511,390,417,431,229, 23,431,322,411,249,484,457, 48,422,318,395,165, 32,330,422,457,460,508,501,401,254,322,166,317,388,168,259, 42,231,264,229, 91,351,116,479,348,458,395,510,483,172, 91,172,175,502,518,161, 349,334, 68,394,494,135,229,408,433,173, 20, 48,208, 18,459,472,352,506,187,395, 123,314,390,461,348,494,346,510,371,341,445, 18, 70,206,484,461,505,214,165,160, 135,110,229, 18, 48,413,264, 90,242, 92,141), TPYIndex_191_list(506,520,405,175, 97,161,219,339,231,505,322,249,376,251,251,383,467,234,341,341, 279,216,297, 23,358, 90, 90,280,460,457, 90,147, 90, 90,182,483,483,472,229,463, 141,520,237,462,389,257,339,339,119,467,483,443,339,232,122,330, 18,339,467, 50, 472,500,483, 0, 72,361,178, 7,159,445, 84,172,483,162,346,417,148,444,268,178, 393, 11,484,328,247,452,161,242,488,109,111,276,482,329,268,151,458, 83,491, 79, 25,220,509,483,483, 49,457,295,307, 54,388,477, 18,508, 11,109,125,242,510,494, 457,390,451,259,398, 32, 49,259,347,294,173,350,386, 18, 81,342,417,178,422,457, 459,261, 7,229,433,457, 59, 30,235,520,376,160,491, 59,467,365,350,176,127,172, 477,236,457,510,110,175,329,151,477,261,507,339,339,474, 72,117,351,182,346,234, 518,491,278,503,176, 48, 87,122,509,477,136), TPYIndex_191_list(462,147,328,236,445, 25,350,333,117, 18,172,451,351, 84, 25,482,142,328,292,506, 420,319,117,498,184,136,395, 89, 69,418,340,399,160,505,106, 4,451,502,510,478, 234,246,439,477,477, 24,451,177,209,462,459,125,166,223,117,193,466, 97,187,431, 262,390,498, 0,417,347,483,282,503,142,128,413,456,350,393,337,164,433,229,386, 386,193,259, 47,229,521,457,481,393,518,339,506,460,282, 57,172, 84,526,445,459, 266,507,472,387, 47,441,225,215,320,161,431,467,145,422,223, 26,177,457,184,229, 470,395, 67, 96,349,469, 63, 22, 13,418,175,117,342,507,117,388,229,445,173, 25, 420,214,345, 18,459,459,172,177,232,172, 58,163, 48,507, 83, 25,507,175, 85, 53, 508,184, 97, 67,329,365,295,317,339, 51,186,337,108, 63,510,235, 42,234,523,462, 507, 84,268,466,268,328,161,186,389,136,524), TPYIndex_191_list(346,136,509, 89,220,110,291,477,215,242,182, 43,180,245,236,521,229,259,520,507, 292,161,483, 81,395,393,164,431,160,506,510,219,520,495, 20, 20,164,352,495,451, 451,483, 57,365,498,165,231,472,350,350,175, 18, 98,473,117,457,459,458,451,161, 395,371,468, 0,452,341,149,456,318,378,237,249,395,395,215,518,427,418,474,125, 481,341,339,452,371,393,231, 6,224,166,265,172,433,351,175,393,251,133,413,507, 518,348,232,483,229,452,435,172,320,110,386,478, 3,459,250, 46,184, 13,433,518, 478,483, 58,455,265,484,445,515,416,187,184,246,351, 50,349,243,456,491,270, 6, 237, 15,463,482,109, 7,333,292,242,413,117,160,420,141,178,451,106,172,177,460, 470,128,229,231,175,395,433,142,386,164,172,348,236,521,110,215, 43,136,291,292, 84,395,518,111, 85, 98,350,117,165, 20,378), TPYIndex_191_list(457,350, 21,172,172,510,176,466,513,481,501,192,469, 22,483,351,460, 25,177,470, 413,165,525,445,388,108,186,235,470,263,457,497,460,111,139,160,211,495,378,500, 122,141,479,229, 43,225,399, 3,366,172,483,161,399,229,234,246,264,505,460, 98, 242,139,229, 0,459, 72,172,444, 7,151,482,498, 25,328,193,439,495,160,211,498, 187,481,339,393, 18, 43,431,452,451,352,176,318,341,451,457,161,122, 6,339,418, 139,474,224, 21,469,251,265,481,141,388,525,229, 68,473, 68,345,251,175,184,365, 135, 15,178,440,209,136, 81,160,125,194, 18,241,340,212, 23, 91,257, 7,472,232, 461,450, 48,460,472,434,423,481, 19,215,254,357,433,172,518,466,352,182, 23,164, 234,256,166,261,172,187,510,261,339, 6,391,235, 69, 51,482,458,477,351, 91,229, 348, 30, 4,111,482,456,472,457,350,147,498), TPYIndex_191_list(500,139,353,477,117,229,507, 26,472,117,502,172,112,366,472,395,112,266, 13,484, 507,161,347,141,111,452,500,395,483,116,474,186,186,328,164,505, 13,472,471,506, 109,112,452,313, 69,125,366,236,264,117,445,452,229, 20,507,125,484, 59,351,461, 48, 70,184, 0,474,136,508,483,473,483,471,434,483,432,479, 94,456,106,137, 3, 507,472,155,461,173,234,510,473,477,159,242,366,270,125,361,461,466, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) ); BEGIN IF (p_Index>0) AND (p_Index<192) THEN RETURN v_list12(p_Index1)(p_Index); ELSE RETURN 0; END IF; end get_py_index_12; FUNCTION get_py_index_13(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER IS v_list13 TPYIndex_list := TPYIndex_list( TPYIndex_191_list(509, 48,246,155,292, 98,243,173,172,441,185,445,337,456,185,483, 25,187,187, 18, 457,187,184,441,180,431, 98, 98,213,161,456,393,220,177,317,242,328,399,117,471, 517,322,350,341, 15, 84,242,353,175,184,441,471,484,339,229,475,515,206, 97,215, 394,339,180, 0,477,477,348,518,220, 89,339,442,128,184,351,477,525,172,399,446, 48,263,365,471,350,431,161,431, 98,178,254,117, 57,441,472,151,484, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), TPYIndex_191_list(329,215,257,161,479,507,456,184, 89,342,109,161,479,484,459,453,395,151, 51,422, 458,371,237,172,161,341,470,147, 59, 59,477,474,472,172,229,432,208,431,431,477, 441,249,461,124,432, 46,172,442,503, 6,474,477,313, 48,507,237,481,247, 18,403, 517,483,456, 0,186,478,431,408,177,477,162, 18,479,413,165,108,177,233,472,124, 182,459,459,441,250,525,483,479,242,442,459,469,477,328,510,246,457, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), TPYIndex_191_list(477,172,494,483,500,475,473,328,297,161,261,479,259, 81,485,483,225, 26,242,151, 240,403,485,479,352,351,229,243,395,342,461,236,469,155,509,456,215,341,128,484, 413,151,350,477,453,237,172,477,477,164,500,259,403,242,179,236,175,459, 67,175, 175,472,482, 0, 63,319, 63,319,510,175,261,483,237, 46,354,235,291,182,354,180, 408,460,472,173,261,229,501,180,339,236,472, 63,250,151, 44,117,262, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), TPYIndex_191_list(262,117,319,351,351,270,117,472,220,262, 48,112,351,262,268,268,521,304,111,165, 179,140,432,440,162,213,159, 48,152,477, 70,457,444,268,341,500,472,257,472,485, 422,472,472,472,505,505,516, 30,477,257,500,472, 91,242,111,265,484, 63,351,502, 447,510,507, 0,259, 6, 22,445, 18,502,261,505,518,136, 89,111,484, 43,124,339, 484,422,427,399,110,452,110, 84,445,508,351,394,395,395,435,457,180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), TPYIndex_191_list(167,457,472,441,408,459,225,474,456,456,209,462,151,466,453,498,299,279,518,499, 172,518,172,172, 48, 46, 46,151,471,478,462, 13,494,462,518, 48,472,498,433,236, 236, 51,352,462,478,295,182,474, 58,487,483, 51,477,291,498,521,351,487,472,483, 98,455,477, 0, 67,521, 83, 51,179,471,151,478,252,318,455,318,472,252,240,133, 194, 68,236, 68,350,350, 22, 56,151,186,462,485, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), TPYIndex_191_list( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) ); BEGIN IF (p_Index>0) AND (p_Index<192) THEN RETURN v_list13(p_Index1)(p_Index); ELSE RETURN 0; END IF; end get_py_index_13; FUNCTION GetHzFullPY(p_String varchar2) RETURN VARCHAR2 IS --declare --p_String varchar2(200) := '???????'; v_char varchar2(2); --???? n_loop number; --?? n_len number; --???? n_ascii number; --??ASCII? n_ord_high number; --n_ascii/156 n_ord_low number; --n mod 256 n_temp number; n_temp1 number; v_PY varchar2(32767); BEGIN v_PY := ''; n_len := length(p_String); FOR n_loop IN 1..n_len LOOP v_char := substr(p_string,n_loop,1); IF upper(v_char) IN ( 'A','B','C','D','E','F','G', 'H','I','J','K','L','M','N', 'O','P','Q','R','S','T', 'U','V','W','X','Y','Z', '0','1','2','3','4','5','6','7','8','9', '(', ')', '[', ']','.', '!', '@', '#', '$', '%', '^', '&', '*', '-', '+','<', '>', '?', ':', '"') THEN v_PY := v_PY||v_char; ELSE n_ascii := ascii(v_char); n_ord_high := trunc(n_ascii/256,0); n_ord_low := n_ascii-(n_ord_high*256); --DBMS_OUTPUT.PUT_LINE('n_ascii = '||to_char(n_ascii,'9999999')); --DBMS_OUTPUT.PUT_LINE('n_ord_high = '||to_char(n_ord_high,'9999999')); --DBMS_OUTPUT.PUT_LINE('n_ord_low = '||to_char(n_ord_low,'9999999')); IF (n_ord_high>128) and (n_ord_low>63) THEN CASE n_ord_high WHEN 162 THEN --???? IF n_ord_low>160 THEN v_PY := v_PY||get_roma_num_py(n_ord_low-160); END IF; WHEN 163 THEN --??ASCII IF n_ord_low>128 THEN v_char := chr(n_ord_low-128); IF upper(v_char) IN ( 'A','B','C','D','E','F','G', 'H','I','J','K','L','M','N', 'O','P','Q','R','S','T', 'U','V','W','X','Y','Z', '0','1','2','3','4','5','6','7','8','9', '(', ')', '[', ']') THEN v_PY := v_PY||v_char; END IF; END IF; WHEN 166 THEN --???? IF (n_ord_low>160) AND (n_ord_low<185) THEN --A1--B8 v_PY := v_PY||get_greece_alphabet_py(n_ord_low-160); ELSE IF (n_ord_low>192) AND (n_ord_low<217) THEN --C1--D8 v_PY := v_PY||get_greece_alphabet_py(n_ord_low-192); END IF; END IF; ELSE BEGIN n_temp := n_ord_high-128; n_ord_low := n_ord_low-63; n_temp1 := trunc(n_temp/10,0); n_temp1 := n_temp-n_temp1*10; IF n_temp1=0 THEN n_temp1 := 10; END IF; --DBMS_OUTPUT.PUT_LINE('n_temp = '||to_char(n_temp,'9999999')); --DBMS_OUTPUT.PUT_LINE('n_temp1 = '||to_char(n_temp1,'9999999')); CASE WHEN n_temp<11 THEN n_temp1 := get_py_index_01(n_temp1,n_ord_low); WHEN n_temp<21 THEN n_temp1 := get_py_index_02(n_temp1,n_ord_low); WHEN n_temp<31 THEN n_temp1 := get_py_index_03(n_temp1,n_ord_low); WHEN n_temp<41 THEN n_temp1 := get_py_index_04(n_temp1,n_ord_low); WHEN n_temp<51 THEN n_temp1 := get_py_index_05(n_temp1,n_ord_low); WHEN n_temp<61 THEN n_temp1 := get_py_index_06(n_temp1,n_ord_low); WHEN n_temp<71 THEN n_temp1 := get_py_index_07(n_temp1,n_ord_low); WHEN n_temp<81 THEN n_temp1 := get_py_index_08(n_temp1,n_ord_low); WHEN n_temp<91 THEN n_temp1 := get_py_index_09(n_temp1,n_ord_low); WHEN n_temp<101 THEN n_temp1 := get_py_index_10(n_temp1,n_ord_low); WHEN n_temp<111 THEN n_temp1 := get_py_index_11(n_temp1,n_ord_low); WHEN n_temp<121 THEN n_temp1 := get_py_index_12(n_temp1,n_ord_low); WHEN n_temp<121 THEN n_temp1 := get_py_index_13(n_temp1,n_ord_low); ELSE n_temp1 := 0; END CASE; v_PY := v_PY||GetHzPY_by_index(n_temp1); END; END CASE; END IF; END IF; END LOOP; RETURN v_PY; --DBMS_OUTPUT.PUT_LINE(v_PY); END; FUNCTION GetHzFullPYLower(p_String varchar2) RETURN VARCHAR2 IS --declare --p_String varchar2(200) := '???????'; v_char varchar2(2); --???? n_loop number; --?? n_len number; --???? n_ascii number; --??ASCII? n_ord_high number; --n_ascii/156 n_ord_low number; --n mod 256 n_temp number; n_temp1 number; v_PY varchar2(32767); BEGIN v_PY := ''; n_len := length(p_String); FOR n_loop IN 1..n_len LOOP v_char := substr(p_string,n_loop,1); IF upper(v_char) IN ( 'A','B','C','D','E','F','G', 'H','I','J','K','L','M','N', 'O','P','Q','R','S','T', 'U','V','W','X','Y','Z', '0','1','2','3','4','5','6','7','8','9', '(', ')', '[', ']','.', '!', '@', '#', '$', '%', '^', '&', '*', '-', '+','<', '>', '?', ':', '"') THEN v_PY := v_PY||v_char; ELSE n_ascii := ascii(v_char); n_ord_high := trunc(n_ascii/256,0); n_ord_low := n_ascii-(n_ord_high*256); --DBMS_OUTPUT.PUT_LINE('n_ascii = '||to_char(n_ascii,'9999999')); --DBMS_OUTPUT.PUT_LINE('n_ord_high = '||to_char(n_ord_high,'9999999')); --DBMS_OUTPUT.PUT_LINE('n_ord_low = '||to_char(n_ord_low,'9999999')); IF (n_ord_high>128) and (n_ord_low>63) THEN CASE n_ord_high WHEN 162 THEN --???? IF n_ord_low>160 THEN v_PY := v_PY||get_roma_num_py(n_ord_low-160); END IF; WHEN 163 THEN --??ASCII IF n_ord_low>128 THEN v_char := chr(n_ord_low-128); IF upper(v_char) IN ( 'A','B','C','D','E','F','G', 'H','I','J','K','L','M','N', 'O','P','Q','R','S','T', 'U','V','W','X','Y','Z', '0','1','2','3','4','5','6','7','8','9', '(', ')', '[', ']') THEN v_PY := v_PY||v_char; END IF; END IF; WHEN 166 THEN --???? IF (n_ord_low>160) AND (n_ord_low<185) THEN --A1--B8 v_PY := v_PY||get_greece_alphabet_py(n_ord_low-160); ELSE IF (n_ord_low>192) AND (n_ord_low<217) THEN --C1--D8 v_PY := v_PY||get_greece_alphabet_py(n_ord_low-192); END IF; END IF; ELSE BEGIN n_temp := n_ord_high-128; n_ord_low := n_ord_low-63; n_temp1 := trunc(n_temp/10,0); n_temp1 := n_temp-n_temp1*10; IF n_temp1=0 THEN n_temp1 := 10; END IF; --DBMS_OUTPUT.PUT_LINE('n_temp = '||to_char(n_temp,'9999999')); --DBMS_OUTPUT.PUT_LINE('n_temp1 = '||to_char(n_temp1,'9999999')); CASE WHEN n_temp<11 THEN n_temp1 := get_py_index_01(n_temp1,n_ord_low); WHEN n_temp<21 THEN n_temp1 := get_py_index_02(n_temp1,n_ord_low); WHEN n_temp<31 THEN n_temp1 := get_py_index_03(n_temp1,n_ord_low); WHEN n_temp<41 THEN n_temp1 := get_py_index_04(n_temp1,n_ord_low); WHEN n_temp<51 THEN n_temp1 := get_py_index_05(n_temp1,n_ord_low); WHEN n_temp<61 THEN n_temp1 := get_py_index_06(n_temp1,n_ord_low); WHEN n_temp<71 THEN n_temp1 := get_py_index_07(n_temp1,n_ord_low); WHEN n_temp<81 THEN n_temp1 := get_py_index_08(n_temp1,n_ord_low); WHEN n_temp<91 THEN n_temp1 := get_py_index_09(n_temp1,n_ord_low); WHEN n_temp<101 THEN n_temp1 := get_py_index_10(n_temp1,n_ord_low); WHEN n_temp<111 THEN n_temp1 := get_py_index_11(n_temp1,n_ord_low); WHEN n_temp<121 THEN n_temp1 := get_py_index_12(n_temp1,n_ord_low); WHEN n_temp<121 THEN n_temp1 := get_py_index_13(n_temp1,n_ord_low); ELSE n_temp1 := 0; END CASE; v_PY := v_PY||GetHzPY_by_index(n_temp1); END; END CASE; END IF; END IF; END LOOP; RETURN Lower(v_PY); --DBMS_OUTPUT.PUT_LINE(v_PY); END; FUNCTION GetHzFullPYUpper(p_String varchar2) RETURN VARCHAR2 IS --declare --p_String varchar2(200) := '???????'; v_char varchar2(2); --???? n_loop number; --?? n_len number; --???? n_ascii number; --??ASCII? n_ord_high number; --n_ascii/156 n_ord_low number; --n mod 256 n_temp number; n_temp1 number; v_PY varchar2(32767); BEGIN v_PY := ''; n_len := length(p_String); FOR n_loop IN 1..n_len LOOP v_char := substr(p_string,n_loop,1); IF upper(v_char) IN ( 'A','B','C','D','E','F','G', 'H','I','J','K','L','M','N', 'O','P','Q','R','S','T', 'U','V','W','X','Y','Z', '0','1','2','3','4','5','6','7','8','9', '(', ')', '[', ']','.', '!', '@', '#', '$', '%', '^', '&', '*', '-', '+','<', '>', '?', ':', '"') THEN v_PY := v_PY||v_char; ELSE n_ascii := ascii(v_char); n_ord_high := trunc(n_ascii/256,0); n_ord_low := n_ascii-(n_ord_high*256); --DBMS_OUTPUT.PUT_LINE('n_ascii = '||to_char(n_ascii,'9999999')); --DBMS_OUTPUT.PUT_LINE('n_ord_high = '||to_char(n_ord_high,'9999999')); --DBMS_OUTPUT.PUT_LINE('n_ord_low = '||to_char(n_ord_low,'9999999')); IF (n_ord_high>128) and (n_ord_low>63) THEN CASE n_ord_high WHEN 162 THEN --???? IF n_ord_low>160 THEN v_PY := v_PY||get_roma_num_py(n_ord_low-160); END IF; WHEN 163 THEN --??ASCII IF n_ord_low>128 THEN v_char := chr(n_ord_low-128); IF upper(v_char) IN ( 'A','B','C','D','E','F','G', 'H','I','J','K','L','M','N', 'O','P','Q','R','S','T', 'U','V','W','X','Y','Z', '0','1','2','3','4','5','6','7','8','9', '(', ')', '[', ']') THEN v_PY := v_PY||v_char; END IF; END IF; WHEN 166 THEN --???? IF (n_ord_low>160) AND (n_ord_low<185) THEN --A1--B8 v_PY := v_PY||get_greece_alphabet_py(n_ord_low-160); ELSE IF (n_ord_low>192) AND (n_ord_low<217) THEN --C1--D8 v_PY := v_PY||get_greece_alphabet_py(n_ord_low-192); END IF; END IF; ELSE BEGIN n_temp := n_ord_high-128; n_ord_low := n_ord_low-63; n_temp1 := trunc(n_temp/10,0); n_temp1 := n_temp-n_temp1*10; IF n_temp1=0 THEN n_temp1 := 10; END IF; --DBMS_OUTPUT.PUT_LINE('n_temp = '||to_char(n_temp,'9999999')); --DBMS_OUTPUT.PUT_LINE('n_temp1 = '||to_char(n_temp1,'9999999')); CASE WHEN n_temp<11 THEN n_temp1 := get_py_index_01(n_temp1,n_ord_low); WHEN n_temp<21 THEN n_temp1 := get_py_index_02(n_temp1,n_ord_low); WHEN n_temp<31 THEN n_temp1 := get_py_index_03(n_temp1,n_ord_low); WHEN n_temp<41 THEN n_temp1 := get_py_index_04(n_temp1,n_ord_low); WHEN n_temp<51 THEN n_temp1 := get_py_index_05(n_temp1,n_ord_low); WHEN n_temp<61 THEN n_temp1 := get_py_index_06(n_temp1,n_ord_low); WHEN n_temp<71 THEN n_temp1 := get_py_index_07(n_temp1,n_ord_low); WHEN n_temp<81 THEN n_temp1 := get_py_index_08(n_temp1,n_ord_low); WHEN n_temp<91 THEN n_temp1 := get_py_index_09(n_temp1,n_ord_low); WHEN n_temp<101 THEN n_temp1 := get_py_index_10(n_temp1,n_ord_low); WHEN n_temp<111 THEN n_temp1 := get_py_index_11(n_temp1,n_ord_low); WHEN n_temp<121 THEN n_temp1 := get_py_index_12(n_temp1,n_ord_low); WHEN n_temp<121 THEN n_temp1 := get_py_index_13(n_temp1,n_ord_low); ELSE n_temp1 := 0; END CASE; v_PY := v_PY||GetHzPY_by_index(n_temp1); END; END CASE; END IF; END IF; END LOOP; RETURN Upper(v_PY); --DBMS_OUTPUT.PUT_LINE(v_PY); END GetHzFullPYUpper; FUNCTION GetHzFullPYsubstr(p_String varchar2,s float, e float) RETURN VARCHAR2 IS --declare --p_String varchar2(200) := '???????'; v_char varchar2(2); --???? n_loop number; --?? n_len number; --???? n_ascii number; --??ASCII? n_ord_high number; --n_ascii/156 n_ord_low number; --n mod 256 n_temp number; n_temp1 number; v_PY varchar2(32767); BEGIN v_PY := ''; n_len := length(p_String); FOR n_loop IN 1..n_len LOOP v_char := substr(p_string,n_loop,1); IF upper(v_char) IN ( 'A','B','C','D','E','F','G', 'H','I','J','K','L','M','N', 'O','P','Q','R','S','T', 'U','V','W','X','Y','Z', '0','1','2','3','4','5','6','7','8','9', '(', ')', '[', ']','.', '!', '@', '#', '$', '%', '^', '&', '*', '-', '+','<', '>', '?', ':', '"') THEN v_PY := v_PY||v_char; ELSE n_ascii := ascii(v_char); n_ord_high := trunc(n_ascii/256,0); n_ord_low := n_ascii-(n_ord_high*256); --DBMS_OUTPUT.PUT_LINE('n_ascii = '||to_char(n_ascii,'9999999')); --DBMS_OUTPUT.PUT_LINE('n_ord_high = '||to_char(n_ord_high,'9999999')); --DBMS_OUTPUT.PUT_LINE('n_ord_low = '||to_char(n_ord_low,'9999999')); IF (n_ord_high>128) and (n_ord_low>63) THEN CASE n_ord_high WHEN 162 THEN --???? IF n_ord_low>160 THEN v_PY := v_PY||get_roma_num_py(n_ord_low-160); END IF; WHEN 163 THEN --??ASCII IF n_ord_low>128 THEN v_char := chr(n_ord_low-128); IF upper(v_char) IN ( 'A','B','C','D','E','F','G', 'H','I','J','K','L','M','N', 'O','P','Q','R','S','T', 'U','V','W','X','Y','Z', '0','1','2','3','4','5','6','7','8','9', '(', ')', '[', ']') THEN v_PY := v_PY||v_char; END IF; END IF; WHEN 166 THEN --???? IF (n_ord_low>160) AND (n_ord_low<185) THEN --A1--B8 v_PY := v_PY||get_greece_alphabet_py(n_ord_low-160); ELSE IF (n_ord_low>192) AND (n_ord_low<217) THEN --C1--D8 v_PY := v_PY||get_greece_alphabet_py(n_ord_low-192); END IF; END IF; ELSE BEGIN n_temp := n_ord_high-128; n_ord_low := n_ord_low-63; n_temp1 := trunc(n_temp/10,0); n_temp1 := n_temp-n_temp1*10; IF n_temp1=0 THEN n_temp1 := 10; END IF; --DBMS_OUTPUT.PUT_LINE('n_temp = '||to_char(n_temp,'9999999')); --DBMS_OUTPUT.PUT_LINE('n_temp1 = '||to_char(n_temp1,'9999999')); CASE WHEN n_temp<11 THEN n_temp1 := get_py_index_01(n_temp1,n_ord_low); WHEN n_temp<21 THEN n_temp1 := get_py_index_02(n_temp1,n_ord_low); WHEN n_temp<31 THEN n_temp1 := get_py_index_03(n_temp1,n_ord_low); WHEN n_temp<41 THEN n_temp1 := get_py_index_04(n_temp1,n_ord_low); WHEN n_temp<51 THEN n_temp1 := get_py_index_05(n_temp1,n_ord_low); WHEN n_temp<61 THEN n_temp1 := get_py_index_06(n_temp1,n_ord_low); WHEN n_temp<71 THEN n_temp1 := get_py_index_07(n_temp1,n_ord_low); WHEN n_temp<81 THEN n_temp1 := get_py_index_08(n_temp1,n_ord_low); WHEN n_temp<91 THEN n_temp1 := get_py_index_09(n_temp1,n_ord_low); WHEN n_temp<101 THEN n_temp1 := get_py_index_10(n_temp1,n_ord_low); WHEN n_temp<111 THEN n_temp1 := get_py_index_11(n_temp1,n_ord_low); WHEN n_temp<121 THEN n_temp1 := get_py_index_12(n_temp1,n_ord_low); WHEN n_temp<121 THEN n_temp1 := get_py_index_13(n_temp1,n_ord_low); ELSE n_temp1 := 0; END CASE; v_PY := v_PY||GetHzPY_by_index(n_temp1); END; END CASE; END IF; END IF; END LOOP; RETURN substr(v_PY,s,e); --DBMS_OUTPUT.PUT_LINE(v_PY); END GetHzFullPYsubstr; FUNCTION GetHzPYCAP(p_String varchar2) RETURN VARCHAR2 IS --declare --p_String varchar2(200) := '???????'; v_char varchar2(2); --???? n_loop number; --?? n_len number; --???? n_ascii number; --??ASCII? n_ord_high number; --n_ascii/156 n_ord_low number; --n mod 256 n_temp number; n_temp1 number; v_PY varchar2(32767); BEGIN v_PY := ''; n_len := length(p_String); FOR n_loop IN 1..n_len LOOP v_char := substr(p_string,n_loop,1); IF upper(v_char) IN ( 'A','B','C','D','E','F','G', 'H','I','J','K','L','M','N', 'O','P','Q','R','S','T', 'U','V','W','X','Y','Z', '0','1','2','3','4','5','6','7','8','9', '(', ')', '[', ']','.', '!', '@', '#', '$', '%', '^', '&', '*', '-', '+','<', '>', '?', ':', '"') THEN v_PY := v_PY||v_char; ELSE n_ascii := ascii(v_char); n_ord_high := trunc(n_ascii/256,0); n_ord_low := n_ascii-(n_ord_high*256); --DBMS_OUTPUT.PUT_LINE('n_ascii = '||to_char(n_ascii,'9999999')); --DBMS_OUTPUT.PUT_LINE('n_ord_high = '||to_char(n_ord_high,'9999999')); --DBMS_OUTPUT.PUT_LINE('n_ord_low = '||to_char(n_ord_low,'9999999')); IF (n_ord_high>128) and (n_ord_low>63) THEN CASE n_ord_high WHEN 162 THEN --???? IF n_ord_low>160 THEN v_PY := v_PY||get_roma_num_py(n_ord_low-160); END IF; WHEN 163 THEN --??ASCII IF n_ord_low>128 THEN v_char := chr(n_ord_low-128); IF upper(v_char) IN ( 'A','B','C','D','E','F','G', 'H','I','J','K','L','M','N', 'O','P','Q','R','S','T', 'U','V','W','X','Y','Z', '0','1','2','3','4','5','6','7','8','9', '(', ')', '[', ']') THEN v_PY := v_PY||v_char; END IF; END IF; WHEN 166 THEN --???? IF (n_ord_low>160) AND (n_ord_low<185) THEN --A1--B8 v_PY := v_PY||get_greece_alphabet_py(n_ord_low-160); ELSE IF (n_ord_low>192) AND (n_ord_low<217) THEN --C1--D8 v_PY := v_PY||get_greece_alphabet_py(n_ord_low-192); END IF; END IF; ELSE BEGIN n_temp := n_ord_high-128; n_ord_low := n_ord_low-63; n_temp1 := trunc(n_temp/10,0); n_temp1 := n_temp-n_temp1*10; IF n_temp1=0 THEN n_temp1 := 10; END IF; --DBMS_OUTPUT.PUT_LINE('n_temp = '||to_char(n_temp,'9999999')); --DBMS_OUTPUT.PUT_LINE('n_temp1 = '||to_char(n_temp1,'9999999')); CASE WHEN n_temp<11 THEN n_temp1 := get_py_index_01(n_temp1,n_ord_low); WHEN n_temp<21 THEN n_temp1 := get_py_index_02(n_temp1,n_ord_low); WHEN n_temp<31 THEN n_temp1 := get_py_index_03(n_temp1,n_ord_low); WHEN n_temp<41 THEN n_temp1 := get_py_index_04(n_temp1,n_ord_low); WHEN n_temp<51 THEN n_temp1 := get_py_index_05(n_temp1,n_ord_low); WHEN n_temp<61 THEN n_temp1 := get_py_index_06(n_temp1,n_ord_low); WHEN n_temp<71 THEN n_temp1 := get_py_index_07(n_temp1,n_ord_low); WHEN n_temp<81 THEN n_temp1 := get_py_index_08(n_temp1,n_ord_low); WHEN n_temp<91 THEN n_temp1 := get_py_index_09(n_temp1,n_ord_low); WHEN n_temp<101 THEN n_temp1 := get_py_index_10(n_temp1,n_ord_low); WHEN n_temp<111 THEN n_temp1 := get_py_index_11(n_temp1,n_ord_low); WHEN n_temp<121 THEN n_temp1 := get_py_index_12(n_temp1,n_ord_low); WHEN n_temp<121 THEN n_temp1 := get_py_index_13(n_temp1,n_ord_low); ELSE n_temp1 := 0; END CASE; v_PY := v_PY||substr(GetHzPY_by_index(n_temp1),1,1); END; END CASE; END IF; END IF; END LOOP; RETURN v_PY; --DBMS_OUTPUT.PUT_LINE(v_PY); END GetHzPYCAP; FUNCTION GetHzPYCAPLower(p_String varchar2) RETURN VARCHAR2 IS --declare --p_String varchar2(200) := '???????'; v_char varchar2(2); --???? n_loop number; --?? n_len number; --???? n_ascii number; --??ASCII? n_ord_high number; --n_ascii/156 n_ord_low number; --n mod 256 n_temp number; n_temp1 number; v_PY varchar2(32767); BEGIN v_PY := ''; n_len := length(p_String); FOR n_loop IN 1..n_len LOOP v_char := substr(p_string,n_loop,1); IF upper(v_char) IN ( 'A','B','C','D','E','F','G', 'H','I','J','K','L','M','N', 'O','P','Q','R','S','T', 'U','V','W','X','Y','Z', '0','1','2','3','4','5','6','7','8','9', '(', ')', '[', ']','.', '!', '@', '#', '$', '%', '^', '&', '*', '-', '+','<', '>', '?', ':', '"') THEN v_PY := v_PY||v_char; ELSE n_ascii := ascii(v_char); n_ord_high := trunc(n_ascii/256,0); n_ord_low := n_ascii-(n_ord_high*256); --DBMS_OUTPUT.PUT_LINE('n_ascii = '||to_char(n_ascii,'9999999')); --DBMS_OUTPUT.PUT_LINE('n_ord_high = '||to_char(n_ord_high,'9999999')); --DBMS_OUTPUT.PUT_LINE('n_ord_low = '||to_char(n_ord_low,'9999999')); IF (n_ord_high>128) and (n_ord_low>63) THEN CASE n_ord_high WHEN 162 THEN --???? IF n_ord_low>160 THEN v_PY := v_PY||get_roma_num_py(n_ord_low-160); END IF; WHEN 163 THEN --??ASCII IF n_ord_low>128 THEN v_char := chr(n_ord_low-128); IF upper(v_char) IN ( 'A','B','C','D','E','F','G', 'H','I','J','K','L','M','N', 'O','P','Q','R','S','T', 'U','V','W','X','Y','Z', '0','1','2','3','4','5','6','7','8','9', '(', ')', '[', ']') THEN v_PY := v_PY||v_char; END IF; END IF; WHEN 166 THEN --???? IF (n_ord_low>160) AND (n_ord_low<185) THEN --A1--B8 v_PY := v_PY||get_greece_alphabet_py(n_ord_low-160); ELSE IF (n_ord_low>192) AND (n_ord_low<217) THEN --C1--D8 v_PY := v_PY||get_greece_alphabet_py(n_ord_low-192); END IF; END IF; ELSE BEGIN n_temp := n_ord_high-128; n_ord_low := n_ord_low-63; n_temp1 := trunc(n_temp/10,0); n_temp1 := n_temp-n_temp1*10; IF n_temp1=0 THEN n_temp1 := 10; END IF; --DBMS_OUTPUT.PUT_LINE('n_temp = '||to_char(n_temp,'9999999')); --DBMS_OUTPUT.PUT_LINE('n_temp1 = '||to_char(n_temp1,'9999999')); CASE WHEN n_temp<11 THEN n_temp1 := get_py_index_01(n_temp1,n_ord_low); WHEN n_temp<21 THEN n_temp1 := get_py_index_02(n_temp1,n_ord_low); WHEN n_temp<31 THEN n_temp1 := get_py_index_03(n_temp1,n_ord_low); WHEN n_temp<41 THEN n_temp1 := get_py_index_04(n_temp1,n_ord_low); WHEN n_temp<51 THEN n_temp1 := get_py_index_05(n_temp1,n_ord_low); WHEN n_temp<61 THEN n_temp1 := get_py_index_06(n_temp1,n_ord_low); WHEN n_temp<71 THEN n_temp1 := get_py_index_07(n_temp1,n_ord_low); WHEN n_temp<81 THEN n_temp1 := get_py_index_08(n_temp1,n_ord_low); WHEN n_temp<91 THEN n_temp1 := get_py_index_09(n_temp1,n_ord_low); WHEN n_temp<101 THEN n_temp1 := get_py_index_10(n_temp1,n_ord_low); WHEN n_temp<111 THEN n_temp1 := get_py_index_11(n_temp1,n_ord_low); WHEN n_temp<121 THEN n_temp1 := get_py_index_12(n_temp1,n_ord_low); WHEN n_temp<121 THEN n_temp1 := get_py_index_13(n_temp1,n_ord_low); ELSE n_temp1 := 0; END CASE; v_PY := v_PY||substr(GetHzPY_by_index(n_temp1),1,1); END; END CASE; END IF; END IF; END LOOP; RETURN Lower(v_PY); --DBMS_OUTPUT.PUT_LINE(v_PY); END GetHzPYCAPLower; FUNCTION GetHzPYCAPsubstr(p_String varchar2,s float, e float) RETURN VARCHAR2 IS --declare --p_String varchar2(200) := '???????'; v_char varchar2(2); --???? n_loop number; --?? n_len number; --???? n_ascii number; --??ASCII? n_ord_high number; --n_ascii/156 n_ord_low number; --n mod 256 n_temp number; n_temp1 number; v_PY varchar2(32767); BEGIN v_PY := ''; n_len := length(p_String); FOR n_loop IN 1..n_len LOOP v_char := substr(p_string,n_loop,1); IF upper(v_char) IN ( 'A','B','C','D','E','F','G', 'H','I','J','K','L','M','N', 'O','P','Q','R','S','T', 'U','V','W','X','Y','Z', '0','1','2','3','4','5','6','7','8','9', '(', ')', '[', ']','.', '!', '@', '#', '$', '%', '^', '&', '*', '-', '+','<', '>', '?', ':', '"') THEN v_PY := v_PY||v_char; ELSE n_ascii := ascii(v_char); n_ord_high := trunc(n_ascii/256,0); n_ord_low := n_ascii-(n_ord_high*256); --DBMS_OUTPUT.PUT_LINE('n_ascii = '||to_char(n_ascii,'9999999')); --DBMS_OUTPUT.PUT_LINE('n_ord_high = '||to_char(n_ord_high,'9999999')); --DBMS_OUTPUT.PUT_LINE('n_ord_low = '||to_char(n_ord_low,'9999999')); IF (n_ord_high>128) and (n_ord_low>63) THEN CASE n_ord_high WHEN 162 THEN --???? IF n_ord_low>160 THEN v_PY := v_PY||get_roma_num_py(n_ord_low-160); END IF; WHEN 163 THEN --??ASCII IF n_ord_low>128 THEN v_char := chr(n_ord_low-128); IF upper(v_char) IN ( 'A','B','C','D','E','F','G', 'H','I','J','K','L','M','N', 'O','P','Q','R','S','T', 'U','V','W','X','Y','Z', '0','1','2','3','4','5','6','7','8','9', '(', ')', '[', ']') THEN v_PY := v_PY||v_char; END IF; END IF; WHEN 166 THEN --???? IF (n_ord_low>160) AND (n_ord_low<185) THEN --A1--B8 v_PY := v_PY||get_greece_alphabet_py(n_ord_low-160); ELSE IF (n_ord_low>192) AND (n_ord_low<217) THEN --C1--D8 v_PY := v_PY||get_greece_alphabet_py(n_ord_low-192); END IF; END IF; ELSE BEGIN n_temp := n_ord_high-128; n_ord_low := n_ord_low-63; n_temp1 := trunc(n_temp/10,0); n_temp1 := n_temp-n_temp1*10; IF n_temp1=0 THEN n_temp1 := 10; END IF; --DBMS_OUTPUT.PUT_LINE('n_temp = '||to_char(n_temp,'9999999')); --DBMS_OUTPUT.PUT_LINE('n_temp1 = '||to_char(n_temp1,'9999999')); CASE WHEN n_temp<11 THEN n_temp1 := get_py_index_01(n_temp1,n_ord_low); WHEN n_temp<21 THEN n_temp1 := get_py_index_02(n_temp1,n_ord_low); WHEN n_temp<31 THEN n_temp1 := get_py_index_03(n_temp1,n_ord_low); WHEN n_temp<41 THEN n_temp1 := get_py_index_04(n_temp1,n_ord_low); WHEN n_temp<51 THEN n_temp1 := get_py_index_05(n_temp1,n_ord_low); WHEN n_temp<61 THEN n_temp1 := get_py_index_06(n_temp1,n_ord_low); WHEN n_temp<71 THEN n_temp1 := get_py_index_07(n_temp1,n_ord_low); WHEN n_temp<81 THEN n_temp1 := get_py_index_08(n_temp1,n_ord_low); WHEN n_temp<91 THEN n_temp1 := get_py_index_09(n_temp1,n_ord_low); WHEN n_temp<101 THEN n_temp1 := get_py_index_10(n_temp1,n_ord_low); WHEN n_temp<111 THEN n_temp1 := get_py_index_11(n_temp1,n_ord_low); WHEN n_temp<121 THEN n_temp1 := get_py_index_12(n_temp1,n_ord_low); WHEN n_temp<121 THEN n_temp1 := get_py_index_13(n_temp1,n_ord_low); ELSE n_temp1 := 0; END CASE; v_PY := v_PY||substr(GetHzPY_by_index(n_temp1),1,1); END; END CASE; END IF; END IF; END LOOP; RETURN substr(v_PY,s,e); --DBMS_OUTPUT.PUT_LINE(v_PY); END GetHzPYCAPsubstr; FUNCTION F_TRANS_PINYIN_CAPITAL(P_NAME IN VARCHAR2) RETURN VARCHAR2 AS V_COMPARE VARCHAR2(100); V_RETURN VARCHAR2(4000); FUNCTION F_NLSSORT(P_WORD IN VARCHAR2) RETURN VARCHAR2 AS BEGIN RETURN NLSSORT(P_WORD, 'NLS_SORT=SCHINESE_PINYIN_M'); END; BEGIN V_COMPARE := F_NLSSORT(SUBSTR(P_NAME, 1, 1)); IF V_COMPARE >= F_NLSSORT(' 吖 ') AND V_COMPARE <= F_NLSSORT('驁 ') THEN V_RETURN := V_RETURN || 'A'; ELSIF V_COMPARE >= F_NLSSORT('八 ') AND V_COMPARE <= F_NLSSORT('簿 ') THEN V_RETURN := V_RETURN || 'B'; ELSIF V_COMPARE >= F_NLSSORT('嚓 ') AND V_COMPARE <= F_NLSSORT('錯 ') THEN V_RETURN := V_RETURN || 'C'; ELSIF V_COMPARE >= F_NLSSORT('咑 ') AND V_COMPARE <= F_NLSSORT('鵽 ') THEN V_RETURN := V_RETURN || 'D'; ELSIF V_COMPARE >= F_NLSSORT('妸 ') AND V_COMPARE <= F_NLSSORT('樲 ') THEN V_RETURN := V_RETURN || 'E'; ELSIF V_COMPARE >= F_NLSSORT('發 ') AND V_COMPARE <= F_NLSSORT('猤 ') THEN V_RETURN := V_RETURN || 'F'; ELSIF V_COMPARE >= F_NLSSORT('旮 ') AND V_COMPARE <= F_NLSSORT('腂 ') THEN V_RETURN := V_RETURN || 'G'; ELSIF V_COMPARE >= F_NLSSORT('妎 ') AND V_COMPARE <= F_NLSSORT('夻 ') THEN V_RETURN := V_RETURN || 'H'; ELSIF V_COMPARE >= F_NLSSORT('丌 ') AND V_COMPARE <= F_NLSSORT('攈 ') THEN V_RETURN := V_RETURN || 'J'; ELSIF V_COMPARE >= F_NLSSORT('咔 ') AND V_COMPARE <= F_NLSSORT('穒 ') THEN V_RETURN := V_RETURN || 'K'; ELSIF V_COMPARE >= F_NLSSORT('垃 ') AND V_COMPARE <= F_NLSSORT('擽 ') THEN V_RETURN := V_RETURN || 'L'; ELSIF V_COMPARE >= F_NLSSORT('嘸 ') AND V_COMPARE <= F_NLSSORT('椧 ') THEN V_RETURN := V_RETURN || 'M'; ELSIF V_COMPARE >= F_NLSSORT('拏 ') AND V_COMPARE <= F_NLSSORT('瘧 ') THEN V_RETURN := V_RETURN || 'N'; ELSIF V_COMPARE >= F_NLSSORT('筽 ') AND V_COMPARE <= F_NLSSORT('漚 ') THEN V_RETURN := V_RETURN || 'O'; ELSIF V_COMPARE >= F_NLSSORT('妑 ') AND V_COMPARE <= F_NLSSORT('曝 ') THEN V_RETURN := V_RETURN || 'P'; ELSIF V_COMPARE >= F_NLSSORT('七 ') AND V_COMPARE <= F_NLSSORT('裠 ') THEN V_RETURN := V_RETURN || 'Q'; ELSIF V_COMPARE >= F_NLSSORT('亽 ') AND V_COMPARE <= F_NLSSORT('鶸 ') THEN V_RETURN := V_RETURN || 'R'; ELSIF V_COMPARE >= F_NLSSORT('仨 ') AND V_COMPARE <= F_NLSSORT('蜶 ') THEN V_RETURN := V_RETURN || 'S'; ELSIF V_COMPARE >= F_NLSSORT('侤 ') AND V_COMPARE <= F_NLSSORT('籜 ') THEN V_RETURN := V_RETURN || 'T'; ELSIF V_COMPARE >= F_NLSSORT('屲 ') AND V_COMPARE <= F_NLSSORT('鶩 ') THEN V_RETURN := V_RETURN || 'W'; ELSIF V_COMPARE >= F_NLSSORT('夕 ') AND V_COMPARE <= F_NLSSORT('鑂 ') THEN V_RETURN := V_RETURN || 'X'; ELSIF V_COMPARE >= F_NLSSORT('丫 ') AND V_COMPARE <= F_NLSSORT('韻 ') THEN V_RETURN := V_RETURN || 'Y'; ELSIF V_COMPARE >= F_NLSSORT('帀 ') AND V_COMPARE <= F_NLSSORT('咗 ') THEN V_RETURN := V_RETURN || 'Z'; END IF; RETURN V_RETURN; END F_TRANS_PINYIN_CAPITAL; --begin -- Initialization --<Statement>; end; / create or replace PACKAGE PKG_FUNC AS --定義1970年1月1日8點時間常量 START_DATE CONSTANT DATE:=TO_DATE('1970-01-01 08:00:00','YYYY-MM-DD HH24:MI:SS'); --表類型 TYPE TYPE_STRLIST IS TABLE OF VARCHAR2(4000); --功能:將字符串按照指定分割字符分割成記錄集 FUNCTION SPLITSTR(pSTR IN VARCHAR2,pSEP IN VARCHAR2:=',') RETURN TYPE_STRLIST PIPELINED; --功能:時間日期轉換成距離1970-01-01的秒數 FUNCTION DATE_TO_SECOND(pDATE IN DATE) RETURN INT; --功能:距離1970-01-01的秒數轉換成時間日期 FUNCTION SECOND_TO_DATE(pSECOND IN INT) RETURN DATE; --功能:傳遞字符串參數,返回格式化替換後的時間日期參數 FUNCTION DATE_FORMAT(pDATE IN VARCHAR,pTYPE IN NUMBER) RETURN DATE; --功能:獲取兩個日期的差值(輸入爲字符串類型) FUNCTION DATEDIFF( Datepart In Varchar2, StartDate In Varchar2, EndDate In Varchar2 ) Return VARCHAR2; --功能:獲取兩個日期的差值(輸入爲日期類型) FUNCTION DATEDIFF( Datepart In Varchar2, StartDate In DATE, EndDate In DATE ) Return VARCHAR2; END; / create or replace PACKAGE BODY PKG_FUNC AS FUNCTION SPLITSTR --功能:將字符串按照指定分割字符分割成記錄集 --參數:pSTR-字符串,pSEP-指定分割字符,默認爲',' --調用:SELECT * FROM TABLE(PKG_FUNC.SPLITSTR('1,2,3,4,5,6,7,8,9,10',',')) --日期:2013-03-03 ( pSTR IN VARCHAR2, pSEP IN VARCHAR2:=',' ) RETURN TYPE_STRLIST PIPELINED IS L_IDX PLS_INTEGER; V_LIST VARCHAR2(4000):=pSTR; BEGIN LOOP L_IDX := INSTR(V_LIST,pSEP); IF L_IDX > 0 THEN PIPE ROW(SUBSTR(V_LIST,1,L_IDX-1)); V_LIST := SUBSTR(V_LIST,L_IDX+LENGTH(pSEP)); ELSE PIPE ROW(V_LIST); EXIT; END IF; END LOOP; RETURN; END; FUNCTION DATE_TO_SECOND --功能:時間日期轉換成距離1970-01-01的秒數 --參數:pDATE-日期格式參數 --調用:SELECT PKG_FUNC.DATE_TO_SECOND(SYSDATE) FROM DUAL; --日期:2013-03-03 ( pDATE IN DATE ) RETURN INT IS pSECOND INT; BEGIN SELECT TRUNC((pDATE-START_DATE)*86400) INTO pSECOND FROM DUAL; RETURN pSECOND; END; FUNCTION SECOND_TO_DATE --功能:距離1970-01-01的秒數轉換成時間日期 --參數:pDATE-傳遞日期格式參數 --調用:SELECT PKG_FUNC.SECOND_TO_DATE(1398733775) FROM DUAL; --日期:2013-02-17 ( pSECOND IN INT ) RETURN DATE IS pDATE DATE; BEGIN SELECT START_DATE+pSECOND/86400 INTO pDATE FROM DUAL; RETURN pDATE; END; FUNCTION DATE_FORMAT --功能:傳遞字符串參數,返回格式化替換後的時間日期參數 --參數:pDATE-字符串參數,pTYPE-不一樣類型進行相應處理 --調用:SELECT PKG_FUNC.DATE_FORMAT('',2) FROM DUAL --日期:2013-02-17 ( pDATE IN VARCHAR, pTYPE IN NUMBER --處理類別 0:時間可爲空 1:最小時間,2:最大時間,其它:系統當前時間 ) -------------------------------------------------------------------------------------- --0-返回的日期時間可爲空 --1-返回的日期時間不爲空,若傳入參數爲空,則轉換爲最小時間 --2-返回的日期時間不爲空,若傳入參數爲空,則轉換爲最大時間 --其它-返回的日期時間不爲空,若傳入參數爲空,則轉換爲系統當前時間 RETURN DATE IS RTN DATE; BEGIN SELECT DECODE(pTYPE,0,TO_DATE(TRIM(pDATE),'YYYY-MM-DD HH24:MI:SS'), 1,TO_DATE(NVL(TRIM(pDATE),'0001-01-01'),'YYYY-MM-DD HH24:MI:SS'), 2,TO_DATE(NVL(TRIM(pDATE),'9999-12-31'),'YYYY-MM-DD HH24:MI:SS'), NVL(TO_DATE(TRIM(pDATE),'YYYY-MM-DD HH24:MI:SS'),SYSDATE)) INTO RTN FROM DUAL; RETURN RTN; END; FUNCTION DATEDIFF --功能:獲取兩個日期的差值(輸入爲字符串類型) --參數:Datepart-返回間隔時間類型,StartDate-開始日期,EndDate-結束日期 --調用:SELECT PKG_FUNC.DATEDIFF('','2012-01-01','2010-01-01') FROM DUAL --日期:2017-03-04 ( Datepart In Varchar2, StartDate In Varchar2, EndDate In Varchar2 ) Return VARCHAR2 IS v_DAY VARCHAR2(200); v_HOUR VARCHAR2(200); v_MINUTE VARCHAR2(200); v_SECOND VARCHAR2(200); ReallyDo VARCHAR2(200); Begin SELECT EXTRACT( DAY FROM (TO_DATE(StartDate, 'YYYY-MM-DD HH24:MI:SS')- TO_DATE(EndDate, 'YYYY-MM-DD HH24:MI:SS')) DAY(9) TO SECOND ) INTO v_DAY FROM DUAL; SELECT EXTRACT( HOUR FROM (TO_DATE(StartDate, 'YYYY-MM-DD HH24:MI:SS')- TO_DATE(EndDate, 'YYYY-MM-DD HH24:MI:SS')) DAY(9) TO SECOND ) INTO v_HOUR FROM DUAL; SELECT EXTRACT( MINUTE FROM (TO_DATE(StartDate, 'YYYY-MM-DD HH24:MI:SS')- TO_DATE(EndDate, 'YYYY-MM-DD HH24:MI:SS')) DAY(9) TO SECOND ) INTO v_MINUTE FROM DUAL; SELECT EXTRACT( SECOND FROM (TO_DATE(StartDate, 'YYYY-MM-DD HH24:MI:SS')- TO_DATE(EndDate, 'YYYY-MM-DD HH24:MI:SS')) DAY(9) TO SECOND ) INTO v_SECOND FROM DUAL; ReallyDo:=v_DAY||'天'||v_HOUR||'小時'||v_MINUTE||'分'||v_SECOND||'秒'; SELECT DECODE(Datepart,'DAY',v_DAY,'D',v_DAY,'HOUR',v_HOUR,'H',v_HOUR,'MINUTE',v_MINUTE,'M',v_MINUTE,'SECOND',v_SECOND,'S',v_SECOND,ReallyDo) INTO ReallyDo FROM DUAL; Return ReallyDo; End; FUNCTION DATEDIFF --功能:獲取兩個日期的差值(輸入爲日期類型) --參數:Datepart-返回間隔時間類型,StartDate-開始日期,EndDate-結束日期 --調用:SELECT PKG_FUNC.DATEDIFF('','2012-01-01','2010-01-01') FROM DUAL --日期:2017-03-04 ( Datepart In Varchar2, StartDate In DATE, EndDate In DATE ) Return VARCHAR2 IS v_DAY VARCHAR2(200); v_HOUR VARCHAR2(200); v_MINUTE VARCHAR2(200); v_SECOND VARCHAR2(200); ReallyDo VARCHAR2(200); Begin SELECT EXTRACT( DAY FROM (StartDate-EndDate) DAY(9) TO SECOND ) INTO v_DAY FROM DUAL; SELECT EXTRACT( HOUR FROM (StartDate-EndDate) DAY(9) TO SECOND ) INTO v_HOUR FROM DUAL; SELECT EXTRACT( MINUTE FROM (StartDate-EndDate) DAY(9) TO SECOND ) INTO v_MINUTE FROM DUAL; SELECT EXTRACT( SECOND FROM (StartDate-EndDate) DAY(9) TO SECOND ) INTO v_SECOND FROM DUAL; ReallyDo:=v_DAY||'天'||v_HOUR||'小時'||v_MINUTE||'分'||v_SECOND||'秒'; SELECT DECODE(Datepart,'DAY',v_DAY,'D',v_DAY,'HOUR',v_HOUR,'H',v_HOUR,'MINUTE',v_MINUTE,'M',v_MINUTE,'SECOND',v_SECOND,'S',v_SECOND,ReallyDo) INTO ReallyDo FROM DUAL; Return ReallyDo; End; END; / CREATE OR REPLACE PACKAGE PKG_ANALYZE AS ----定義過濾的表差別數量的對象 TYPE CHETABLECOUNT IS RECORD ( TABLE_NAME VARCHAR2(40), DELETECOUNT NUMBER(10), INSERTCOUNT NUMBER(10), UPDATECOUNT NUMBER(10) ); --定義過濾的表差別數量集合類型 TYPE CHETABLECOUNTLIST IS TABLE OF CHETABLECOUNT; --獲取差別的表記錄數量集合 FUNCTION GET_TABLE_COUNT( pLINKNAME IN VARCHAR, --連接名 pCHECKTABLELIST IN CHECKTABLELIST --源過濾的表類型 ) RETURN CHETABLECOUNTLIST PIPELINED; --獲取差別的表記錄數量集合 PROCEDURE CHECK_MERGE_COUNT( pLINKNAME IN VARCHAR, --連接名 pCHECKTABLELIST IN CHECKTABLELIST, --源過濾的表類型 pCURSOR OUT SYS_REFCURSOR ); --功能:獲取當前的redo size日誌大小 FUNCTION NOW_REDO_SIZE RETURN NUMBER; --功能:開啓日誌分析,計算初始redo size大小 PROCEDURE START_REDO; --功能:計算生成的日誌大小 FUNCTION GET_REDO_SIZE RETURN NUMBER; --功能:查詢當前數據庫誰在運行什麼SQL語句 PROCEDURE SESSION_RUN_SQL(pCURSOR OUT SYS_REFCURSOR); --功能:查詢使用CPU多的用戶SESSION PROCEDURE SESSION_CPU_COST(pCURSOR OUT SYS_REFCURSOR); --功能:查詢影響性能的SQL語句 PROCEDURE SQL_IO_COST(pCURSOR OUT SYS_REFCURSOR); --功能:分析存儲過程、函數(或者包中的存儲過程、函數)參數信息 PROCEDURE GET_ARGUMENTS( DBUSER IN VARCHAR2:=USER, pPACKAGENAME IN VARCHAR2:=NULL, pOBJNAME IN VARCHAR2:=NULL, pCURSOR OUT SYS_REFCURSOR ); --功能:統計分析用戶下的單表/索引或者全庫表/索引,爲NULL則分析全庫表/索引,多個對象以','分隔 PROCEDURE ANALYZE_TABLEANDINDEX(DBUSER IN VARCHAR2:=USER,pOBJNAME IN VARCHAR2:=NULL); --功能:分析數據庫中單表或全部表產生行遷移和行鏈接的記錄,爲NULL則分析全庫表,多個表以','分隔 PROCEDURE ANALYZE_CHAINED_ROWS(DBUSER IN VARCHAR2:=USER,pOBJNAME IN VARCHAR2:=NULL); --功能:查詢錶行數、索引塊大小、數據塊大小佔用狀況,爲NULL則查詢全庫表,多個表以','分隔,數據塊包含表、分區表、LOB段空間,索引塊包含普通索引、分區索引、LOB段索引 PROCEDURE TABLE_ROWSANDSPACE( DBUSER IN VARCHAR2:=USER, pOBJNAME IN VARCHAR2:=NULL, pCURSOR OUT SYS_REFCURSOR ); PROCEDURE VIEW_COUNT( DBUSER IN VARCHAR2:=USER, pTBNAME IN VARCHAR2:=NULL, pCURSOR OUT SYS_REFCURSOR ); --功能:檢測設計後的錶行總長度是否超過當前所在的表空間最小單元數據塊大小(若超過,可能產生行鏈接),爲NULL則查詢全庫表,多個表以','分隔 PROCEDURE ROW_CHARLENGTH( DBUSER IN VARCHAR2:=USER, pOBJNAME IN VARCHAR2:=NULL, pCURSOR OUT SYS_REFCURSOR ); --功能:檢測哪些表中的列名稱採用系統關鍵字(可能引發沒必要要的錯誤,如Ora-01747:user.table.column,tabel.coulmn或列說明無效) PROCEDURE CHECK_COLNAMEISKEYWORD(DBUSER IN VARCHAR2:=USER,pCURSOR OUT SYS_REFCURSOR); --功能:檢測數據庫中外鍵上未創建索引的狀況 PROCEDURE CHECK_FOREIGNINDEX(DBUSER IN VARCHAR2:=USER,pCURSOR OUT SYS_REFCURSOR); --功能:檢測數據庫中外鍵依賴列的類型、長度、小數位與主鍵列不一致的狀況,這可能在其餘數據庫(如SQL SERVER)中因爲嚴格限制沒法創建外鍵關聯 PROCEDURE CHECK_KEYRELATIONTYPE(DBUSER IN VARCHAR2:=USER,pCURSOR OUT SYS_REFCURSOR); --功能:檢測數據庫中未創建主鍵或者惟一約束的狀況 PROCEDURE CHECK_NOPRIMARY(DBUSER IN VARCHAR:=USER,pCURSOR OUT SYS_REFCURSOR); --功能:返回查詢目標庫與連接源庫表的差別或相同部分的SQL語句 PROCEDURE GET_COMPARETEXT( pTAG IN NUMBER, --查詢模式:1-求同(交集),2-求異(補集) pLINKNAME IN VARCHAR, --連接名 pTABLENAME IN VARCHAR2:=NULL, --源表,能夠爲一張或多張表,多個表以','分隔,爲空則選擇全部表 pMODE IN NUMBER:=1, --匹配模式 pSELTEXT OUT VARCHAR2 ); --功能:查詢目標庫與源庫表的差別部分(若是目標表中存在主鍵相同記錄,則同步類型爲'UPDATE',不存在則同步類型爲'INSERT',目標表中存在而源表中不存在則同步類型爲'DELETE') PROCEDURE CHECK_MERGE_MINUS( pSOURCETB IN VARCHAR, --源表名,若是爲遠程連接表,相似爲LINKNAME@TABLENAME的格式,如:DATABASE_LINK1@USR_INFOTAB pTARGETTB IN VARCHAR2, --目標表名 pFILTER IN VARCHAR2:=NULL, --條件過濾 pCURSOR OUT SYS_REFCURSOR ); --功能:查詢目標庫與連接源庫表的差別部分(求補集) PROCEDURE CHECK_MINUS( pLINKNAME IN VARCHAR, --連接名 pTABLENAME IN VARCHAR2:=NULL, --源表,能夠爲一張或多張表,多個表以','分隔,爲空則選擇全部表 pMODE IN NUMBER:=1, --匹配模式 pCURSOR OUT SYS_REFCURSOR --返回連接庫中有而目標庫中沒有的部分 ); --功能:查詢目標庫與連接源庫表的相同部分(求交集) PROCEDURE CHECK_INTERSECT( pLINKNAME IN VARCHAR, --連接名 pTABLENAME IN VARCHAR2:=NULL, --源表,能夠爲一張或多張表,多個表以','分隔,爲空則選擇全部表 pMODE IN NUMBER:=1, --匹配模式 pCURSOR OUT SYS_REFCURSOR --返回連接庫、目標庫中共有的部分 ); --功能:查詢對比目標庫與連接源庫表數據對比具備相同列數據的部分(如查詢重複列數據) PROCEDURE CHECK_DISTINCT( pLINKNAME IN VARCHAR, --連接名 pTABLENAME IN VARCHAR2, --表名 pCOLNAME IN VARCHAR2, --匹配列名,多個列以逗號分隔 pCURSOR OUT SYS_REFCURSOR --返回連接庫、目標庫中共有的部分 ); END; / create or replace PACKAGE BODY PKG_ANALYZE AS LAST_REDOSIZE NUMBER:=NULL; FUNCTION NOW_REDO_SIZE --功能:獲取當前的redo size日誌大小 --參數: --調用: --日期:2014-07-10 RETURN NUMBER IS REDOSIZE NUMBER; BEGIN SELECT "VALUE" INTO REDOSIZE FROM V$STATNAME A,V$MYSTAT B WHERE A.STATISTIC#=B.STATISTIC# AND A.NAME='redo size'; RETURN REDOSIZE; END; PROCEDURE START_REDO --功能:開啓日誌分析,計算初始redo size大小 --參數: --調用: --日期:2014-07-10 AS BEGIN SELECT NOW_REDO_SIZE INTO LAST_REDOSIZE FROM DUAL; END; FUNCTION GET_REDO_SIZE --功能:計算生成的日誌大小 --參數: --調用: --日期:2014-07-10 RETURN NUMBER IS END_REDOSIZE NUMBER; BEGIN SELECT NOW_REDO_SIZE INTO END_REDOSIZE FROM DUAL; RETURN END_REDOSIZE-LAST_REDOSIZE; END; PROCEDURE SESSION_RUN_SQL --功能:查詢當前數據庫誰在運行什麼SQL語句 --參數:pCURSOR-返回數據集 --調用: /* DECLARE pCURSOR SYS_REFCURSOR; BEGIN PKG_ANALYZE.SESSION_RUN_SQL(pCURSOR); END; */ --日期:2013-03-11 ( pCURSOR OUT SYS_REFCURSOR ) AS BEGIN OPEN pCURSOR FOR SELECT DISTINCT SID,SERIAL#,USERNAME,machine,TERMINAL,module,PROGRAM,PROCESS,STATUS, EVENT,SERVICE_NAME,logon_time,SQL_EXEC_START,PREV_EXEC_START,SQL_TEXT FROM( SELECT SID,SERIAL#,USERNAME,a.machine,TERMINAL,a.module,PROGRAM,PROCESS,STATUS,EVENT,SERVICE_NAME,a.logon_time, SQL_EXEC_START,PREV_EXEC_START,LISTAGG(SQL_TEXT,'') WITHIN GROUP(ORDER BY PIECE) OVER(PARTITION BY SID) AS SQL_TEXT FROM v$session a, v$sqltext b WHERE a.sql_address =b.address ORDER BY address, piece ); END; PROCEDURE SESSION_CPU_COST --功能:查詢使用CPU多的用戶SESSION --參數:pCURSOR-返回數據集 --調用: /* DECLARE pCURSOR SYS_REFCURSOR; BEGIN PKG_ANALYZE.SESSION_CPU_COST(pCURSOR); END; */ --日期:2013-03-11 ( pCURSOR OUT SYS_REFCURSOR ) AS BEGIN OPEN pCURSOR FOR SELECT a.sid,spid,status,substr(a.program,1,40) prog,a.terminal,osuser,value/60/100 VALUE FROM v$session a,v$process b,v$sesstat c WHERE c.statistic#=11 AND c.sid=a.sid AND a.paddr=b.addr ORDER BY VALUE DESC; END; PROCEDURE SQL_IO_COST --功能:查詢影響性能的SQL語句 --參數:pCURSOR-返回數據集 --調用: /* DECLARE pCURSOR SYS_REFCURSOR; BEGIN PKG_ANALYZE.SQL_IO_COST(pCURSOR); END; */ --日期:2013-03-11 ( pCURSOR OUT SYS_REFCURSOR ) AS BEGIN OPEN pCURSOR FOR SELECT SQL_ID,MODULE,SORTS,LOADS,FIRST_LOAD_TIME,LAST_LOAD_TIME,DISK_READS,CPU_TIME,BUFFER_GETS,executions, CASE executions WHEN 0 THEN 0 ELSE buffer_gets/executions END AS "GETS/EXEC",hash_value,address,SQL_TEXT,SQL_FULLTEXT FROM V$SQLAREA ORDER BY BUFFER_GETS DESC; END; PROCEDURE GET_ARGUMENTS --功能:分析存儲過程、函數(或者包中的存儲過程、函數)參數信息 --參數:DBUSER-數據庫用戶,pOBJNAME-表/索引名稱,爲NULL則分析全庫表/索引,多個對象以','分隔 --調用: /* DECLARE pCURSOR SYS_REFCURSOR; BEGIN PKG_ANALYZE.GET_ARGUMENTS('DKGLL','','USR_INFOTAB',pCURSOR); END; */ --日期:2013-03-5 ( DBUSER IN VARCHAR2:=USER, pPACKAGENAME IN VARCHAR2:=NULL, pOBJNAME IN VARCHAR2:=NULL, pCURSOR OUT SYS_REFCURSOR ) AS BEGIN OPEN pCURSOR FOR SELECT OWNER,PACKAGE_NAME, CASE MIN(POSITION) OVER(PARTITION BY OBJECT_NAME) WHEN 0 THEN 'FUNCTION' ELSE 'PROCEDURE' END OBJECT_TYPE, OBJECT_NAME,ARGUMENT_NAME,OVERLOAD,IN_OUT,DATA_TYPE FROM DBA_ARGUMENTS WHERE OWNER=NVL(DBUSER,OWNER) AND PACKAGE_NAME=NVL(pPACKAGENAME,PACKAGE_NAME) AND OBJECT_NAME=NVL(pOBJNAME,OBJECT_NAME) ORDER BY OWNER,SUBPROGRAM_ID,POSITION; END; PROCEDURE ANALYZE_TABLEANDINDEX --功能:統計分析用戶下的單表/索引或者全庫表/索引 --參數:DBUSER-數據庫用戶,pOBJNAME-表/索引名稱,爲NULL則分析全庫表/索引,多個對象以','分隔 --調用:EXECUTE PKG_ANALYZE.ANALYZE_TABLEANDINDEX('DKGLL','USR_INFOTAB'); --日期:2013-03-5 ( DBUSER IN VARCHAR2:=USER, pOBJNAME IN VARCHAR2:=NULL ) AS pUSER VARCHAR2(200):=COALESCE(UPPER(DBUSER),USER); BEGIN --分析全部表 FOR CUR_ITEM IN ( SELECT TABLE_NAME FROM SYS.DBA_TABLES WHERE OWNER=pUSER AND(INSTR(','||pOBJNAME||',',','||TABLE_NAME||',',1)>0 OR pOBJNAME IS NULL) ) LOOP BEGIN EXECUTE IMMEDIATE 'ANALYZE TABLE "'||pUSER||'"."'||CUR_ITEM.TABLE_NAME||'" COMPUTE STATISTICS'; EXCEPTION WHEN OTHERS THEN SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'分析表異常:' ||SQLERRM); END; END LOOP; --分析全部索引 FOR CUR_ITEM IN ( SELECT INDEX_NAME FROM SYS.DBA_INDEXES WHERE OWNER=pUSER AND(INSTR(','||pOBJNAME||',',','||TABLE_NAME||',',1)>0 OR pOBJNAME IS NULL) ) LOOP BEGIN EXECUTE IMMEDIATE 'ANALYZE INDEX "'||pUSER||'"."'||CUR_ITEM.INDEX_NAME||'" ESTIMATE STATISTICS'; EXCEPTION WHEN OTHERS THEN SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'分析索引異常:' ||SQLERRM); END; END LOOP; COMMIT; END; PROCEDURE ANALYZE_CHAINED_ROWS --功能:分析數據庫中單表或全部表產生行遷移和行鏈接的記錄,用戶需具有在存儲過程當中動態建表的權限 --參數:DBUSER-數據庫用戶,pOBJNAME-表名稱,爲NULL則分析全庫表,多個表以','分隔 --調用:EXECUTE PKG_ANALYZE.ANALYZE_CHAINED_ROWS('DKGLL','USR_INFOTAB'); --日期:2013-03-5 ( DBUSER IN VARCHAR2:=USER, pOBJNAME IN VARCHAR2:=NULL ) AS pUSER VARCHAR2(200):=COALESCE(UPPER(DBUSER),USER); pCOUNT NUMBER; pSQL VARCHAR2(300); BEGIN SELECT COUNT(1) INTO pCOUNT FROM SYS.DBA_TABLES WHERE OWNER=pUSER AND TABLE_NAME='CHAINED_ROWS'; IF pCOUNT=0 THEN --行遷移分析表不存在則建立行遷移分析表 pSQL:='CREATE TABLE "'||pUSER||'"."CHAINED_ROWS" ('||CHR(10)|| 'owner_name VARCHAR2(30),'||CHR(10)|| 'table_name VARCHAR2(30),'||CHR(10)|| 'cluster_name VARCHAR2(30),'||CHR(10)|| 'partition_name VARCHAR2(30),'||CHR(10)|| 'subpartition_name VARCHAR2(30),'||CHR(10)|| 'head_rowid ROWID,'||CHR(10)|| 'analyze_timestamp DATE'||CHR(10)|| ')'; ELSE pSQL:='DELETE FROM "'||pUSER||'"."CHAINED_ROWS"'; END IF; EXECUTE IMMEDIATE pSQL; --刪除上次分析後的數據 --分析全部表 FOR CUR_ITEM IN ( SELECT TABLE_NAME FROM SYS.DBA_TABLES WHERE OWNER=pUSER AND (INSTR(','||pOBJNAME||',',','||TABLE_NAME||',',1)>0 OR pOBJNAME IS NULL) ) LOOP EXECUTE IMMEDIATE 'ANALYZE TABLE "'||pUSER||'"."'||CUR_ITEM.TABLE_NAME||'" LIST CHAINED ROWS INTO CHAINED_ROWS'; END LOOP; COMMIT; EXCEPTION WHEN OTHERS THEN SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'執行錯誤:' ||SQLERRM); END; PROCEDURE TABLE_ROWSANDSPACE --功能:查詢錶行數、索引塊大小、數據塊大小佔用狀況,數據塊包含表、分區表、LOB段空間,索引塊包含普通索引、分區索引、LOB段索引 --參數:DBUSER-數據庫用戶,pOBJNAME-表名稱,爲NULL則查詢全庫表,多個表以','分隔,pCURSOR-返回數據集 --調用: /* DECLARE pCURSOR SYS_REFCURSOR; BEGIN PKG_ANALYZE.TABLE_ROWSANDSPACE('DKGLL','USR_INFOTAB',pCURSOR); END; */ --日期:2013-03-8 ( DBUSER IN VARCHAR2:=USER, pOBJNAME IN VARCHAR2:=NULL, pCURSOR OUT SYS_REFCURSOR ) AS pUSER VARCHAR2(200):=COALESCE(UPPER(DBUSER),USER); BEGIN OPEN pCURSOR FOR SELECT DISTINCT TA.TABLE_NAME AS "表名",TA.NUM_ROWS AS "行數", CASE WHEN TB.INDEXUSE IS NULL THEN TA.TABLEUSE/1048576 ELSE(TB.INDEXUSE+TA.TABLEUSE)/1048576 END AS "總佔用(MB)", TA.TABLEUSE/1048576 AS "數據塊佔用(MB)", CASE WHEN TB.INDEXUSE IS NULL THEN 0 ELSE TB.INDEXUSE/1048576 END AS "索引塊佔用(MB)" FROM ( SELECT OWNER,TABLE_NAME,SEGMENT_TYPE,NUM_ROWS,SUM(BYTES) OVER(PARTITION BY OWNER,TABLE_NAME,SEGMENT_TYPE) AS TABLEUSE FROM ( SELECT A.OWNER,A.TABLE_NAME,'TABLE' AS SEGMENT_TYPE,A.NUM_ROWS, CASE WHEN B.BYTES IS NULL THEN 0 ELSE B.BYTES END AS BYTES FROM SYS.DBA_TABLES A LEFT JOIN SYS.DBA_SEGMENTS B ON(A.OWNER=B.OWNER AND A.TABLE_NAME=B.SEGMENT_NAME) WHERE A.OWNER=pUSER ) ) TA LEFT JOIN (SELECT OWNER,TABLE_NAME,SEGMENT_TYPE,SUM(BYTES) OVER(PARTITION BY OWNER,TABLE_NAME,SEGMENT_TYPE) AS INDEXUSE FROM (SELECT C.OWNER,C.TABLE_NAME,'INDEX' AS SEGMENT_TYPE,CASE WHEN D.BYTES IS NULL THEN 0 ELSE D.BYTES END AS BYTES FROM SYS.DBA_INDEXES C LEFT JOIN SYS.DBA_SEGMENTS D ON(C.OWNER=D.OWNER AND C.INDEX_NAME=D.SEGMENT_NAME) WHERE C.OWNER=pUSER ) ) TB ON(TA.OWNER=TB.OWNER AND TA.TABLE_NAME=TB.TABLE_NAME) WHERE(INSTR(','||pOBJNAME||',',','||TA.TABLE_NAME||',',1)>0 OR pOBJNAME IS NULL) ORDER BY "行數" DESC,"總佔用(MB)" DESC,"數據塊佔用(MB)" DESC,"索引塊佔用(MB)" DESC; END; PROCEDURE VIEW_COUNT --功能:檢測系統視圖、如DBA,ALL,USER,動態性能視圖數據行數 --參數:DBUSER-數據庫用戶,pTBNAME-視圖名稱,模糊匹配,爲NULL則分析全部視圖,pCURSOR-返回數據集 --調用: /* DECLARE pCURSOR SYS_REFCURSOR; BEGIN PKG_ANALYZE.VIEW_COUNT('DKGLL',NULL,pCURSOR); END; */ --日期:2014-12-9 ( DBUSER IN VARCHAR2:=USER, pTBNAME IN VARCHAR2:=NULL, pCURSOR OUT SYS_REFCURSOR ) AS pUSER VARCHAR2(200):=COALESCE(UPPER(DBUSER),USER); pSQL VARCHAR2(200); pCOUNT NUMBER; PROCEDURE ADD_TB_COUNT ( pOWNER IN VARCHAR2, pTBNAME IN VARCHAR2 ) AS pSQL1 VARCHAR2(200); BEGIN pSQL1:='INSERT INTO V$TABLE_COUNT SELECT '''||pOWNER||''','''||pTBNAME||''',COUNT(1) FROM '||pTBNAME; EXECUTE IMMEDIATE pSQL1; EXCEPTION WHEN OTHERS THEN SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'獲取視圖'||pTBNAME||'行數出錯:' ||SQLERRM); END; BEGIN SELECT COUNT(1) INTO pCOUNT FROM SYS.DBA_TABLES WHERE OWNER=pUSER AND TABLE_NAME='V$TABLE_COUNT'; IF pCOUNT=0 THEN pSQL:='CREATE TABLE "'||pUSER||'"."V$TABLE_COUNT" ('||CHR(10)|| 'owner_name VARCHAR2(30),'||CHR(10)|| 'table_name VARCHAR2(30),'||CHR(10)|| 'rowcount number'||CHR(10)|| ')'; ELSE pSQL:='DELETE FROM "'||pUSER||'"."V$TABLE_COUNT"'; END IF; EXECUTE IMMEDIATE pSQL; --刪除上次分析後的數據 FOR X IN ( SELECT OWNER,SYNONYM_NAME FROM DBA_SYNONYMS WHERE SYNONYM_NAME LIKE pTBNAME||'%' OR pTBNAME IS NULL ) LOOP ADD_TB_COUNT(X.OWNER,X.SYNONYM_NAME); END LOOP; COMMIT; EXCEPTION WHEN OTHERS THEN SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'查詢動態視圖出錯:' ||SQLERRM); END; PROCEDURE ROW_CHARLENGTH --功能:檢測設計後的錶行總長度是否超過當前所在的表空間最小單元數據塊大小(若超過,可能產生行鏈接) --參數:DBUSER-數據庫用戶,pOBJNAME-表名稱,爲NULL則分析全庫表,pCURSOR-返回數據集 --調用: /* DECLARE pCURSOR SYS_REFCURSOR; BEGIN PKG_ANALYZE.ROW_CHARLENGTH('DKGLL','USR_INFOTAB',pCURSOR); END; */ --日期:2013-03-8 ( DBUSER IN VARCHAR2:=USER, pOBJNAME IN VARCHAR2:=NULL, pCURSOR OUT SYS_REFCURSOR ) AS pUSER VARCHAR2(200):=COALESCE(UPPER(DBUSER),USER); BEGIN OPEN pCURSOR FOR SELECT TA.TABLESPACE_NAME AS "表空間名稱",TABLE_NAME AS "表名",TOTALLENGTH AS "行總長度(字節)", CASE WHEN TB.BLOCK_SIZE IS NULL THEN 8191 ELSE TB.BLOCK_SIZE END AS "單元數據塊大小(字節)", CASE WHEN TOTALLENGTH-(CASE WHEN TB.BLOCK_SIZE IS NULL THEN 8191 ELSE TB.BLOCK_SIZE END)>0 THEN 'YES' ELSE 'NO' END AS "是否超出數據塊大小" FROM( SELECT TABLESPACE_NAME,TABLE_NAME,SUM(DECODE(CHAR_LENGTH,0,NVL(DATA_PRECISION,MAXCHARLEN),CHAR_LENGTH)) AS TOTALLENGTH FROM( SELECT A.TABLESPACE_NAME,A.TABLE_NAME,CASE DATA_TYPE WHEN 'NUMBER' THEN 38 WHEN 'DECIMAL' THEN 38 WHEN 'NUMERIC' THEN 38 WHEN 'FLOAT' THEN 126 WHEN 'INT' THEN 11 WHEN 'INTEGER' THEN 11 WHEN 'PLS_INTEGER' THEN 11 WHEN 'SMALLINT' THEN 5 WHEN 'BIGINT' THEN 20 WHEN 'TINYINT' THEN 3 WHEN 'DATE' THEN 7 WHEN 'TIMESTAMP(6)' THEN 11 ELSE 0 END AS MAXCHARLEN, B.DATA_PRECISION, B.CHAR_LENGTH FROM SYS.DBA_TABLES A JOIN SYS.DBA_TAB_COLUMNS B ON A.OWNER=B.OWNER AND A.OWNER=pUSER AND A.TABLE_NAME=B.TABLE_NAME ) GROUP BY TABLESPACE_NAME,TABLE_NAME ) TA LEFT JOIN SYS.DBA_TABLESPACES TB ON TA.TABLESPACE_NAME=TB.TABLESPACE_NAME WHERE (INSTR(','||pOBJNAME||',',','||TABLE_NAME||',',1)>0 OR pOBJNAME IS NULL) ORDER BY TOTALLENGTH DESC,TABLE_NAME; END; PROCEDURE CHECK_COLNAMEISKEYWORD --功能:檢測哪些表中的列名稱採用系統關鍵字(可能引發沒必要要的錯誤) --參數:DBUSER-數據庫用戶,pCURSOR-返回採用關鍵字的表、列 --調用: /* DECLARE pCURSOR SYS_REFCURSOR; BEGIN PKG_ANALYZE.CHECK_COLNAMEISKEYWORD('DKGLL',pCURSOR); END; */ --日期:2013-03-11 ( DBUSER IN VARCHAR2:=USER, pCURSOR OUT SYS_REFCURSOR ) AS pUSER VARCHAR2(200):=COALESCE(UPPER(DBUSER),USER); BEGIN OPEN pCURSOR FOR SELECT A.OWNER,A.TABLE_NAME,B.COLUMN_NAME FROM SYS.DBA_TABLES A JOIN SYS.DBA_TAB_COLUMNS B ON (A.TABLE_NAME=B.TABLE_NAME AND A.OWNER=B.OWNER) JOIN v$reserved_words C ON B.COLUMN_NAME=C.KEYWORD WHERE A.OWNER=pUSER ORDER BY A.TABLE_NAME,B.COLUMN_ID; END; PROCEDURE CHECK_FOREIGNINDEX --功能:檢測數據庫中外鍵上未創建索引的狀況 --參數:DBUSER-數據庫用戶,pCURSOR-返回數據庫中外鍵上未創建索引的表、列記錄 --調用: /* DECLARE pCURSOR SYS_REFCURSOR; BEGIN PKG_ANALYZE.CHECK_FOREIGNINDEX('DKGLL',pCURSOR); END; */ --日期:2013-03-8 ( DBUSER IN VARCHAR2:=USER, pCURSOR OUT SYS_REFCURSOR ) AS pUSER VARCHAR2(200):=COALESCE(UPPER(DBUSER),USER); BEGIN OPEN pCURSOR FOR SELECT TABLE_NAME,COLUMNLIST FROM( SELECT A.TABLE_NAME,A.CONSTRAINT_NAME, LISTAGG(B.COLUMN_NAME,',') WITHIN GROUP(ORDER BY B.COLUMN_NAME) OVER(PARTITION BY A.TABLE_NAME,A.CONSTRAINT_NAME) AS COLUMNLIST FROM SYS.DBA_CONSTRAINTS A JOIN SYS.DBA_CONS_COLUMNS B ON (A.OWNER=B.OWNER AND A.TABLE_NAME=B.TABLE_NAME AND A.CONSTRAINT_NAME=B.CONSTRAINT_NAME AND A.CONSTRAINT_TYPE='R' AND A.OWNER=pUSER ) ) TA MINUS SELECT TABLE_NAME,COLUMNLIST FROM( SELECT DISTINCT A.TABLE_NAME,A.INDEX_NAME, LISTAGG(B.COLUMN_NAME,',') WITHIN GROUP(ORDER BY B.COLUMN_POSITION) OVER(PARTITION BY A.TABLE_NAME,A.INDEX_NAME) AS COLUMNLIST FROM SYS.DBA_INDEXES A JOIN SYS.DBA_IND_COLUMNS B ON (A.TABLE_OWNER=B.TABLE_OWNER AND A.TABLE_NAME=B.TABLE_NAME AND A.INDEX_NAME=B.INDEX_NAME AND A.INDEX_TYPE='NORMAL' AND A.TABLE_OWNER=pUSER ) ); END; PROCEDURE CHECK_KEYRELATIONTYPE --功能:檢測數據庫中外鍵依賴列的類型、長度、小數位與主鍵列不一致的狀況,這可能在其餘數據庫(如SQL SERVER)中因爲嚴格限制沒法創建外鍵關聯 --參數:DBUSER-數據庫用戶,pCURSOR-返回數據庫中未創建主鍵或者惟一約束的表 --調用: /* DECLARE pCURSOR SYS_REFCURSOR; BEGIN PKG_ANALYZE.CHECK_KEYRELATIONTYPE('DKGLL',pCURSOR); END; */ --日期:2013-02-10 ( DBUSER IN VARCHAR2:=USER, pCURSOR OUT SYS_REFCURSOR ) AS pUSER VARCHAR2(200):=COALESCE(UPPER(DBUSER),USER); BEGIN OPEN pCURSOR FOR SELECT * FROM( SELECT DISTINCT A.CONSTRAINT_NAME,A.TABLE_NAME,B.COLUMN_NAME, CASE B1.DATA_TYPE WHEN 'NUMBER' THEN REPLACE(B1.DATA_TYPE||'('||NVL(TO_CHAR(B1.DATA_PRECISION),'*') ||','||NVL(TO_CHAR(B1.DATA_SCALE),'*') ||')','(*,*)','') WHEN 'VARCHAR2' THEN B1.DATA_TYPE||'('||B1.CHAR_LENGTH||')' ELSE B1.DATA_TYPE END AS DATA_TYPE, C.TABLE_NAME AS R_TABLE_NAME,D.COLUMN_NAME AS R_COLUMN_NAME, CASE D1.DATA_TYPE WHEN 'NUMBER' THEN REPLACE(D1.DATA_TYPE||'('||NVL(TO_CHAR(D1.DATA_PRECISION),'*') ||','||NVL(TO_CHAR(D1.DATA_SCALE),'*') ||')','(*,*)','') WHEN 'VARCHAR2' THEN D1.DATA_TYPE||'('||D1.CHAR_LENGTH||')' ELSE D1.DATA_TYPE END AS R_DATA_TYPE, A.DELETE_RULE FROM SYS.DBA_CONSTRAINTS A JOIN SYS.DBA_CONS_COLUMNS B ON(A.OWNER=B.OWNER AND A.CONSTRAINT_NAME=B.CONSTRAINT_NAME AND A.TABLE_NAME=B.TABLE_NAME) JOIN SYS.DBA_TAB_COLUMNS B1 ON(B1.OWNER=B.OWNER AND B1.TABLE_NAME=B.TABLE_NAME AND B1.COLUMN_NAME=B.COLUMN_NAME) JOIN SYS.DBA_CONSTRAINTS C ON(A.R_OWNER=C.OWNER AND A.R_CONSTRAINT_NAME=C.CONSTRAINT_NAME) JOIN SYS.DBA_CONS_COLUMNS D ON(D.OWNER=C.OWNER AND D.CONSTRAINT_NAME=C.CONSTRAINT_NAME AND D.TABLE_NAME=C.TABLE_NAME AND D.POSITION=B.POSITION) JOIN SYS.DBA_TAB_COLUMNS D1 ON(D1.OWNER=D.OWNER AND D1.TABLE_NAME=D.TABLE_NAME AND D1.COLUMN_NAME=D.COLUMN_NAME) WHERE A.OWNER=pUSER AND A.TABLE_NAME NOT LIKE 'BIN$%' AND C.TABLE_NAME NOT LIKE 'BIN$%' AND A.CONSTRAINT_TYPE='R' AND C.CONSTRAINT_TYPE='P' ) WHERE DATA_TYPE<>R_DATA_TYPE; END; PROCEDURE CHECK_NOPRIMARY --功能:檢測數據庫中未創建主鍵或者惟一約束的狀況 --參數:DBUSER-數據庫用戶,pCURSOR-返回數據庫中未創建主鍵或者惟一約束的表 --調用: /* DECLARE pCURSOR SYS_REFCURSOR; BEGIN PKG_ANALYZE.CHECK_NOPRIMARY('DKGLL',pCURSOR); END; */ --日期:2013-02-10 ( DBUSER IN VARCHAR:=USER, pCURSOR OUT SYS_REFCURSOR ) AS pUSER VARCHAR2(200):=COALESCE(UPPER(DBUSER),USER); BEGIN OPEN pCURSOR FOR SELECT * FROM SYS.DBA_TABLES A WHERE A.OWNER=pUSER AND NOT EXISTS( SELECT * FROM SYS.DBA_CONSTRAINTS B WHERE B.OWNER=pUSER AND B.CONSTRAINT_TYPE IN('P','U') AND B.TABLE_NAME=A.TABLE_NAME ) AND A.TEMPORARY='N' ORDER BY A.TABLE_NAME; END; PROCEDURE GET_COMPARETEXT --功能:返回查詢目標庫與連接源庫表的差別或相同部分的SQL語句 --參數:見下方說明 --調用: /* DECLARE pSELTEXT VARCHAR2(4000); BEGIN PKG_ANALYZE.GET_COMPARETEXT(1,'DATABASE_LINK1','DEV_INFOEXTAB',3,pSELTEXT); SYS.DBMS_OUTPUT.PUT_LINE('--SQL語句:'||CHR(10)||pSELTEXT); END; */ --日期:2013-04-1 ( pTAG IN NUMBER, --查詢模式:1-求同(交集),2-求異(補集) pLINKNAME IN VARCHAR, --連接名 pTABLENAME IN VARCHAR2:=NULL, --源表,能夠爲一張或多張表,多個表以','分隔,爲空則選擇全部表 pMODE IN NUMBER:=1, --匹配模式 pSELTEXT OUT VARCHAR2 ) --匹配模式: --1-只比較基礎數據類型,如VARCHAR二、NUMBER、DATE等, --2-在1基礎上比較數據類型的長度和精度, --3-在2基礎上比較列可否爲空 AS pUSER VARCHAR2(200):=USER; pSELECT VARCHAR2(1000); pFROM VARCHAR2(1000); pLINKFROM VARCHAR2(1000); pOUTCOL VARCHAR2(100); pSELTYPE VARCHAR2(50); BEGIN pSELECT:=Q'{SELECT A.TABLE_NAME AS TABLENAME,B.COLUMN_NAME AS COLUMNNAME,DATA_TYPE, CASE DATA_TYPE WHEN 'NUMBER' THEN CASE NVL(TO_CHAR(B.DATA_SCALE),'0') WHEN '0' THEN 'INT' ELSE 'DECIMAL('||NVL(TO_CHAR(B.DATA_PRECISION),'18')||','||B.DATA_SCALE||')' END WHEN 'VARCHAR2' THEN 'VARCHAR('||B.CHAR_LENGTH||')' WHEN 'DATE' THEN 'DATETIME' WHEN 'BLOB' THEN 'VARBINARY(4000)' WHEN 'LONG' THEN 'VARCHAR(4000)' ELSE B.DATA_TYPE END AS SQLTYPE, CASE DATA_TYPE WHEN 'NUMBER' THEN REPLACE(B.DATA_TYPE||'('||NVL(TO_CHAR(B.DATA_PRECISION),'*')||','||NVL(TO_CHAR(B.DATA_SCALE),'*')||')','(*,*)','') WHEN 'VARCHAR2' THEN B.DATA_TYPE||'('||B.CHAR_LENGTH||')' ELSE B.DATA_TYPE END AS ORACLETYPE, CASE B.NULLABLE WHEN 'Y' THEN 'NULL' ELSE 'NOT NULL' END AS ISNULLABLE, COLUMN_ID AS COLUMN_ID FROM }'; pFROM:='SYS.DBA_TABLES A JOIN SYS.DBA_TAB_COLUMNS B ON (A.TABLE_NAME=B.TABLE_NAME AND A.OWNER=B.OWNER) WHERE A.OWNER='''||pUSER ||''' AND (INSTR('',''||'''|| pTABLENAME||'''||'','','',''||A.TABLE_NAME||'','',1)>0 OR '''||pTABLENAME|| ''' IS NULL) AND A.TEMPORARY=''N'' ORDER BY TABLENAME,COLUMN_ID'; --查詢本地表 pLINKFROM:='SYS.USER_TABLES@'||pLINKNAME||' A JOIN SYS.USER_TAB_COLUMNS@'||pLINKNAME|| ' B ON (A.TABLE_NAME=B.TABLE_NAME) WHERE (INSTR('',''||'''|| pTABLENAME||'''||'','','',''||A.TABLE_NAME||'','',1)>0 OR '''||pTABLENAME|| ''' IS NULL) AND A.TEMPORARY=''N'''; --查詢連接庫表 SELECT 'SELECT TABLENAME,COLUMNNAME,DATA_TYPE'||DECODE(pMODE,2,',ORACLETYPE',3,',ORACLETYPE,ISNULLABLE','')||' FROM(' INTO pOUTCOL FROM DUAL; SELECT DECODE(pTAG,1,'INTERSECT','MINUS') INTO pSELTYPE FROM DUAL; --查詢模式 pSELTEXT:=pOUTCOL||chr(10)||' '||pSELECT||pLINKFROM||CHR(10)||') LINKDB'||CHR(10)||pSELTYPE||' '||pOUTCOL||CHR(10)||' '|| pSELECT||pFROM||CHR(10)||') SELFDB'; END; PROCEDURE CHECK_MERGE_MINUS --功能:查詢目標庫與源庫表的差別部分(若是目標表中存在主鍵相同記錄,則同步類型爲'UPDATE',不存在則同步類型爲'INSERT',目標表中存在而源表中不存在則同步類型爲'DELETE') --參數: --調用: /* DECLARE pCURSOR SYS_REFCURSOR; BEGIN PKG_ANALYZE.CHECK_MERGE_MINUS('USR_INFOTAB@DBLINK','USR_INFOTAB',pCURSOR); END; */ --日期:2014-05-8 ( pSOURCETB IN VARCHAR, --源表名,若是爲遠程連接表,相似爲TABLENAME@LINKNAME的格式,如:USR_INFOTAB@DATABASE_LINK1 pTARGETTB IN VARCHAR2, --目標表名 pFILTER IN VARCHAR2:=NULL, --條件過濾 pCURSOR OUT SYS_REFCURSOR ) AS pON VARCHAR2(4000); --鏈接查詢條件列 pWHERE VARCHAR2(4000); --WHERE條件列 pMINUSSQL VARCHAR2(4000); --查詢差別記錄的SQL語句 pSQL VARCHAR2(4000); --拼接完整的查詢SQL語句 BEGIN pMINUSSQL:= 'SELECT * FROM '||pSOURCETB||''||' '||pFILTER||' MINUS SELECT * FROM '||pTARGETTB||' '||pFILTER; -- --條件爲主鍵、全部惟一約束、全部惟一索引共同匹配,防止出現違反惟一約束或主鍵衝突 -- SELECT DISTINCT LISTAGG('TA."'||COLUMN_NAME||'"=TB."'||COLUMN_NAME||'"',' AND ') WITHIN GROUP(ORDER BY 1) OVER(), -- LISTAGG('TB."'||COLUMN_NAME||'"','||') WITHIN GROUP(ORDER BY 1) OVER() INTO pON,pWHERE FROM( -- SELECT DISTINCT B.COLUMN_NAME -- FROM SYS.USER_INDEXES A -- JOIN SYS.USER_IND_COLUMNS B ON (A.TABLE_NAME=B.TABLE_NAME AND A.INDEX_NAME=B.INDEX_NAME) -- WHERE A.TABLE_NAME=pTARGETTB AND A.TABLE_TYPE='TABLE' AND A.UNIQUENESS='UNIQUE'); --2016-02-20修改:當主鍵字段已存在,惟一約束字段值不一樣時不會進行同步,故去掉惟一約束、惟一索引條件 SELECT DISTINCT LISTAGG('TA."'||TB.COLUMN_NAME||'"=TB."'||TB.COLUMN_NAME||'"',' AND ') WITHIN GROUP(ORDER BY TB.POSITION) OVER(PARTITION BY TA.INDEX_NAME), LISTAGG('TB."'||TB.COLUMN_NAME||'"','||') WITHIN GROUP(ORDER BY TB.POSITION) OVER() INTO pON,pWHERE FROM SYS.USER_CONSTRAINTS TA JOIN SYS.USER_CONS_COLUMNS TB ON (TA.owner=TB.owner AND TA.table_name=TB.table_name AND TA.constraint_name=TB.constraint_name) WHERE TA.TABLE_NAME=pTARGETTB AND TA.CONSTRAINT_TYPE='P'; pSQL:='SELECT CASE WHEN '||pWHERE||' IS NOT NULL THEN ''UPDATE'' ELSE ''INSERT'' END AS MERGE_DATA_TYPE,TA.* FROM('||CHR(10)|| ' SELECT * FROM '||pSOURCETB||''||' '||pFILTER||CHR(10)|| ' MINUS'||CHR(10)|| ' SELECT * FROM '||pTARGETTB||' '||pFILTER||CHR(10)|| ') TA'||CHR(10)|| ' LEFT JOIN '||pTARGETTB||' TB ON ('||pON||')'||CHR(10)|| 'UNION ALL'||CHR(10)|| 'SELECT ''DELETE'' AS MERGE_DATA_TYPE,TB.* FROM '||pTARGETTB||' TB WHERE NOT EXISTS('||CHR(10)|| ' SELECT * FROM '||pSOURCETB||' TA WHERE '||pON||CHR(10)|| ')'; SYS.DBMS_OUTPUT.PUT_LINE('/*SQL語句*/'||CHR(10)||pSQL); OPEN pCURSOR FOR pSQL; EXCEPTION WHEN NO_DATA_FOUND THEN OPEN pCURSOR FOR 'SELECT ''INSERT'' AS MERGE_DATA_TYPE,TB.* FROM(' ||pMINUSSQL||') TB'; --SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'表'||pTABLENAME||'中無主鍵和惟一約束,沒法進行對比!'); WHEN OTHERS THEN SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'對比表數據異常:' ||SQLERRM); END; FUNCTION GET_TABLE_COUNT ( pLINKNAME IN VARCHAR, --連接名 pCHECKTABLELIST IN CHECKTABLELIST --源過濾的表類型 ) RETURN CHETABLECOUNTLIST PIPELINED AS pSOURCETB VARCHAR2(200); --源表名 pTARGETTB VARCHAR2(200); --目的表名 pFILTER VARCHAR2(2000); --過濾條件 pON VARCHAR2(4000); --鏈接查詢條件列 pWHERE VARCHAR2(4000); --WHERE條件列 pMINUSSQL VARCHAR2(4000); --查詢差別記錄的SQL語句 pSQL VARCHAR2(4000); --拼接完整的查詢SQL語句 CN CHETABLECOUNT; BEGIN FOR X IN ( SELECT * FROM TABLE(pCHECKTABLELIST) ) LOOP pSOURCETB:=X.TABLENAME||'@'||pLINKNAME; pTARGETTB:=X.TABLENAME; pFILTER:=X.WHERESTR; pMINUSSQL:= 'SELECT * FROM '||pSOURCETB||''||' '||pFILTER||' MINUS SELECT * FROM '||pTARGETTB||' '||pFILTER; --2016-02-20修改:當主鍵字段已存在,惟一約束字段值不一樣時不會進行同步,故去掉惟一約束、惟一索引條件 SELECT DISTINCT LISTAGG('TA."'||TB.COLUMN_NAME||'"=TB."'||TB.COLUMN_NAME||'"',' AND ') WITHIN GROUP(ORDER BY TB.POSITION) OVER(PARTITION BY TA.INDEX_NAME), LISTAGG('TB."'||TB.COLUMN_NAME||'"','||') WITHIN GROUP(ORDER BY TB.POSITION) OVER() INTO pON,pWHERE FROM SYS.USER_CONSTRAINTS TA JOIN SYS.USER_CONS_COLUMNS TB ON (TA.owner=TB.owner AND TA.table_name=TB.table_name AND TA.constraint_name=TB.constraint_name) WHERE TA.TABLE_NAME=pTARGETTB AND TA.CONSTRAINT_TYPE='P'; pSQL:='SELECT '''||pTARGETTB||''' AS "表名",SUM(CASE MERGE_DATA_TYPE WHEN ''DELETE'' THEN MERGE_COUNT ELSE 0 END) AS "DELETE",'||CHR(10)|| 'SUM(CASE MERGE_DATA_TYPE WHEN ''INSERT'' THEN MERGE_COUNT ELSE 0 END) AS "INSERT",'||CHR(10)|| 'SUM(CASE MERGE_DATA_TYPE WHEN ''UPDATE'' THEN MERGE_COUNT ELSE 0 END) AS "UPDATE" FROM ('||CHR(10)|| ' SELECT DISTINCT MERGE_DATA_TYPE,COUNT(MERGE_DATA_TYPE) OVER(PARTITION BY MERGE_DATA_TYPE) AS "MERGE_COUNT" FROM ('||CHR(10)|| ' SELECT CASE WHEN '||pWHERE||' IS NOT NULL THEN ''UPDATE'' ELSE ''INSERT'' END AS MERGE_DATA_TYPE,TA.* FROM('||CHR(10)|| ' SELECT * FROM '||pSOURCETB||''||' '||pFILTER||CHR(10)|| ' MINUS'||CHR(10)|| ' SELECT * FROM '||pTARGETTB||' '||pFILTER||CHR(10)|| ' ) TA'||CHR(10)|| ' LEFT JOIN '||pTARGETTB||' TB ON ('||pON||')'||CHR(10)|| ' UNION ALL'||CHR(10)|| ' SELECT ''DELETE'' AS MERGE_DATA_TYPE,TB.* FROM '||pTARGETTB||' TB WHERE NOT EXISTS('||CHR(10)|| ' SELECT * FROM '||pSOURCETB||' TA WHERE '||pON||CHR(10)|| ' )'||CHR(10)|| ' )'||CHR(10)|| ')'; EXECUTE IMMEDIATE pSQL INTO CN; PIPE ROW(CN); END LOOP; RETURN; END; PROCEDURE CHECK_MERGE_COUNT --功能:查詢目標庫與源庫表的差別記錄數量(若是目標表中存在主鍵相同記錄,則同步類型爲'UPDATE',不存在則同步類型爲'INSERT',目標表中存在而源表中不存在則同步類型爲'DELETE') --參數: --調用: /* DECLARE pCURSOR SYS_REFCURSOR; pCB CHECKTABLELIST; BEGIN --pCB:=CHECKTABLELIST(); --PCB.EXTEND(1); pCB(1):=CHECKTABLE('USR_INFOTAB',''); --PKG_ANALYZE.CHECK_MERGE_COUNT('DLINK_160222094700882',pCB,pCURSOR); END; */ --日期:2014-05-8 ( pLINKNAME IN VARCHAR, --連接名 pCHECKTABLELIST IN CHECKTABLELIST, --源過濾的表類型 pCURSOR OUT SYS_REFCURSOR ) AS BEGIN OPEN pCURSOR FOR SELECT TABLE_NAME AS "表名",INSERTCOUNT AS "INSER數量",UPDATECOUNT AS "修改數量",DELETECOUNT AS "刪除數量" FROM TABLE(PKG_ANALYZE.GET_TABLE_COUNT(pLINKNAME,pCHECKTABLELIST)) WHERE (DELETECOUNT+INSERTCOUNT+UPDATECOUNT)>0; END; PROCEDURE CHECK_MINUS --功能:查詢目標庫與連接源庫表的差別部分(求補集) --參數: --調用: /* DECLARE pCURSOR SYS_REFCURSOR; BEGIN PKG_ANALYZE.CHECK_MINUS('DATABASE_LINK1','DEV_INFOEXTAB',3,pCURSOR); END; */ --日期:2013-04-1 ( pLINKNAME IN VARCHAR, --連接名 pTABLENAME IN VARCHAR2:=NULL, --源表,能夠爲一張或多張表,多個表以','分隔,爲空則選擇全部表 pMODE IN NUMBER:=1, --匹配模式 pCURSOR OUT SYS_REFCURSOR --返回連接庫中有而目標庫中沒有的部分 ) --匹配模式: --1-只比較基礎數據類型,如VARCHAR二、NUMBER、DATE等, --2-在1基礎上比較數據類型的長度和精度, --3-在2基礎上比較列可否爲空 AS pSQLTEXT VARCHAR2(4000); BEGIN GET_COMPARETEXT(2,pLINKNAME,pTABLENAME,pMODE,pSQLTEXT); OPEN pCURSOR FOR pSQLTEXT; END; PROCEDURE CHECK_INTERSECT --功能:查詢目標庫與連接源庫表的相同部分(求交集) --參數: --調用: /* DECLARE pCURSOR SYS_REFCURSOR; BEGIN PKG_ANALYZE.CHECK_INTERSECT('DATABASE_LINK1','DEV_INFOEXTAB',3,pCURSOR); END; */ --日期:2013-04-1 ( pLINKNAME IN VARCHAR, --連接名 pTABLENAME IN VARCHAR2:=NULL, --源表,能夠爲一張或多張表,多個表以','分隔,爲空則選擇全部表 pMODE IN NUMBER:=1, --匹配模式 pCURSOR OUT SYS_REFCURSOR --返回連接庫、目標庫中共有的部分 ) --匹配模式: --1-只比較基礎數據類型,如VARCHAR二、NUMBER、DATE等, --2-在1基礎上比較數據類型的長度和精度, --3-在2基礎上比較列可否爲空 AS pSQLTEXT VARCHAR2(4000); BEGIN GET_COMPARETEXT(1,pLINKNAME,pTABLENAME,pMODE,pSQLTEXT); OPEN pCURSOR FOR pSQLTEXT; END; PROCEDURE CHECK_DISTINCT --功能:查詢對比目標庫與連接源庫表數據對比具備相同列數據的部分(如查詢重複列數據) --參數: --調用: /* DECLARE pCURSOR SYS_REFCURSOR; BEGIN PKG_ANALYZE.CHECK_DISTINCT('DATABASE_LINK1','DEV_INFOEXTAB','DEVICENAME,DEVICETYPE,DEVICEMODEL,DEVICESN,DEVICEVER,PRODUCTCOMPANY,PRODUCTLINKPERSON,PRODUCTLINKTEL, BUILDCOMPANY,BUILDTEL,BUILDLINKPERSON,DEVICEAREA,DEVICEPLACE,LINKPERSON,LINKTEL,LINKMOBILE,LINKEMAIL',pCURSOR); END; */ --日期:2013-04-9 ( pLINKNAME IN VARCHAR, --連接名 pTABLENAME IN VARCHAR2, --表名 pCOLNAME IN VARCHAR2, --匹配列名,多個列以逗號分隔 pCURSOR OUT SYS_REFCURSOR --返回連接庫、目標庫中共有的部分 ) AS pCOLLIST VARCHAR2(2000); pSQLTEXT VARCHAR2(2000); BEGIN SELECT LISTAGG('LOWER(A.'||A.COL||')=LOWER(B.'||A.COL||')',' AND ') WITHIN GROUP(ORDER BY A.ROWN) INTO pCOLLIST FROM ( SELECT ROWNUM AS ROWN,UPPER(regexp_substr(pCOLNAME,'[^,]+',1,LEVEL)) AS COL FROM DUAL CONNECT BY LEVEL<=LENGTH(pCOLNAME)-LENGTH(REPLACE(pCOLNAME,',',''))+1 ) A; pSQLTEXT:='SELECT * FROM '||pTABLENAME||' A WHERE EXISTS ('||CHR(10)|| 'SELECT * FROM '||pTABLENAME||'@'||pLINKNAME||' b WHERE '||pCOLLIST||')'; --SYS.DBMS_OUTPUT.PUT_LINE('/*SQL語句:*/'||pSQLTEXT); OPEN pCURSOR FOR pSQLTEXT; EXCEPTION WHEN OTHERS THEN NULL; END; END; / create or replace PACKAGE PKG_MERGE AS --功能:同步目標表和源表數據一致 PROCEDURE MERGE_TABLE( pTARGETTB IN VARCHAR2, --表示目標表,只能爲單表名稱 pSOURCETB IN VARCHAR2, --表示源表,可爲單表、單視圖、多表、多視圖鏈接查詢的結果集 pTARGETWHERE IN VARCHAR2, --目標表條件列,多個列以','分隔.列數和順序與源表條件列一致 pSOURCEWHERE IN VARCHAR2, --源表條件列,多個列以','分隔.列數和順序與目標表條件列一致 pTARGETCOL IN VARCHAR2, --目標表記錄操做列,多個列以','分隔.列數和順序與源表記錄操做列一致 pSOURCECOL IN VARCHAR2 --源表記錄操做列,多個列以','分隔.列數和順序與目標表記錄操做條件列一致; ); --功能:同步表,條件爲主鍵和惟一約束進行匹配 PROCEDURE MERGE_TABLE( pTARGETTB IN VARCHAR2, --表示目標表,只能爲單表名稱 pSOURCETB IN VARCHAR2, --表示源表,只能爲單表名稱,源表和目標表結構和類型保持一致 pKEY IN VARCHAR2:=NULL, --匹配條件,多列以逗號分隔 pMODE IN NUMBER:=1, --若是記錄在目的數據庫上存在而在源數據庫表中不存在,處理方式:1-刪除目的數據庫中的記錄、其餘-不予操做 pMSG OUT NUMBER --返回消息,1-同步成功,-1:失敗,-2:無主鍵和惟一約束 ); --功能:同步表,條件爲主鍵和惟一約束進行匹配,源數據庫來自遠程連接 PROCEDURE MERGE_LINK_TABLE( pLINKNAME IN VARCHAR2, --連接名 pTBLIST IN VARCHAR2:=NULL, --表示目標表,能夠爲一張或多張表,多個表以','分隔 pMODE IN NUMBER:=1, --若是記錄在目的數據庫上存在而在源數據庫表中不存在,處理方式:1-刪除目的數據庫中的記錄、其餘-不予操做 pMSG OUT NUMBER, --返回消息,1-同步成功,-1:失敗,-2:無主鍵和惟一約束 pFILTER IN VARCHAR2:=NULL --條件過濾 ); --功能:同步表,條件爲主鍵和惟一約束進行匹配,源數據庫來自遠程連接,目標數據庫也來自遠程連接 PROCEDURE MERGE_TWOLINK( pSOURCELINK IN VARCHAR2, --連接源數據庫的連接名 pTARGETLINK IN VARCHAR2, --連接目的數據庫的連接名 pTBLIST IN VARCHAR2:=NULL, --表示目標表,能夠爲一張或多張表,多個表以','分隔 pMODE IN NUMBER:=1, --若是記錄在目的數據庫上存在而在源數據庫表中不存在,處理方式:1-刪除目的數據庫中的記錄、其餘-不予操做 pMSG OUT NUMBER --返回消息,1-同步成功,-1:失敗,-2:無主鍵和惟一約束 ); --功能:同步表數據(支持低版本數據源往同版本或高版本目標庫同步,同時也支持高版本數據源往低版本目標庫同步) PROCEDURE MERGE_INTERSECT( pLINKNAME IN VARCHAR2, --連接名 pTABLENAME IN VARCHAR2:=NULL, --源表,能夠爲一張或多張表,多個表以','分隔,爲空則選擇結構類型一致的全部表 pMODE IN NUMBER:=1 --匹配模式 ); --功能:同步本地數據庫表,根據列名相同原則來匹配,pTABLENAME爲NULL則同步全部表的記錄,不爲NULL則同步一個或多個表的記錄,多個表以','分隔 PROCEDURE MERGE_FROM_DB( pLINKNAME IN VARCHAR2, --連接名 pTABLENAME IN VARCHAR2:=NULL, --連接數據庫同步表,多個表以','分隔 pTABLEEXIXTS IN VARCHAR2:='DELETE' --本地表存在的處理方式 ); --功能:同步連接數據庫表,根據列名相同原則來匹配,pTABLENAME爲NULL則同步全部表的記錄,不爲NULL則同步一個或多個表的記錄,多個表以','分隔 PROCEDURE MERGE_TO_DB( pLINKNAME IN VARCHAR2, --連接名 pTABLENAME IN VARCHAR2:=NULL, --本地數據庫同步表,多個表以','分隔 pTABLEEXIXTS IN VARCHAR2:='DELETE' --連接表存在的處理方式:'DELETE'-直接刪除表數據再添加、'APPEND'-追加 ); END; / create or replace PACKAGE BODY PKG_MERGE AS PROCEDURE MERGE_TABLE --功能:同步表 --參數:見下方說明 --調用:EXECUTE PKG_MERGE.MERGE_TABLE('DEV_INFOEXTAB','DEV_INFOTAB','DEVICENAME','DEVICENAME','DEVICEID','DEVICEID'); --日期:2013-02-10 ( pTARGETTB IN VARCHAR2, --表示目標表,只能爲單表名稱 pSOURCETB IN VARCHAR2, --表示源表,可爲單表、單視圖、多表、多視圖鏈接查詢的結果集 pTARGETWHERE IN VARCHAR2, --目標表條件列,多個列以','分隔.列數和順序與源表條件列一致 pSOURCEWHERE IN VARCHAR2, --源表條件列,多個列以','分隔.列數和順序與目標表條件列一致 pTARGETCOL IN VARCHAR2, --目標表記錄操做列,多個列以','分隔.列數和順序與源表記錄操做列一致 pSOURCECOL IN VARCHAR2 --源表記錄操做列,多個列以','分隔.列數和順序與目標表記錄操做條件列一致 ) AS pUSESOURCE VARCHAR2(4000); --拼接源表結果集,若是是單表能夠直接爲表名,不然必須用'()'進行包裝查詢語句 pWHERE VARCHAR2(4000); --拼接MERGER同步源表與目標表的匹配WHERE條件 pUPDATECOL VARCHAR2(4000); --拼接MERGER同步源表與目標表的修改列 pINSERTCOL VARCHAR2(4000); --拼接MERGER同步源表與目標表的添加列 pSQL VARCHAR2(4000); --拼接MERGER同步的完整SQL語句 BEGIN SELECT DECODE(INSTR(TRIM(UPPER(pSOURCETB)),'SELECT'),1,'('||pSOURCETB||')',pSOURCETB) INTO pUSESOURCE FROM DUAL;--拼接源表結果集 SELECT LISTAGG('S.'||A.COL||'=T.'||B.COL,' AND ') WITHIN GROUP(ORDER BY A.ROWN) INTO pWHERE FROM (SELECT ROWNUM AS ROWN,UPPER(regexp_substr(pSOURCEWHERE,'[^,]+',1,LEVEL)) AS COL FROM DUAL CONNECT BY LEVEL<=LENGTH(pSOURCEWHERE)-LENGTH(REPLACE(pSOURCEWHERE,',',''))+1) A JOIN (SELECT ROWNUM AS ROWN,UPPER(regexp_substr(pTARGETWHERE,'[^,]+',1,LEVEL)) AS COL FROM DUAL CONNECT BY LEVEL<=LENGTH(pTARGETWHERE)-LENGTH(REPLACE(pTARGETWHERE,',',''))+1) B ON A.ROWN=B.ROWN; --拼接MERGER同步源表與目標表的匹配WHERE條件 SELECT LISTAGG(A.COL||'=T.'||B.COL,',') WITHIN GROUP(ORDER BY A.ROWN) INTO pUPDATECOL FROM (SELECT ROWNUM AS ROWN,UPPER(regexp_substr(pSOURCECOL,'[^,]+',1,LEVEL)) AS COL FROM DUAL CONNECT BY LEVEL<=LENGTH(pSOURCECOL)-LENGTH(REPLACE(pSOURCECOL,',',''))+1) A JOIN (SELECT ROWNUM AS ROWN,UPPER(regexp_substr(pTARGETCOL,'[^,]+',1,LEVEL)) AS COL FROM DUAL CONNECT BY LEVEL<=LENGTH(pTARGETCOL)-LENGTH(REPLACE(pTARGETCOL,',',''))+1) B ON A.ROWN=B.ROWN; --拼接MERGER同步源表與目標表的修改列 SELECT 'T.'||REPLACE(pSOURCEWHERE||','||pSOURCECOL,',',',T.') INTO pINSERTCOL FROM DUAL; --拼接MERGER同步源表與目標表的添加列 pSQL:='MERGE INTO '||pTARGETTB||' S'||CHR(10)|| 'USING '||pUSESOURCE||' T'||CHR(10)|| 'ON('||pWHERE||')'||CHR(10)|| ' WHEN MATCHED THEN'||CHR(10)|| ' UPDATE SET '||pUPDATECOL||CHR(10)|| ' WHEN NOT MATCHED THEN'||CHR(10)|| ' INSERT ('||pTARGETWHERE||','||pTARGETCOL||')'||' VALUES('||pINSERTCOL||')'; --拼接MERGER同步的完整SQL語句 --SYS.DBMS_OUTPUT.PUT_LINE('/*SQL語句:*/'||pSQL); EXECUTE IMMEDIATE pSQL; COMMIT; EXCEPTION WHEN OTHERS THEN SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'同步表數據異常:' ||SQLERRM); END; PROCEDURE MERGE_TABLE --功能:同步表,條件爲主鍵和惟一約束進行匹配 --參數:見下方說明 --調用: /* DECLARE pMSG NUMBER(2); BEGIN PKG_MERGE.MERGE_TABLE('DATABASE_LINK1','USR_ROLETAB',1,pMSG); DBMS_OUTPUT.PUT_LINE('同步消息:'||pMSG); END; */ --日期:2014-05-13 ( pTARGETTB IN VARCHAR2, --表示目標表,只能爲單表名稱 pSOURCETB IN VARCHAR2, --表示源表,只能爲單表名稱,源表和目標表結構和類型保持一致 pKEY IN VARCHAR2:=NULL, --匹配條件,多列以逗號分隔 pMODE IN NUMBER:=1, --若是記錄在目的數據庫上存在而在源數據庫表中不存在,處理方式:1-刪除目的數據庫中的記錄、其餘-不予操做 pMSG OUT NUMBER --返回消息,1-同步成功,-1:失敗,-2:無主鍵和惟一約束 ) AS pWHERE VARCHAR2(4000); --拼接MERGER同步源表與目標表的匹配WHERE條件 pUPDATECOL VARCHAR2(4000); --拼接MERGER同步源表與目標表的修改列 pINSERTCOL VARCHAR2(4000); --拼接MERGER同步源表與目標表的添加列 pSQL VARCHAR2(4000); --拼接MERGER同步的完整SQL語句 PROCEDURE MERGE_NOCONSTRA AS BEGIN IF pKEY IS NOT NULL THEN SELECT DISTINCT LISTAGG('S."'||COLUMN_VALUE||'"=T."'||COLUMN_VALUE||'"',' AND ') WITHIN GROUP(ORDER BY 1) OVER() INTO pWHERE FROM ( SELECT * FROM TABLE(PKG_FUNC.SPLITSTR(pKEY)) ); ELSE SELECT DISTINCT LISTAGG('S."'||B.COLUMN_NAME||'"=T."'||B.COLUMN_NAME||'"',' AND ') WITHIN GROUP(ORDER BY B.POSITION) OVER(PARTITION BY A.INDEX_NAME) INTO pWHERE FROM SYS.USER_CONSTRAINTS A JOIN SYS.USER_CONS_COLUMNS B ON (A.owner=b.owner AND A.table_name=b.table_name AND A.constraint_name=B.constraint_name) WHERE A.TABLE_NAME=pTARGETTB AND A.CONSTRAINT_TYPE='P'; END IF; EXCEPTION WHEN NO_DATA_FOUND THEN pMSG:=1; --無主鍵和惟一約束則直接添加,2014-08-02修改成去掉惟一約束斷定 pSQL:='INSERT INTO '||pTARGETTB||' SELECT * FROM '||pSOURCETB; --SYS.DBMS_OUTPUT.PUT_LINE(pSQL); EXECUTE IMMEDIATE pSQL; --SYS.DBMS_OUTPUT.PUT_LINE('同步無主鍵和惟一約束的表'||pTARGETTB||'數據成功!'); WHEN OTHERS THEN pMSG:=-1; --同步失敗 --SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'同步無主鍵和惟一約束的表'||pTARGETTB||'數據異常:' ||SQLERRM); END; BEGIN pWHERE:=''; pUPDATECOL:=''; pINSERTCOL:=''; MERGE_NOCONSTRA; --判斷表中是否有主鍵、惟一約束,若是不存在則直接添加表數據,不然跳過直接進行下一步操做,2014-08-02修改成去掉惟一約束斷定 IF pWHERE IS NOT NULL THEN FOR Y IN ( SELECT DISTINCT * FROM ( SELECT TA.COLUMN_NAME,TB.COLUMN_NAME AS CONS_COL FROM SYS.USER_TAB_COLUMNS TA LEFT JOIN( SELECT A.TABLE_NAME,B.COLUMN_NAME FROM SYS.USER_CONSTRAINTS A JOIN SYS.USER_CONS_COLUMNS B ON (A.owner=b.owner AND A.table_name=b.table_name AND A.constraint_name=B.constraint_name) WHERE A.TABLE_NAME=pTARGETTB AND A.CONSTRAINT_TYPE='P' ) TB ON (TA.TABLE_NAME=TB.TABLE_NAME AND TA.COLUMN_NAME=TB.COLUMN_NAME) WHERE TA.TABLE_NAME=pTARGETTB ORDER BY TA.COLUMN_ID) ) --2014-08-02修改成條件爲主鍵匹配 LOOP IF Y.CONS_COL IS NULL THEN pUPDATECOL:=pUPDATECOL||'"'||Y.COLUMN_NAME||'"=T."'||Y.COLUMN_NAME||'",'; END IF; pINSERTCOL:=pINSERTCOL||',"'||Y.COLUMN_NAME||'"'; END LOOP; pUPDATECOL:=RTRIM(pUPDATECOL,','); pSQL:='MERGE INTO '||pTARGETTB||' S'||CHR(10)|| 'USING '||pSOURCETB||' T'||CHR(10)|| 'ON('||pWHERE||')'||CHR(10); IF pUPDATECOL IS NOT NULL THEN pSQL:=pSQL||' WHEN MATCHED THEN'||CHR(10)|| ' UPDATE SET '||RTRIM(pUPDATECOL,',')||CHR(10); END IF; pSQL:=pSQL||' WHEN NOT MATCHED THEN'||CHR(10)|| ' INSERT ('||LTRIM(REPLACE(pINSERTCOL,',',',S.'),',')||')'||' VALUES('||LTRIM(REPLACE(pINSERTCOL,',',',T.'),',')||')'; --SYS.DBMS_OUTPUT.PUT_LINE(pSQL); EXECUTE IMMEDIATE pSQL; --SYS.DBMS_OUTPUT.PUT_LINE(pSQL); IF pMODE=1 THEN --若是記錄在目的數據庫上存在而在源數據庫表中不存在,刪除目的數據庫中的記錄 pSQL:='DELETE FROM '||pTARGETTB||' T WHERE NOT EXISTS(SELECT * FROM '||pSOURCETB||' S WHERE '||pWHERE||')';--刪除在目標表中存在而在源表不存在的數據 EXECUTE IMMEDIATE pSQL; --SYS.DBMS_OUTPUT.PUT_LINE(pSQL); END IF; END IF; pMSG:=1; --同步成功 COMMIT; EXCEPTION WHEN OTHERS THEN pMSG:=-1; --同步失敗 SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'同步表數據異常:' ||SQLERRM); END; PROCEDURE MERGE_LINK_TABLE --功能:同步表,條件爲主鍵和惟一約束進行匹配,源數據庫來自遠程連接,2014-08-02修改成去掉惟一約束斷定 --參數:見下方說明 --調用: /* DECLARE pMSG NUMBER(2); BEGIN PKG_MERGE.MERGE_LINK_TABLE('DATABASE_LINK1','USR_ROLETAB',1,pMSG,null); DBMS_OUTPUT.PUT_LINE('同步消息:'||pMSG); END; */ --日期:2014-05-13 ( pLINKNAME IN VARCHAR2, --連接名 pTBLIST IN VARCHAR2:=NULL, --表示目標表,能夠爲一張或多張表,多個表以','分隔 pMODE IN NUMBER:=1, --若是記錄在目的數據庫上存在而在源數據庫表中不存在,處理方式:1-刪除目的數據庫中的記錄、其餘-不予操做 pMSG OUT NUMBER, --返回消息,1-同步成功,-1:失敗,-2:無主鍵和惟一約束 pFILTER IN VARCHAR2:=NULL --條件過濾 ) AS pSINGLETBNAME VARCHAR2(50); --保存當前表名 pCLONETBNAME VARCHAR2(50); --中間表名稱 pWHERE VARCHAR2(4000); --拼接MERGER同步源表與目標表的匹配WHERE條件 pUPDATECOL VARCHAR2(4000); --拼接MERGER同步源表與目標表的修改列 pINSERTCOL VARCHAR2(4000); --拼接MERGER同步源表與目標表的添加列 pSQL VARCHAR2(4000); --拼接MERGER同步的完整SQL語句 PROCEDURE MERGE_NOCONSTRA AS BEGIN --條件爲主鍵、全部惟一約束、全部惟一索引共同匹配,防止出現違反惟一約束或主鍵衝突 -- SELECT DISTINCT LISTAGG('('||WHERELIST||')',' OR ') WITHIN GROUP(ORDER BY INDEX_NAME) OVER() INTO pWHERE FROM( -- SELECT DISTINCT A.INDEX_NAME, -- LISTAGG('S."'||B.COLUMN_NAME||'"=T."'||B.COLUMN_NAME||'"',' AND ') -- WITHIN GROUP(ORDER BY B.COLUMN_POSITION) OVER(PARTITION BY A.INDEX_NAME) AS WHERELIST FROM SYS.USER_INDEXES A -- JOIN SYS.USER_IND_COLUMNS B ON (A.TABLE_NAME=B.TABLE_NAME AND A.INDEX_NAME=B.INDEX_NAME) -- WHERE A.TABLE_NAME=pSINGLETBNAME AND A.TABLE_TYPE='TABLE' AND A.UNIQUENESS='UNIQUE'); --2014-08-02修改:當主鍵字段已存在,惟一約束字段值不一樣時不會進行同步,故去掉惟一約束、惟一索引條件 SELECT DISTINCT LISTAGG('S."'||B.COLUMN_NAME||'"=T."'||B.COLUMN_NAME||'"',' AND ') WITHIN GROUP(ORDER BY B.POSITION) OVER(PARTITION BY A.INDEX_NAME) INTO pWHERE FROM SYS.USER_CONSTRAINTS A JOIN SYS.USER_CONS_COLUMNS B ON (A.owner=b.owner AND A.table_name=b.table_name AND A.constraint_name=B.constraint_name) WHERE A.TABLE_NAME=pSINGLETBNAME AND A.CONSTRAINT_TYPE='P'; EXCEPTION WHEN NO_DATA_FOUND THEN pMSG:=1; --無主鍵和惟一約束則直接添加,2014-08-02修改成去掉惟一約束斷定 pSQL:='INSERT INTO '||pSINGLETBNAME||' SELECT * FROM '||pSINGLETBNAME||'@'||pLINKNAME||' '||pFILTER; EXECUTE IMMEDIATE pSQL; --SYS.DBMS_OUTPUT.PUT_LINE('同步無主鍵和惟一約束的表'||pSINGLETBNAME||'數據成功!'); WHEN OTHERS THEN pMSG:=-1; --同步失敗 --SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'同步無主鍵和惟一約束的表'||pSINGLETBNAME||'數據異常:' ||SQLERRM); END; BEGIN FOR X IN ( SELECT LEVEL AS RN,REGEXP_SUBSTR(UPPER(pTBLIST),'[^,]+',1,LEVEL) AS TBNAME FROM DUAL CONNECT BY LEVEL<LENGTH(pTBLIST)-LENGTH(REPLACE(pTBLIST,','))+2 ) LOOP pSINGLETBNAME:=X.TBNAME; pWHERE:=''; pUPDATECOL:=''; pINSERTCOL:=''; MERGE_NOCONSTRA; --判斷表中是否有主鍵、惟一約束,若是不存在則直接添加表數據,不然跳過直接進行下一步操做,2014-08-02修改成去掉惟一約束斷定 IF pWHERE IS NOT NULL THEN -- FOR Y IN -- ( -- SELECT DISTINCT * FROM ( SELECT TA.COLUMN_NAME,TB.COLUMN_NAME AS CONS_COL FROM SYS.USER_TAB_COLUMNS TA -- LEFT JOIN( -- SELECT A.TABLE_NAME,B.COLUMN_NAME FROM SYS.USER_INDEXES A -- JOIN SYS.USER_IND_COLUMNS B ON (A.TABLE_NAME=B.TABLE_NAME AND A.INDEX_NAME=B.INDEX_NAME) -- WHERE A.TABLE_TYPE='TABLE' AND A.UNIQUENESS='UNIQUE' -- ) TB ON (TA.TABLE_NAME=TB.TABLE_NAME AND TA.COLUMN_NAME=TB.COLUMN_NAME) -- WHERE TA.TABLE_NAME=pSINGLETBNAME ORDER BY TA.COLUMN_ID) -- ) --條件爲主鍵、全部惟一約束、全部惟一索引共同匹配,防止出現違反惟一約束或主鍵衝突,2014-08-02修改成去掉惟一約束斷定 FOR Y IN ( SELECT DISTINCT * FROM ( SELECT TA.COLUMN_NAME,TB.COLUMN_NAME AS CONS_COL FROM SYS.USER_TAB_COLUMNS TA LEFT JOIN( SELECT A.TABLE_NAME,B.COLUMN_NAME FROM SYS.USER_CONSTRAINTS A JOIN SYS.USER_CONS_COLUMNS B ON (A.owner=b.owner AND A.table_name=b.table_name AND A.constraint_name=B.constraint_name) WHERE A.TABLE_NAME=pSINGLETBNAME AND A.CONSTRAINT_TYPE='P' ) TB ON (TA.TABLE_NAME=TB.TABLE_NAME AND TA.COLUMN_NAME=TB.COLUMN_NAME) WHERE TA.TABLE_NAME=pSINGLETBNAME ORDER BY TA.COLUMN_ID) ) --2014-08-02修改成條件爲主鍵匹配 LOOP IF Y.CONS_COL IS NULL THEN pUPDATECOL:=pUPDATECOL||Y.COLUMN_NAME||'=T.'||Y.COLUMN_NAME||','; END IF; pINSERTCOL:=pINSERTCOL||','||Y.COLUMN_NAME; END LOOP; pUPDATECOL:=RTRIM(pUPDATECOL,','); pSQL:='MERGE INTO '||pSINGLETBNAME||' S'||CHR(10)|| 'USING (SELECT * FROM '||pSINGLETBNAME||'@'||pLINKNAME||' '||pFILTER||') T'||CHR(10)|| 'ON('||pWHERE||')'||CHR(10); IF pUPDATECOL IS NOT NULL THEN pSQL:=pSQL||' WHEN MATCHED THEN'||CHR(10)|| ' UPDATE SET '||RTRIM(pUPDATECOL,',')||CHR(10); END IF; pSQL:=pSQL||' WHEN NOT MATCHED THEN'||CHR(10)|| ' INSERT ('||LTRIM(REPLACE(pINSERTCOL,',',',S.'),',')||')'||' VALUES('||LTRIM(REPLACE(pINSERTCOL,',',',T.'),',')||')'; EXECUTE IMMEDIATE pSQL; --SYS.DBMS_OUTPUT.PUT_LINE(pSQL); --SYS.DBMS_OUTPUT.PUT_LINE('同步'||pSINGLETBNAME||'表數據成功!'); IF pMODE=1 THEN --若是記錄在目的數據庫上存在而在源數據庫表中不存在,刪除目的數據庫中的記錄,採用傳輸數據到中間表的方式進行優化處理 pCLONETBNAME:='TMP_'||pSINGLETBNAME; PKG_DBMANAGE.CLONE_TEMP_TB(pSINGLETBNAME,pCLONETBNAME); --克隆生成中間臨時表 EXECUTE IMMEDIATE 'INSERT INTO '||pCLONETBNAME||' SELECT * FROM '||pSINGLETBNAME||'@'||pLINKNAME; --轉儲數據到中間表中 pSQL:='DELETE FROM '||pSINGLETBNAME||' T WHERE NOT EXISTS(SELECT * FROM '||pCLONETBNAME||' S WHERE '||pWHERE||')';--刪除在目標表中存在而在中間表不存在的數據 EXECUTE IMMEDIATE pSQL; END IF; END IF; END LOOP; pMSG:=1; --同步成功 COMMIT; EXCEPTION WHEN OTHERS THEN pMSG:=-1; --同步失敗 --SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'同步表數據異常:' ||SQLERRM); END; PROCEDURE MERGE_TWOLINK --功能:同步表,條件爲主鍵和惟一約束進行匹配,源數據庫來自遠程連接,目標數據庫也來自遠程連接 --參數:見下方說明 --調用: /* DECLARE pMSG NUMBER(2); BEGIN PKG_MERGE.MERGE_TWOLINK('DLIN11','DLINK2','USR_ROLETAB',1,pMSG); DBMS_OUTPUT.PUT_LINE('同步消息:'||pMSG); END; */ --日期:2014-10-30 ( pSOURCELINK IN VARCHAR2, --連接源數據庫的連接名 pTARGETLINK IN VARCHAR2, --連接目的數據庫的連接名 pTBLIST IN VARCHAR2:=NULL, --表示目標表,能夠爲一張或多張表,多個表以','分隔 pMODE IN NUMBER:=1, --若是記錄在目的數據庫上存在而在源數據庫表中不存在,處理方式:1-刪除目的數據庫中的記錄、其餘-不予操做 pMSG OUT NUMBER --返回消息,1-同步成功,-1:失敗,-2:無主鍵和惟一約束 ) AS pSINGLETBNAME VARCHAR2(50); --保存當前表名 pCLONETBNAME VARCHAR2(50); --中間表名稱 pTBSQL VARCHAR2(4000); --表記錄查詢SQL語句 pTBCURSOR SYS_REFCURSOR; --表記錄遊標 pCONSNAME VARCHAR2(100); --主鍵或者惟一約束名稱 pCOLNAME VARCHAR2(100); --列名 pWHERE VARCHAR2(4000); --拼接MERGER同步源表與目標表的匹配WHERE條件 pUPDATECOL VARCHAR2(4000); --拼接MERGER同步源表與目標表的修改列 pINSERTCOL VARCHAR2(4000); --拼接MERGER同步源表與目標表的添加列 pSQL VARCHAR2(4000); --拼接MERGER同步的完整SQL語句 PROCEDURE MERGE_NOCONSTRA AS pSELTXT VARCHAR2(4000); BEGIN --條件爲主鍵、全部惟一約束、全部惟一索引共同匹配,防止出現違反惟一約束或主鍵衝突 -- SELECT DISTINCT LISTAGG('('||WHERELIST||')',' OR ') WITHIN GROUP(ORDER BY INDEX_NAME) OVER() INTO pWHERE FROM( -- SELECT DISTINCT A.INDEX_NAME, -- LISTAGG('S."'||B.COLUMN_NAME||'"=T."'||B.COLUMN_NAME||'"',' AND ') -- WITHIN GROUP(ORDER BY B.COLUMN_POSITION) OVER(PARTITION BY A.INDEX_NAME) AS WHERELIST FROM SYS.USER_INDEXES A -- JOIN SYS.USER_IND_COLUMNS B ON (A.TABLE_NAME=B.TABLE_NAME AND A.INDEX_NAME=B.INDEX_NAME) -- WHERE A.TABLE_NAME=pSINGLETBNAME AND A.TABLE_TYPE='TABLE' AND A.UNIQUENESS='UNIQUE'); --2014-08-02修改:當主鍵字段已存在,惟一約束字段值不一樣時不會進行同步,故去掉惟一約束、惟一索引條件 pSELTXT:='SELECT DISTINCT LISTAGG(''S."''||B.COLUMN_NAME||''"=T."''||B.COLUMN_NAME||''"'','' AND '')'||CHR(10)|| ' WITHIN GROUP(ORDER BY B.POSITION) OVER(PARTITION BY A.INDEX_NAME) FROM SYS.USER_CONSTRAINTS@'||pTARGETLINK||' A '||CHR(10)|| ' JOIN SYS.USER_CONS_COLUMNS@'||pTARGETLINK||' B ON (A.owner=b.owner AND A.table_name=b.table_name AND A.constraint_name=B.constraint_name)'||CHR(10)|| ' WHERE A.TABLE_NAME='''||pSINGLETBNAME||''' AND A.CONSTRAINT_TYPE=''P'''; EXECUTE IMMEDIATE pSELTXT INTO pWHERE; EXCEPTION WHEN NO_DATA_FOUND THEN pMSG:=1; --無主鍵和惟一約束則直接添加,2014-08-02修改成去掉惟一約束斷定 pSQL:='INSERT INTO '||pSINGLETBNAME||'@'||pTARGETLINK||' SELECT * FROM '||pSINGLETBNAME||'@'||pSOURCELINK; EXECUTE IMMEDIATE pSQL; --SYS.DBMS_OUTPUT.PUT_LINE('同步無主鍵和惟一約束的表'||pSINGLETBNAME||'數據成功!'); WHEN OTHERS THEN pMSG:=-1; --同步失敗 SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'同步無主鍵和惟一約束的表'||pSINGLETBNAME||'數據異常:' ||SQLERRM); END; BEGIN FOR X IN ( SELECT LEVEL AS RN,REGEXP_SUBSTR(UPPER(pTBLIST),'[^,]+',1,LEVEL) AS TBNAME FROM DUAL CONNECT BY LEVEL<LENGTH(pTBLIST)-LENGTH(REPLACE(pTBLIST,','))+2 ) LOOP pSINGLETBNAME:=X.TBNAME; pWHERE:=''; pUPDATECOL:=''; pINSERTCOL:=''; MERGE_NOCONSTRA; --判斷表中是否有主鍵、惟一約束,若是不存在則直接添加表數據,不然跳過直接進行下一步操做,2014-08-02修改成去掉惟一約束斷定 IF pWHERE IS NOT NULL THEN pTBSQL:='SELECT DISTINCT * FROM ( SELECT TA.COLUMN_NAME,TB.COLUMN_NAME AS CONS_COL FROM SYS.USER_TAB_COLUMNS TA'||CHR(10)|| ' LEFT JOIN('||CHR(10)|| ' SELECT A.TABLE_NAME,B.COLUMN_NAME FROM SYS.USER_CONSTRAINTS@'||pTARGETLINK||' A '||CHR(10)|| ' JOIN SYS.USER_CONS_COLUMNS@'||pTARGETLINK||' B ON (A.owner=b.owner AND A.table_name=b.table_name AND A.constraint_name=B.constraint_name)'||CHR(10)|| ' WHERE A.TABLE_NAME='''||pSINGLETBNAME||''' AND A.CONSTRAINT_TYPE=''P'''||CHR(10)|| ' ) TB ON (TA.TABLE_NAME=TB.TABLE_NAME AND TA.COLUMN_NAME=TB.COLUMN_NAME)'||CHR(10)|| ' WHERE TA.TABLE_NAME='''||pSINGLETBNAME||''' ORDER BY TA.COLUMN_ID)'; OPEN pTBCURSOR FOR pTBSQL; LOOP FETCH pTBCURSOR INTO pCOLNAME,pCONSNAME; EXIT WHEN pTBCURSOR%NOTFOUND; IF pCONSNAME IS NULL THEN pUPDATECOL:=pUPDATECOL||pCOLNAME||'=T.'||pCOLNAME||','; END IF; pINSERTCOL:=pINSERTCOL||','||pCOLNAME; END LOOP; pUPDATECOL:=RTRIM(pUPDATECOL,','); pSQL:='MERGE INTO (SELECT * FROM '||pSINGLETBNAME||'@'||pTARGETLINK||') S'||CHR(10)|| 'USING (SELECT * FROM '||pSINGLETBNAME||'@'||pSOURCELINK||') T'||CHR(10)|| 'ON('||pWHERE||')'||CHR(10); IF pUPDATECOL IS NOT NULL THEN pSQL:=pSQL||' WHEN MATCHED THEN'||CHR(10)|| ' UPDATE SET '||RTRIM(pUPDATECOL,',')||CHR(10); END IF; pSQL:=pSQL||' WHEN NOT MATCHED THEN'||CHR(10)|| ' INSERT ('||LTRIM(REPLACE(pINSERTCOL,',',',S.'),',')||')'||' VALUES('||LTRIM(REPLACE(pINSERTCOL,',',',T.'),',')||')'; EXECUTE IMMEDIATE pSQL; --SYS.DBMS_OUTPUT.PUT_LINE(pSQL); SYS.DBMS_OUTPUT.PUT_LINE('同步'||pSINGLETBNAME||'表數據成功!'); IF pMODE=1 THEN --若是記錄在目的數據庫上存在而在源數據庫表中不存在,刪除目的數據庫中的記錄,採用傳輸數據到中間表的方式進行優化處理 pCLONETBNAME:='TMP_'||pSINGLETBNAME; PKG_DBMANAGE.CLONE_TEMP_TB(pSINGLETBNAME,pCLONETBNAME); --克隆生成中間臨時表,該臨時表保存在當前操做的數據 EXECUTE IMMEDIATE 'INSERT INTO '||pCLONETBNAME||' SELECT * FROM '||pSINGLETBNAME||'@'||pSOURCELINK; --轉儲數據到中間表中 pSQL:='DELETE FROM '||pSINGLETBNAME||'@'||pTARGETLINK||' T WHERE NOT EXISTS(SELECT * FROM '||pCLONETBNAME||' S WHERE '||pWHERE||')';--刪除在目標表中存在而在中間表不存在的數據 EXECUTE IMMEDIATE pSQL; --DBMS_OUTPUT.PUT_LINE(pSQL); END IF; END IF; END LOOP; pMSG:=1; --同步成功 COMMIT; EXCEPTION WHEN OTHERS THEN pMSG:=-1; --同步失敗 SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'同步表數據異常:' ||SQLERRM); END; PROCEDURE MERGE_INTERSECT --功能:同步表數據(支持低版本數據源往同版本或高版本目標庫同步,同時也支持高版本數據源往低版本目標庫同步),只同步具備相同列名稱和類型的表列, -- 同時目標庫中不能存在不爲空的新列,以保證能夠兼容添加數據到目標庫中,不然可能同步出錯) --參數:見下方說明 --調用:EXEC PKG_MERGE.MERGE_INTERSECT('DBLINK',NULL) --日期:2013-03-28 ( pLINKNAME IN VARCHAR2, --連接名 pTABLENAME IN VARCHAR2:=NULL, --源表,能夠爲一張或多張表,多個表以','分隔,爲空則選擇結構類型一致的全部表 pMODE IN NUMBER:=1 --匹配模式 ) --匹配模式: --1-只比較基礎數據類型,如VARCHAR二、NUMBER、DATE等, --2-在1基礎上比較數據類型的長度和精度, --3-在2基礎上比較列可否爲空 AS pUSER VARCHAR2(200):=USER; pSQLTEXT VARCHAR2(4000); TYPE pOBJTYPE IS RECORD ( TABLENAME SYS.DBA_TABLES.TABLE_NAME%TYPE, COLLIST VARCHAR2(4000) ) ; TYPE pOBJTYPELIST IS TABLE OF pOBJTYPE INDEX BY PLS_INTEGER; pTABCOLLIST pOBJTYPELIST; pINSERTTEXT VARCHAR2(4000) ; pRFECUR SYS_REFCURSOR; pSINGLETBNAME SYS.DBA_TABLES.TABLE_NAME%TYPE; BEGIN PKG_ANALYZE.GET_COMPARETEXT(1,pLINKNAME,pTABLENAME,pMODE,pSQLTEXT); --建議使用非嚴格模式進行匹配 pSQLTEXT:='SELECT DISTINCT TABLENAME,LISTAGG(''"''||COLUMNNAME||''"'','','')'|| 'WITHIN GROUP(ORDER BY 1) OVER(PARTITION BY TABLENAME) AS COLLIST FROM ('||pSQLTEXT||')'; OPEN pRFECUR FOR pSQLTEXT; FETCH pRFECUR BULK COLLECT INTO pTABCOLLIST; FOR L_ROW IN pTABCOLLIST.FIRST..pTABCOLLIST.LAST LOOP pSINGLETBNAME:=pTABCOLLIST(L_ROW).TABLENAME; pINSERTTEXT:='INSERT INTO '||pSINGLETBNAME||'('||pTABCOLLIST(L_ROW).COLLIST||') SELECT '||pTABCOLLIST(L_ROW).COLLIST|| ' FROM '||pSINGLETBNAME||'@'||pLINKNAME; PKG_DBMANAGE.DELETE_TABLE(pUSER,pSINGLETBNAME) ; --清空本地數據庫表記錄 EXECUTE IMMEDIATE pINSERTTEXT; --同步連接庫表數據到本地庫表中 SYS.DBMS_OUTPUT.PUT_LINE('同步表:'||pSINGLETBNAME||'數據成功!') ; END LOOP; CLOSE pRFECUR; EXCEPTION WHEN OTHERS THEN SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'同步表數據出錯:'||SQLERRM||',發生在表:'||pSINGLETBNAME) ; ROLLBACK; END; PROCEDURE MERGE_FROM_DB --功能:同步本地數據庫表,根據列名相同原則來匹配,pTABLENAME爲NULL則同步全部表的記錄,不爲NULL則同步一個或多個表的記錄,多個表以','分隔 -- 注意:只能從低版本數據源往同版本或高版本目標庫同步(即目標庫中的表同名列數、類型大於或等於源表列數,同時目標庫中不能存在不爲空的新列, -- 以保證能夠兼容添加數據到目標庫中,不然則可能同步出錯) --參數:見下方說明 --調用:EXECUTE PKG_MERGE.MERGE_FROM_DB('DBLINK'); --日期:2013-03-28 ( pLINKNAME IN VARCHAR2, --連接名 pTABLENAME IN VARCHAR2:=NULL, --本地數據庫同步表,多個表以','分隔 pTABLEEXIXTS IN VARCHAR2:='DELETE' --本地表存在的處理方式 ) --本地表存在的處理方式: --'RECOVER'-全部表全覆蓋、 --'DROP'-先刪除本地表再建立新表,表結構和數據與連接庫表保持一致、 --'DELETE'-直接刪除表數據再添加、'APPEND'-追加 AS pCOLLIST VARCHAR2(32767); pCOUNT1 PLS_INTEGER; pCOUNT2 PLS_INTEGER; pUSER VARCHAR2(200):=USER; pSQLTEXT VARCHAR2(2000); pRFECUR SYS_REFCURSOR; pSINGLETBNAME SYS.DBA_TABLES.TABLE_NAME%TYPE; BEGIN IF pTABLEEXIXTS='RECOVER' THEN --模式選擇爲全覆蓋 PKG_DBMANAGE.DROP_ALL_OBJECT(pUSER,8); --刪除全部表 END IF; pSQLTEXT:='SELECT TABLE_NAME FROM SYS.DBA_TABLES@'||pLINKNAME||' TA WHERE (INSTR('',''||'''|| pTABLENAME||'''||'','','',''||TABLE_NAME||'','',1)>0 OR '''||pTABLENAME|| ''' IS NULL) AND TA.TEMPORARY=''N'' AND OWNER='''||pUSER||''''; --查詢過濾連接表 OPEN pRFECUR FOR pSQLTEXT; --臨時表不作處理 LOOP FETCH pRFECUR INTO pSINGLETBNAME; EXIT WHEN pRFECUR%NOTFOUND; EXECUTE IMMEDIATE 'SELECT COUNT(1) FROM '||pSINGLETBNAME||'@'||pLINKNAME INTO pCOUNT1; EXECUTE IMMEDIATE 'SELECT LISTAGG(''"''||COLUMN_NAME||''"'','','') WITHIN GROUP(ORDER BY COLUMN_ID) FROM SYS.DBA_TAB_COLUMNS@'|| pLINKNAME||'WHERE OWNER=USER AND TABLE_NAME='''||pSINGLETBNAME||''' AND DATA_TYPE<>''LONG''' INTO pCOLLIST; --'LONG'類型沒法進行處理 IF pCOUNT1>0 THEN --連接數據庫表數據不爲空 EXECUTE IMMEDIATE 'SELECT COUNT(TABLE_NAME) FROM SYS.USER_TABLES WHERE TABLE_NAME=:v1' INTO pCOUNT2 using pSINGLETBNAME; IF pCOUNT2=1 THEN --本地表存在 IF UPPER(pTABLEEXIXTS)='DROP' THEN --模式選擇刪除本地表再建立新表 EXECUTE IMMEDIATE 'DROP TABLE '||pSINGLETBNAME||' CASCADE CONSTRAINTS'; ELSIF UPPER(pTABLEEXIXTS)='DELETE' THEN --模式選擇直接刪除表數據再添加 PKG_DBMANAGE.DELETE_TABLE(pUSER,pSINGLETBNAME); --清空本地數據庫表記錄 END IF; END IF; IF pCOUNT2=0 OR UPPER(pTABLEEXIXTS) IN ('DROP','RECOVER') THEN --本地數據庫表不存在 或者模式選擇刪除本地表再建立新表,此種方式不能創建表約束和索引 EXECUTE IMMEDIATE 'CREATE TABLE '||pSINGLETBNAME||' AS SELECT '||pCOLLIST||' FROM '||pSINGLETBNAME||'@'||pLINKNAME; END IF; IF UPPER(pTABLEEXIXTS) NOT IN ('DROP','REVOVER') THEN --添加連接數據庫表數據到本地表中 EXECUTE IMMEDIATE 'INSERT INTO '||pSINGLETBNAME||'('||pCOLLIST||') SELECT '||pCOLLIST||' FROM '||pSINGLETBNAME||'@'||pLINKNAME; END IF; END IF; END LOOP; CLOSE pRFECUR; COMMIT; IF UPPER(pTABLEEXIXTS) IN ('DROP','REVOVER') THEN PKG_DBMANAGE.RECOMPILE_ALL_PROJECT(pUSER); --表被刪除,須要從新編譯全部結構 END IF; EXCEPTION WHEN OTHERS THEN SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'同步本地表出錯:'||SQLERRM||',發生在表:'||pSINGLETBNAME); ROLLBACK; END; PROCEDURE MERGE_TO_DB --功能:同步連接數據庫表,根據列名相同原則來匹配,pTABLENAME爲NULL則同步全部表的記錄,不爲NULL則同步一個或多個表的記錄,多個表以','分隔 -- 注意:只能從低版本數據源往同版本或高版本目標庫同步(即目標庫中的表同名列數、類型大於或等於源表列數,同時目標庫中不能存在不爲空的新列, -- 以保證能夠兼容添加數據到目標庫中,不然則可能同步出錯) --參數:見下方說明 --調用:EXECUTE PKG_MERGE.MERGE_TO_DB('DBLINK'); --日期:2013-03-28 ( pLINKNAME IN VARCHAR2, --連接名 pTABLENAME IN VARCHAR2:=NULL, --連接數據庫同步表,多個表以','分隔 pTABLEEXIXTS IN VARCHAR2:='DELETE' --連接表存在的處理方式:'DELETE'-直接刪除表數據再添加、'APPEND'-追加 ) AS pSINGLETBNAME VARCHAR2(100); pCOLLIST VARCHAR2(32767); pCOUNT1 PLS_INTEGER; pCOUNT2 PLS_INTEGER; pUSER VARCHAR2(200):=USER; BEGIN FOR X IN ( SELECT TABLE_NAME FROM SYS.DBA_TABLES WHERE OWNER=pUSER AND(INSTR(','||pTABLENAME||',',','||TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL) AND TEMPORARY='N' ) LOOP pSINGLETBNAME:=X.TABLE_NAME; EXECUTE IMMEDIATE 'SELECT COUNT(1) FROM '||pUSER||'.'||pSINGLETBNAME INTO pCOUNT1; SELECT LISTAGG('"'||COLUMN_NAME||'"',',') WITHIN GROUP(ORDER BY COLUMN_ID) INTO pCOLLIST FROM SYS.DBA_TAB_COLUMNS WHERE OWNER=pUSER AND TABLE_NAME=pSINGLETBNAME AND DATA_TYPE<>'LONG'; IF pCOUNT1>0 THEN --本地數據庫表數據不爲空 EXECUTE IMMEDIATE 'SELECT COUNT(TABLE_NAME) FROM SYS.USER_TABLES@'||pLINKNAME||' WHERE TABLE_NAME=:v1' INTO pCOUNT2 USING pSINGLETBNAME; IF pCOUNT2=1 THEN IF UPPER(pTABLEEXIXTS)='DELETE' THEN EXECUTE IMMEDIATE 'DELETE FROM '||X.TABLE_NAME||'@'||pLINKNAME; --先清空連接數據庫表記錄在進行添加 END IF; EXECUTE IMMEDIATE 'INSERT INTO '||pSINGLETBNAME||'@'||pLINKNAME||'('||pCOLLIST||') SELECT '||pCOLLIST||' FROM '||pUSER||'.'||pSINGLETBNAME; END IF; END IF; END LOOP; COMMIT; EXCEPTION WHEN OTHERS THEN SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'同步遠程表出錯:'||SQLERRM||',發生在表:'||pSINGLETBNAME) ; ROLLBACK; END; END; / create or replace PACKAGE PKG_GET_INSERT AS --功能:獲取用戶下表記錄的INSERT語句的的查詢SQL語句 PROCEDURE GET_INSERT_SQL( DBUSER IN VARCHAR2:=USER, --用戶名 pTBLIST IN VARCHAR2:=NULL, --表和where條件的鏈接,多個鏈接用','分隔,注意:where條件中不能有','不然將出現分割錯誤,表名按照在字符串中前後位置排序 pMERGER IN NUMBER:=0, --Insert語句的操做模式 pENDSTR IN VARCHAR2:=';', --每條Inser語句的結束符,默認以';'結束,這樣能夠進行批量執行 pDELQLTEXT OUT CLOB, --獲取刪除表記錄的SQL語句字符串 pINSERSQLTEXT OUT CLOB --獲取添加表記錄的SQL語句字符串 ); --功能:獲取用戶下遠程連接表記錄的INSERT語句的的查詢SQL語句 PROCEDURE GET_REMOTEINSERT_SQL( pLINKNAME IN VARCHAR2, --遠程連接名稱 DBUSER IN VARCHAR2:=NULL, --遠程連接用戶名,爲空則採用連接用戶名,默認爲空 pTBLIST IN VARCHAR2:=NULL, --表和where條件的鏈接,多個鏈接用','分隔,注意:where條件中不能有','不然將出現分割錯誤,表名按照在字符串中前後位置排序 pMERGER IN NUMBER:=0, --Insert語句的操做模式 pENDSTR IN VARCHAR2:=';', --每條Inser語句的結束符,默認以';'結束,這樣能夠進行批量執行 pSQLTEXT OUT CLOB --SQL語句字符串 ); --功能:獲取用戶下表記錄的INSERT語句 PROCEDURE GET_ALL_INSERT( DBUSER IN VARCHAR2:=USER, --用戶名 pTBLIST IN VARCHAR2:=NULL, --表和where條件的鏈接,多個鏈接用','分隔,注意:where條件中不能有','不然將出現分割錯誤,表名按照在字符串中前後位置排序 pMERGER IN NUMBER:=0, --Insert語句的操做模式 pENDSTR IN VARCHAR2:=';', --每條Inser語句的結束符,默認以';'結束,這樣能夠進行批量執行 pCURSOR OUT SYS_REFCURSOR ); --功能:獲取用戶下遠程連接表記錄的INSERT語句 PROCEDURE GET_ALL_REMOTEINSERT( pLINKNAME IN VARCHAR2, --遠程連接名稱 DBUSER IN VARCHAR2:=USER, --用戶名 pTBLIST IN VARCHAR2:=NULL, --表和where條件的鏈接,多個鏈接用','分隔,注意:where條件中不能有','不然將出現分割錯誤,表名按照在字符串中前後位置排序 pMERGER IN NUMBER:=0, --Insert語句的操做模式 pENDSTR IN VARCHAR2:=';', --每條Inser語句的結束符,默認以';'結束,這樣能夠進行批量執行 pCURSOR OUT SYS_REFCURSOR ); --功能:保存用戶下表記錄的INSERT語句到文件中 PROCEDURE SAVE_ALL_INSERT( pLINKNAME IN VARCHAR2:=NULL, --遠程連接名稱,爲空則使用本地表,默認採用本地表 DBUSER IN VARCHAR2:=USER, --用戶名 pTBLIST IN VARCHAR2:=NULL, --表和where條件的鏈接 pMERGER IN NUMBER:=0, --Insert語句的操做模式 DIR IN VARCHAR2:='DATA_PUMP_DIR',--目錄名稱(若是不填,則使用當前數據庫目錄) FILENAME IN VARCHAR:=NULL --保存文件名稱 ); --功能:獲取表數據進行Loader格式輸出 PROCEDURE GET_LOADER_SQL( DBUSER IN VARCHAR2:=USER, --用戶名 pTBNAME IN VARCHAR2:=NULL, --表和where條件的鏈接 pSEP IN VARCHAR2:='|', --分隔符 pSQLTEXT OUT CLOB --SQL語句字符串 ); END; / create or replace PACKAGE BODY PKG_GET_INSERT AS PROCEDURE GET_INSERT_SQL --功能:獲取用戶下表記錄的INSERT語句的的查詢SQL語句 --參數: --調用: /* DECLARE pSQLTEXT1 CLOB; pSQLTEXT2 CLOB; BEGIN PKG_GET_INSERT.GET_INSERT_SQL('DKGLL','DEV_INFOEXTAB',0,';',pSQLTEXT,pSQLTEXT2); dbms_output.put_line(pSQLTEXT2); END; */ --日期:2013-04-11 ( DBUSER IN VARCHAR2:=USER, --用戶名 pTBLIST IN VARCHAR2:=NULL, --表和where條件的鏈接,多個鏈接用','分隔,注意:where條件中不能有','不然將出現分割錯誤,表名按照在字符串中前後位置排序 pMERGER IN NUMBER:=0, --Insert語句的操做模式 pENDSTR IN VARCHAR2:=';', --每條Inser語句的結束符,默認以';'結束,這樣能夠進行批量執行 pDELQLTEXT OUT CLOB, --獲取刪除表記錄的SQL語句字符串 pINSERSQLTEXT OUT CLOB --獲取添加表記錄的SQL語句字符串 ) ------------------------------------------------------------------------------------------------------------------ --Insert語句的操做模式(pMERGER參數)值詳細說明: --0:默認值,非嚴格模式.不判斷Insert語句的每一行在表中是否存在-Insert Into TableName(Col1,Col2,Col3..) Values(Value1,Value2,Value3..) --1:中間模式.若是表中有主鍵或者惟一約束不判斷Insert語句的每一行在表中是否存在,這樣在執行Insert記錄的時候可能會報主鍵衝突或者違反惟一約束的錯誤,但會添加失敗,格式同0 -- 若是表中既無主鍵也無惟一約束,則要進行判斷Insert語句的每一行在表中是否存在(經過每一列字段的值進行判斷),拼接格式以下: -- Insert Into TableName(Col1,Col2,Col3..) Select Value1,Value2,Value3.. From Dual -- Where Not Exists( -- Select * From TableName Where Col1=Value1 And Col2=Value2 And Col3=Value3 And.. -- ) --其餘值:嚴格模式.不管表中是否存在主鍵或者惟一約束,均需判斷Insert語句的每一行在表中是否存在,這樣在執行Insert記錄的時候就不會報主鍵衝突或者違反惟一約束的錯誤,格式如上 ------------------------------------------------------------------------------------------------------------------ --獲取INSERT語句的的查詢SQL語句格式以下: --說明:經過UNION ALL鏈接多個表的查詢;LONG列和LOB列沒法處理被過濾掉;列拼接長度大於4000字節時會報鏈接字符串長度過長的錯誤,經過TO_CLOB函數強制轉換成CLOB類型 --SELECT 'TABLENAME' AS TABLENAME, -- TO_CLOB('INSERT INTO TABLENAME("COLUMN1","COLUMN2","COLUMN3") SELECT ')|| -- CASE WHEN "COLUMN1" IS NULL THEN TO_CLOB('NULL') ELSE TO_CLOB('''')||"COLUMN1"||'''' END||','|| -- CASE WHEN "COLUMN2" IS NULL THEN TO_CLOB('NULL') ELSE TO_CLOB('''')||"COLUMN2"||'''' END||','|| -- CASE WHEN "COLUMN3" IS NULL THEN 'NULL' ELSE 'TO_DATE('''||TO_CHAR("COLUMN3",'YYYY-MM-DD HH24:MI:SS')||''',''YYYY-MM-DD HH24:MI:SS'')' END||' -- FROM DUAL -- WHERE NOT EXISTS( -- SELECT * FROM TABLENAME WHERE "COLUMN1"'|| -- CASE WHEN "COLUMN1" IS NULL THEN TO_CLOB('IS NULL') ELSE TO_CLOB('=''')||"COLUMN1"||'''' END||' AND "COLUMN1"'|| -- CASE WHEN "COLUMN2" IS NULL THEN TO_CLOB('IS NULL') ELSE TO_CLOB('=''')||"COLUMN2"||'''' END||' AND "COLUMN2"'|| -- CASE WHEN "COLUMN3" IS NULL THEN 'IS NULL' ELSE '=TO_DATE('''||TO_CHAR("COLUMN3",'YYYY-MM-DD HH24:MI:SS')||''',''YYYY-MM-DD HH24:MI:SS'')' END||' -- );' AS CONTEN FROM TABLENAME -- UNION ALL -- SELECT ... ------------------------------------------------------------------------------------------------------------------ AS pUSER VARCHAR2(200):=COALESCE(UPPER(DBUSER),USER); SINGLECOL VARCHAR2(4000); --單列值 COL CLOB; --Insert列名 VAL CLOB; --Insert列值 CONSCOL CLOB; --重複條件判斷列值 CONSTR CLOB; --重複條件判斷拼接字符串,格式如Col1=Value1 And Col2=Value2 And Col3=Value3 And.. SINGLETXT1 CLOB; --保存單表的完整Delete語句 SINGLETXT2 CLOB; --保存單表的完整Inser語句 REPLACENAME VARCHAR2(30); pSINGLENAME VARCHAR2(30); BEGIN FOR X IN ( SELECT DISTINCT MIN(RN) OVER(PARTITION BY TBNAME) AS MINRN,TBNAME,WHERESTR,HASCONSTRAINT FROM( SELECT RN,TBNAME,WHERESTR,CASE WHEN TC.TABLE_NAME IS NULL THEN 'NO' ELSE 'YES' END AS HASCONSTRAINT FROM( SELECT RN,DECODE(ISWHERE,0,TBNAME,SUBSTR(TBNAME,1,INSTR(TBNAME,'WHERE')-2)) AS TBNAME, DECODE(ISWHERE,0,'',SUBSTR(TBNAME,INSTR(TBNAME,'WHERE'))) AS WHERESTR FROM ( SELECT RN,TBNAME,INSTR(TBNAME,'WHERE') AS ISWHERE FROM ( SELECT LEVEL AS RN,REGEXP_SUBSTR(UPPER(pTBLIST),'[^,]+',1,LEVEL) AS TBNAME FROM DUAL CONNECT BY LEVEL<LENGTH(pTBLIST)-LENGTH(REPLACE(pTBLIST,','))+2 ) UNION SELECT 0 AS RN,TABLE_NAME AS TBNAME,INSTR(TABLE_NAME,'WHERE') AS ISWHERE FROM SYS.DBA_TABLES WHERE OWNER=pUSER AND pTBLIST IS NULL AND TEMPORARY='N' ) ) TB LEFT JOIN SYS.DBA_CONSTRAINTS TC ON (TB.TBNAME=TC.TABLE_NAME AND TC.OWNER=pUSER AND TC.CONSTRAINT_TYPE IN('P','U')) WHERE TBNAME IS NOT NULL ) ORDER BY MINRN --表名按照在字符串中前後位置進行排序,注意:若是表名在字符串中重複出現,若where條件相同則只取該表一次,若條件不一樣則仍然讀取屢次 ) LOOP BEGIN pSINGLENAME:=X.TBNAME; COL:='SELECT '''||pSINGLENAME||''' AS TABLENAME,TO_CLOB(''INSERT INTO '||pSINGLENAME||'('; VAL:=''; --每一次循環清空上一次的值 CONSTR:=''; FOR Y IN ( SELECT B.COLUMN_NAME,B.DATA_TYPE FROM SYS.DBA_TABLES A JOIN SYS.DBA_TAB_COLUMNS B ON(A.OWNER=B.OWNER AND A.TABLE_NAME=B.TABLE_NAME) WHERE A.OWNER=pUSER AND A.TABLE_NAME=pSINGLENAME AND B.DATA_TYPE NOT LIKE '%LOB' AND B.DATA_TYPE NOT LIKE '%LONG' ORDER BY B.COLUMN_ID ) LOOP SINGLECOL:=CHR(10)||'CASE WHEN "'||Y.COLUMN_NAME||'" IS NULL THEN '; ------------------------------------------------------------------------------------------------------------ --此部分解決當字段長度大於等於4000時報字符串鏈接過長的錯誤,若是是非數字和日期類型(此類型長度較小)則統一強制轉換成CLOB類型 IF Y.DATA_TYPE NOT IN('NUMBER','DATE') THEN CONSCOL:=SINGLECOL||'TO_CLOB('' IS NULL'') ELSE TO_CLOB(''='; VAL:=VAL||SINGLECOL||'TO_CLOB(''NULL'') ELSE TO_CLOB('; ELSE CONSCOL:=SINGLECOL||''' IS NULL'' ELSE ''='; VAL:=VAL||SINGLECOL||'''NULL'' ELSE '; ------------------------------------------------------------------------------------------------------------ END IF; IF Y.DATA_TYPE='NUMBER' THEN --數值類型不帶引號 SINGLECOL:='''||"'||Y.COLUMN_NAME||'"||''''' ; CONSCOL:=CONSCOL||SINGLECOL; VAL:=VAL||''''||SINGLECOL; ELSIF Y.DATA_TYPE='DATE' THEN --日期類型進行轉換 SINGLECOL:='TO_DATE(''''''||TO_CHAR("'||Y.COLUMN_NAME||'",''YYYY-MM-DD HH24:MI:SS'')||'''''',''''YYYY-MM-DD HH24:MI:SS'''')'''; CONSCOL:=CONSCOL||SINGLECOL; VAL:=VAL||''''||SINGLECOL; ELSE --其餘類型帶引號 SINGLECOL:=''''''')||"'||Y.COLUMN_NAME||'"||'''''''''; CONSCOL:=CONSCOL||SINGLECOL; VAL:=VAL||''''||SINGLECOL; END IF; VAL:=VAL||' END||'',''||'; SELECT '"'||REPLACE(Y.COLUMN_NAME,'''','''''')||'"' INTO REPLACENAME FROM DUAL; COL:=COL||REPLACENAME||','; CONSTR:=CONSTR||REPLACENAME||'''||'||CONSCOL||' END||'' AND '; END LOOP; IF VAL IS NOT NULL THEN --若是字段列表爲空(由於clob字段不給與處理),則不處理該表 IF (pMERGER=1 AND X.HASCONSTRAINT='NO') OR pMERGER NOT IN(0,1) THEN --判斷記錄的每一行在表中是否存在 SELECT SUBSTR(COL,1,LENGTH(COL)-1) ||') SELECT '')||'|| SUBSTR(VAL,1,LENGTH(VAL)-4) ||' FROM DUAL'||CHR(10)|| ' WHERE NOT EXISTS('||CHR(10)|| ' SELECT * FROM '||pSINGLENAME||' WHERE '||SUBSTR(CONSTR,1,LENGTH(CONSTR)-4)||CHR(10)|| ' )'||pENDSTR||''' AS CONTEN FROM '|| pSINGLENAME||' '||X.WHERESTR INTO SINGLETXT2 FROM DUAL; ELSE --有主見或者惟一約束或者容許添加劇復記錄,則直接爲通常的Insert Into格式 SELECT SUBSTR(COL,1,LENGTH(COL)-1) ||') VALUES('')||'|| SUBSTR(VAL,1,LENGTH(VAL)-4)|| ')'||pENDSTR||''' AS CONTEN FROM '|| pSINGLENAME||' '||X.WHERESTR INTO SINGLETXT2 FROM DUAL; END IF; SINGLETXT1:='SELECT '''||pSINGLENAME||''' AS TABLENAME,''DELETE FROM '||pSINGLENAME||' WHERE '||SUBSTR(CONSTR,1,LENGTH(CONSTR)-4)||''' AS CONTEN FROM '||pSINGLENAME; --獲取刪除表記錄的SQL語句字符串 IF pDELQLTEXT IS NULL THEN pDELQLTEXT:=SINGLETXT1; --單表的Delete查詢語句 ELSE --經過Union All方式來拼接全部的查詢語句 pDELQLTEXT:=pDELQLTEXT||' UNION ALL '||SINGLETXT1; END IF; --獲取添加表記錄的SQL語句字符串 IF pINSERSQLTEXT IS NULL THEN pINSERSQLTEXT:=SINGLETXT2; --單表的Insert查詢語句 ELSE --經過Union All方式來拼接全部的查詢語句 pINSERSQLTEXT:=pINSERSQLTEXT||' UNION ALL '||SINGLETXT2; END IF; END IF; END; END LOOP; IF pINSERSQLTEXT IS NULL THEN pINSERSQLTEXT:='SELECT NULL AS TABLENAME,DUMMY AS CONTEN FROM DUAL WHERE 1=2'; --修正查詢動態SQL爲空報錯的bug END IF; --SYS.DBMS_OUTPUT.PUT_LINE('/*SQL語句:*/'||pSQLTEXT); EXCEPTION WHEN OTHERS THEN SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'導出表出錯:'||SQLERRM||',發生在表:'||pSINGLENAME); NULL; END; PROCEDURE GET_REMOTEINSERT_SQL --功能:獲取用戶下遠程連接表記錄的INSERT語句的的查詢SQL語句 --參數: --調用: /* DECLARE pSQLTEXT CLOB; BEGIN PKG_GET_INSERT.GET_REMOTEINSERT_SQL('DATABASE_LINK1',NULL,'DEV_INFOEXTAB',0,';',pSQLTEXT); dbms_output.put_line(pSQLTEXT); END; */ --日期:2013-04-11 ( pLINKNAME IN VARCHAR2, --遠程連接名稱 DBUSER IN VARCHAR2:=NULL, --遠程連接用戶名,爲空則採用連接用戶名,默認爲空 pTBLIST IN VARCHAR2:=NULL, --表和where條件的鏈接,多個鏈接用','分隔,注意:where條件中不能有','不然將出現分割錯誤,表名按照在字符串中前後位置排序 pMERGER IN NUMBER:=0, --Insert語句的操做模式 pENDSTR IN VARCHAR2:=';', --每條Inser語句的結束符,默認以';'結束,這樣能夠進行批量執行 pSQLTEXT OUT CLOB --SQL語句字符串 ) AS pUSER VARCHAR2(200); SINGLECOL VARCHAR2(4000); --單列值 COL CLOB; --Insert列名 VAL CLOB; --Insert列值 CONSCOL CLOB; --重複條件判斷列值 CONSTR CLOB; --重複條件判斷拼接字符串,格式如Col1=Value1 And Col2=Value2 And Col3=Value3 And.. SINGLETXT CLOB; --保存單表的完整Inser語句 REPLACENAME VARCHAR2(30); --替換後的列名集合 pMINRN PLS_INTEGER; --最小行號 pSINGLENAME VARCHAR2(30); --單表名稱 pWHERESTR VARCHAR2(4000); --where條件字符串 pHASCON VARCHAR2(10); --是否有約束或主鍵 pCOLNAME VARCHAR2(50); --列名 pDATATYPE VARCHAR2(100); --列數據類型 pTBCURSOR SYS_REFCURSOR; --表記錄遊標 pCOLCURSOR SYS_REFCURSOR; --列類型遊標 pSELTBTEXT VARCHAR2(4000); --查詢表記錄的sql語句 pSELCOLTEXT VARCHAR2(4000); --查詢列類型記錄的sql語句 BEGIN IF pLINKNAME IS NOT NULL THEN --若是連接名稱不爲空 IF DBUSER IS NULL THEN --若是名稱爲空則採用連接用戶名 SELECT USERNAME INTO pUSER FROM SYS.DBA_DB_LINKS WHERE DB_LINK=pLINKNAME AND OWNER=USER; ELSE pUSER:=DBUSER; END IF; pSELTBTEXT:= 'SELECT DISTINCT MIN(RN) OVER(PARTITION BY TBNAME) AS MINRN,TBNAME,WHERESTR,HASCONSTRAINT FROM( SELECT RN,TBNAME,WHERESTR,CASE WHEN TC.TABLE_NAME IS NULL THEN ''NO'' ELSE ''YES'' END AS HASCONSTRAINT FROM( SELECT RN,DECODE(ISWHERE,0,TBNAME,SUBSTR(TBNAME,1,INSTR(TBNAME,''WHERE'')-2)) AS TBNAME, DECODE(ISWHERE,0,'''',SUBSTR(TBNAME,INSTR(TBNAME,''WHERE''))) AS WHERESTR FROM ( SELECT RN,TBNAME,INSTR(TBNAME,''WHERE'') AS ISWHERE FROM ( SELECT LEVEL AS RN,REGEXP_SUBSTR(UPPER('''||pTBLIST||'''),''[^,]+'',1,LEVEL) AS TBNAME FROM DUAL CONNECT BY LEVEL<LENGTH('''||pTBLIST||''')-LENGTH(REPLACE('''||pTBLIST||''','',''))+2 ) UNION SELECT 0 AS RN,TABLE_NAME AS TBNAME,INSTR(TABLE_NAME,''WHERE'') AS ISWHERE FROM SYS.DBA_TABLES@'||pLINKNAME||' WHERE OWNER='''||pUSER||''' AND '''||pTBLIST||''' IS NULL AND TEMPORARY=''N'' ) ) TB LEFT JOIN SYS.DBA_CONSTRAINTS@'||pLINKNAME||' TC ON (TB.TBNAME=TC.TABLE_NAME AND TC.OWNER='''||pUSER||''' AND TC.CONSTRAINT_TYPE IN(''P'',''U'')) WHERE TBNAME IS NOT NULL ) ORDER BY MINRN '; OPEN pTBCURSOR FOR pSELTBTEXT; LOOP FETCH pTBCURSOR INTO pMINRN,pSINGLENAME,pWHERESTR,pHASCON; EXIT WHEN pTBCURSOR%NOTFOUND; COL:='SELECT '''||pSINGLENAME||''' AS TABLENAME,TO_CLOB(''INSERT INTO '||pSINGLENAME||'('; VAL:=''; --每一次循環清空上一次的值 CONSTR:=''; pSELCOLTEXT:='SELECT B.COLUMN_NAME,B.DATA_TYPE FROM SYS.DBA_TABLES@'||pLINKNAME||' A JOIN SYS.DBA_TAB_COLUMNS@'||pLINKNAME||' B ON(A.OWNER=B.OWNER AND A.TABLE_NAME=B.TABLE_NAME) WHERE A.OWNER='''||pUSER||''' AND A.TABLE_NAME='''||pSINGLENAME||''' AND B.DATA_TYPE NOT LIKE ''%LOB'' AND B.DATA_TYPE NOT LIKE ''%LONG'' ORDER BY B.COLUMN_ID'; OPEN pCOLCURSOR FOR pSELCOLTEXT; LOOP FETCH pCOLCURSOR INTO pCOLNAME,pDATATYPE; EXIT WHEN pCOLCURSOR%NOTFOUND; SINGLECOL:='CASE WHEN "'||pCOLNAME||'" IS NULL THEN '; ------------------------------------------------------------------------------------------------------------ --此部分解決當字段長度大於等於4000時報字符串鏈接過長的錯誤,若是是非數字和日期類型(此類型長度較小)則統一強制轉換成CLOB類型 IF pDATATYPE NOT IN('NUMBER','DATE') THEN CONSCOL:=SINGLECOL||'TO_CLOB('' IS NULL'') ELSE TO_CLOB(''='; VAL:=VAL||SINGLECOL||'TO_CLOB(''NULL'') ELSE TO_CLOB('; ELSE CONSCOL:=SINGLECOL||''' IS NULL'' ELSE ''='; VAL:=VAL||SINGLECOL||'''NULL'' ELSE '; ------------------------------------------------------------------------------------------------------------ END IF; IF pDATATYPE='NUMBER' THEN --數值類型不帶引號 SINGLECOL:='''||"'||pCOLNAME||'"||''''' ; CONSCOL:=CONSCOL||SINGLECOL; VAL:=VAL||''''||SINGLECOL; ELSIF pDATATYPE='DATE' THEN --日期類型進行轉換 SINGLECOL:='TO_DATE(''''''||TO_CHAR("'||pCOLNAME||'",''YYYY-MM-DD HH24:MI:SS'')||'''''',''''YYYY-MM-DD HH24:MI:SS'''')'''; CONSCOL:=CONSCOL||SINGLECOL; VAL:=VAL||''''||SINGLECOL; ELSE --其餘類型帶引號 SINGLECOL:=''''''')||"'||pCOLNAME||'"||'''''''''; CONSCOL:=CONSCOL||SINGLECOL; VAL:=VAL||''''||SINGLECOL; END IF; VAL:=VAL||' END||'',''||'; SELECT '"'||REPLACE(pCOLNAME,'''','''''')||'"' INTO REPLACENAME FROM DUAL; COL:=COL||REPLACENAME||','; CONSTR:=CONSTR||REPLACENAME||'''||'||CONSCOL||' END||'' AND '; END LOOP; IF VAL IS NOT NULL THEN --若是字段列表爲空(由於clob字段不給與處理),則不處理該表 IF (pMERGER=1 AND pHASCON='NO') OR pMERGER NOT IN(0,1) THEN --判斷記錄的每一行在表中是否存在 SELECT SUBSTR(COL,1,LENGTH(COL)-1) ||') SELECT '')||'|| SUBSTR(VAL,1,LENGTH(VAL)-4) ||' FROM DUAL'||CHR(10)|| ' WHERE NOT EXISTS('||CHR(10)|| ' SELECT * FROM '||pSINGLENAME||' WHERE '||SUBSTR(CONSTR,1,LENGTH(CONSTR)-4)||CHR(10)|| ' )'||pENDSTR||''' AS CONTEN FROM '|| pSINGLENAME||'@'||pLINKNAME||' '||pWHERESTR INTO SINGLETXT FROM DUAL; ELSE --有主見或者惟一約束或者容許添加劇復記錄,則直接爲通常的Insert Into格式 SELECT SUBSTR(COL,1,LENGTH(COL)-1) ||') VALUES('')||'|| SUBSTR(VAL,1,LENGTH(VAL)-4)|| ')'||pENDSTR||''' AS CONTEN FROM '|| pSINGLENAME||'@'||pLINKNAME||' '||pWHERESTR INTO SINGLETXT FROM DUAL; END IF; IF pSQLTEXT IS NULL THEN pSQLTEXT:=SINGLETXT; --單表的Insert查詢語句 ELSE --經過Union All方式來拼接全部的查詢語句 pSQLTEXT:=pSQLTEXT||' UNION ALL '||SINGLETXT; END IF; END IF; END LOOP; IF pSQLTEXT IS NULL THEN pSQLTEXT:='SELECT NULL AS TABLENAME,DUMMY AS CONTEN FROM DUAL WHERE 1=2'; --修正查詢動態SQL爲空報錯的bug END IF; ELSE SYS.DBMS_OUTPUT.PUT_LINE('數據庫連接名稱不能爲空!'); END IF; --SYS.DBMS_OUTPUT.PUT_LINE('/*SQL語句:*/'||pSQLTEXT); EXCEPTION WHEN NO_DATA_FOUND THEN SYS.DBMS_OUTPUT.PUT_LINE('當前系統用戶下未找到數據庫連接'||pLINKNAME||',請檢查或新建數據庫連接!'); WHEN OTHERS THEN SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'導出遠程表出錯:'||SQLERRM||',發生在表:'||pSINGLENAME); NULL; END; PROCEDURE GET_ALL_INSERT --功能:獲取用戶下表記錄的INSERT語句 --參數: --調用: /* DECLARE PCURSOR SYS_REFCURSOR; BEGIN PKG_GET_INSERT.GET_ALL_INSERT('DKGLL','DEV_INFOEXTAB',0,';',PCURSOR); END; */ --日期:2013-04-11 ( DBUSER IN VARCHAR2:=USER, --用戶名 pTBLIST IN VARCHAR2:=NULL, --表和where條件的鏈接,多個鏈接用','分隔,注意:where條件中不能有','不然將出現分割錯誤,表名按照在字符串中前後位置排序 pMERGER IN NUMBER:=0, --Insert語句的操做模式 pENDSTR IN VARCHAR2:=';', --每條Inser語句的結束符,默認以';'結束,這樣能夠進行批量執行 pCURSOR OUT SYS_REFCURSOR ) AS pSQLTEXT1 CLOB; --SQL語句字符串 pSQLTEXT2 CLOB; --SQL語句字符串 BEGIN GET_INSERT_SQL(DBUSER,pTBLIST,pMERGER,pENDSTR,pSQLTEXT1,pSQLTEXT2); --獲取Insert腳本的查詢SQL語句 OPEN pCURSOR FOR pSQLTEXT1; END; PROCEDURE GET_ALL_REMOTEINSERT --功能:獲取用戶下遠程連接表記錄的INSERT語句 --參數: --調用: /* DECLARE PCURSOR SYS_REFCURSOR; BEGIN PKG_GET_INSERT.GET_ALL_REMOTEINSERT('DATABASE_LINK1',NULL,'dev_infoextab',0,';',PCURSOR); END; */ --日期:2013-04-11 ( pLINKNAME IN VARCHAR2, --遠程連接名稱 DBUSER IN VARCHAR2:=USER, --用戶名 pTBLIST IN VARCHAR2:=NULL, --表和where條件的鏈接,多個鏈接用','分隔,注意:where條件中不能有','不然將出現分割錯誤,表名按照在字符串中前後位置排序 pMERGER IN NUMBER:=0, --Insert語句的操做模式 pENDSTR IN VARCHAR2:=';', --每條Inser語句的結束符,默認以';'結束,這樣能夠進行批量執行 pCURSOR OUT SYS_REFCURSOR ) AS pUSER VARCHAR2(200):=COALESCE(UPPER(DBUSER),USER); pCOUNT PLS_INTEGER; pSQLTEXT CLOB; --SQL語句字符串 BEGIN SELECT COUNT(1) INTO pCOUNT FROM SYS.DBA_TABLES WHERE OWNER=pUSER AND TABLE_NAME='TEMP_REMOTEINSERT'; IF pCOUNT=0 THEN --保存insert數據的臨時表不存在則建立一個全局臨時表 pSQLTEXT:='CREATE GLOBAL TEMPORARY TABLE "'||pUSER||'"."TEMP_REMOTEINSERT" ('||CHR(10)|| ' TABLENAME VARCHAR2(50),'||CHR(10)|| ' CONTEN CLOB'||CHR(10)|| ') ON COMMIT PRESERVE ROWS'; ELSE --刪除臨時表數據 pSQLTEXT:='DELETE FROM TEMP_REMOTEINSERT'; END IF; EXECUTE IMMEDIATE pSQLTEXT; GET_REMOTEINSERT_SQL(pLINKNAME,DBUSER,pTBLIST,pMERGER,pENDSTR,pSQLTEXT); --獲取Insert腳本的查詢SQL語句 --LOB列數據沒法經過數據庫連接直接查詢,必須經過臨時表或者物化視圖方式查詢,不然會報ORA-22992: 沒法使用從遠程表選擇的 LOB 定位器的錯誤 --此處採用臨時表過分的方式查詢,經測試,經過臨時表插入遠程連接表數據16000條需耗時80秒,效率較低.此處的效率瓶頸在於CLOB字段和TO_CLOB函數運用上, --系統對於CLOB字段存儲在LOB段中,不管是本地仍是經過遠程連接存儲和查詢效率都較低,建議控制該字段長度,或者利用多個VARCHAR2字段代替CLOB字段 pSQLTEXT:='INSERT INTO TEMP_REMOTEINSERT SELECT TABLENAME,CONTEN FROM('||pSQLTEXT||') TB'; EXECUTE IMMEDIATE pSQLTEXT; OPEN pCURSOR FOR 'SELECT TABLENAME,CONTEN FROM TEMP_REMOTEINSERT'; EXCEPTION WHEN OTHERS THEN SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'獲取遠程表INSERT語句出錯:'||SQLERRM); ROLLBACK; END; PROCEDURE SAVE_ALL_INSERT --功能:保存用戶下表記錄或者遠程連接表記錄的INSERT語句到文件中 --參數: --調用: /* --保存本地數據 BEGIN PKG_GET_INSERT.SAVE_ALL_INSERT(NULL,USER,'DEV_INFOEXTAB',0,'BACKDIR','insert腳本0429.sql'); END; */ /* --保存遠程鏈接表數據 DECLARE PLINKNAME VARCHAR2(100);pCOUNT PLS_INTEGER; BEGIN PLINKNAME := 'DATABASE_LINK1'; PLINKNAME:=UPPER(PLINKNAME); SELECT COUNT(1) INTO pCOUNT FROM SYS.DBA_DB_LINKS WHERE OWNER=USER AND DB_LINK=PLINKNAME; DBMS_OUTPUT.PUT_LINE(pCOUNT); IF pCOUNT=0 THEN PKG_DBMANAGE.CREATE_DBLINK( PHOST => '172.16.3.251', PLINKDB => 'TBS1', PLINKUSER => 'DKGLL', PLINKPWD => 'DKGLL', PLINKNAME => PLINKNAME ); --創建數據庫連接 END IF; PKG_GET_INSERT.SAVE_ALL_INSERT(PLINKNAME,NULL,'dev_infoextab',0,'BACKDIR','insert腳本0428.sql'); END; */ --日期:2013-04-25 ( pLINKNAME IN VARCHAR2:=NULL, --遠程連接名稱,爲空則使用本地表,默認採用本地表 DBUSER IN VARCHAR2:=USER, --用戶名 pTBLIST IN VARCHAR2:=NULL, --表和where條件的鏈接 pMERGER IN NUMBER:=0, --Insert語句的操做模式 DIR IN VARCHAR2:='DATA_PUMP_DIR', --目錄名稱(若是不填,則使用當前數據庫目錄) FILENAME IN VARCHAR:=NULL --保存文件名稱 ) AS pSQLTEXT1 CLOB; pSQLTEXT2 CLOB; pFILED UTL_FILE.FILE_TYPE; pTABLENAME VARCHAR2(50); pCONTENT VARCHAR2(32767); --寫入文件的每一行最大值不能超過32767個字節 pRFECUR SYS_REFCURSOR; BEGIN IF pLINKNAME IS NULL THEN GET_INSERT_SQL(DBUSER,pTBLIST,pMERGER,';',pSQLTEXT1,pSQLTEXT2); --獲取Insert腳本的查詢SQL語句 OPEN pRFECUR FOR pSQLTEXT2; --轉換成遊標 ELSE GET_ALL_REMOTEINSERT(pLINKNAME,DBUSER,pTBLIST,pMERGER,';',pRFECUR); --獲取用戶下遠程連接表記錄的INSERT語句 END IF; --打開文件,限制每行最大字符數不能超過32767個字節數 pFILED:=SYS.UTL_FILE.FOPEN(DIR,NVL(FILENAME,'導出Insert腳本'||TO_CHAR(CURRENT_DATE,'YYYYMMDDHH24')||'.sql'),'W',32767); LOOP FETCH pRFECUR INTO pTABLENAME,pCONTENT; EXIT WHEN pRFECUR%NOTFOUND; SYS.UTL_FILE.PUT_LINE(pFILED,pCONTENT); --寫入文件,按照字節長度寫入文件,不能超過32767個字節數 END LOOP; SYS.UTL_FILE.FCLOSE(pFILED); --關閉文件 EXCEPTION WHEN OTHERS THEN SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'保存表數據出錯:'||SQLERRM||',發生在表:'||pTABLENAME) ; ROLLBACK; END; PROCEDURE GET_LOADER_SQL --功能:獲取表數據進行Loader格式輸出 --參數: --調用: /* DECLARE pSQLTEXT CLOB; BEGIN PKG_GET_INSERT.GET_LOADER_SQL('DKGLL','DEV_INFOEXTAB','|',pSQLTEXT); END; */ /* DECLARE PCURSOR SYS_REFCURSOR; pSQLTEXT CLOB; BEGIN PKG_GET_INSERT.GET_LOADER_SQL('DKGLL','TBUSERNAME',',',pSQLTEXT); --Loader格式表數據 --dbms_output.put_line(pSQLTEXT); OPEN PCURSOR FOR pSQLTEXT; PKG_DBMANAGE.CURSOR_TO_FILE('PKG_DBMANAGER_DIR','TBUSERNAME.txt',1,PCURSOR); --寫入指定目錄的外部表txt文件 PKG_DBMANAGE.CLONE_EXTERNAL_TB('PKG_DBMANAGER_DIR','TBUSERNAME'); --克隆生成外部表,查詢該表數據便可 END; */ --日期:2014-12-10 ( DBUSER IN VARCHAR2:=USER, --用戶名 pTBNAME IN VARCHAR2:=NULL, --表和where條件的鏈接 pSEP IN VARCHAR2:='|', --分隔符 pSQLTEXT OUT CLOB --SQL語句字符串 ) AS pUSER VARCHAR2(200):=COALESCE(UPPER(DBUSER),USER); pCOL VARCHAR2(4000); --單列值 pRFECUR SYS_REFCURSOR; BEGIN FOR Y IN ( SELECT B.COLUMN_NAME,B.DATA_TYPE FROM SYS.DBA_TABLES A JOIN SYS.DBA_TAB_COLUMNS B ON(A.OWNER=B.OWNER AND A.TABLE_NAME=B.TABLE_NAME) WHERE A.OWNER=pUSER AND A.TABLE_NAME=pTBNAME AND B.DATA_TYPE NOT LIKE '%LOB' AND B.DATA_TYPE NOT LIKE '%LONG' ORDER BY B.COLUMN_ID ) LOOP IF Y.DATA_TYPE='NUMBER' THEN --數值類型不帶引號 pCOL:='"'||Y.COLUMN_NAME||'"||'''||pSEP||'''||' ; ELSIF Y.DATA_TYPE='DATE' OR Y.DATA_TYPE LIKE 'TIMESTAMP%' THEN --日期類型進行轉換 pCOL:='TO_CHAR("'||Y.COLUMN_NAME||'",''YYYY-MM-DD HH24:MI:SS'')||'''||pSEP||'''||' ; ELSE --其餘類型帶引號 pCOL:='"'||Y.COLUMN_NAME||'"||'''||pSEP||'''||' ; END IF; pSQLTEXT:=pSQLTEXT||pCOL; END LOOP; pSQLTEXT:='SELECT RTRIM('||SUBSTR(pSQLTEXT,1,LENGTH(pSQLTEXT)-2)||','','') FROM '||pTBNAME; EXCEPTION WHEN OTHERS THEN SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'導出表出錯:'||SQLERRM||',發生在表:'||pTBNAME); NULL; END; END; / CREATE OR REPLACE PACKAGE PKG_TESTDATA AS --功能:獲取在用戶表中添加測試數據的文本 PROCEDURE GET_TEST_DATA( DBUSER IN VARCHAR2:=USER, pTBNAME IN VARCHAR2, pSQLTEXT OUT CLOB ); --功能:在用戶表中添加測試數據 PROCEDURE ADD_TEST_DATA( DBUSER IN VARCHAR2:=USER, pTBNAME IN VARCHAR2, pCOUNT IN NUMBER ); END; / CREATE OR REPLACE PACKAGE BODY PKG_TESTDATA AS PROCEDURE GET_TEST_DATA --功能:獲取在用戶表中添加測試數據的文本 --參數:DBUSER-用戶名,pTBNAME-表名,pSQLTEXT-返回測試數據文本 --調用: /* DECLARE pTXT CLOB; BEGIN PKG_TESTDATA.GET_TEST_DATA('DKGLL','USR_INFOTAB',pTXT); DBMS_OUTPUT.PUT_LINE(pTXT); END; */ --日期:2013-03-01 ( DBUSER IN VARCHAR2:=USER, pTBNAME IN VARCHAR2, pSQLTEXT OUT CLOB ) AS pUSER VARCHAR2(200):=COALESCE(UPPER(DBUSER),USER); Val VARCHAR2(4000):=''; Coltxt VARCHAR2(4000):=''; Valtxt VARCHAR2(4000):=''; BEGIN FOR X IN( SELECT TABLE_NAME,COLUMN_NAME,SQLTYPE, CASE SQLTYPE WHEN 'INT' THEN NVL(DATA_PRECISION,10) ELSE CHAR_LENGTH END AS CHARLENGTH,DATA_SCALE FROM( SELECT A.TABLE_NAME,B.COLUMN_NAME, CASE DATA_TYPE WHEN 'NUMBER' THEN 'INT' WHEN 'DECIMAL' THEN 'INT' WHEN 'NUMERIC' THEN 'INT' WHEN 'INT' THEN 'INT' WHEN 'FLOAT' THEN 'INT' WHEN 'SMALLINT' THEN 'INT' WHEN 'VARCHAR2' THEN 'STRING' WHEN 'DATE' THEN 'DATETIME' WHEN 'VARCHAR2' THEN 'STRING' WHEN 'NVARCHAR' THEN 'STRING' WHEN 'VARCHAR' THEN 'STRING' WHEN 'NVARCHAR' THEN 'STRING' WHEN 'CHAR' THEN 'STRING' WHEN 'NCHAR' THEN 'STRING' WHEN 'BLOB' THEN 'STRING' WHEN 'NBLOB' THEN 'STRING' WHEN 'CLOB' THEN 'STRING' WHEN 'NCLOB' THEN 'STRING' WHEN 'LONG' THEN 'STRING' ELSE NULL END AS SQLTYPE, B.DATA_PRECISION,B.CHAR_LENGTH, CASE WHEN B.DATA_SCALE IS NOT NULL THEN B.DATA_SCALE ELSE 0 END AS DATA_SCALE,B.COLUMN_ID FROM SYS.DBA_TABLES A JOIN SYS.DBA_TAB_COLUMNS B ON (A.OWNER=B.OWNER AND A.TABLE_NAME=B.TABLE_NAME) WHERE A.OWNER=pUSER AND A.TABLE_NAME=pTBNAME ) TB WHERE SQLTYPE IS NOT NULL ORDER BY TABLE_NAME,COLUMN_ID ) LOOP Coltxt:=Coltxt||',"'||X.COLUMN_NAME||'"'; IF X.SQLTYPE='INT' THEN --處理數字類型,採用隨機數 IF X.CHARLENGTH=1 THEN X.CHARLENGTH:=2; ELSIF X.CHARLENGTH>=11 THEN X.CHARLENGTH:=10; END IF; IF X.CHARLENGTH-X.DATA_SCALE>0 THEN X.CHARLENGTH:=X.CHARLENGTH-X.DATA_SCALE; Val:='TRUNC(DBMS_RANDOM.VALUE(RPAD(10,'||X.CHARLENGTH||'-1,0),RPAD(10,'||X.CHARLENGTH||',0)))'; ELSE Val:='0'; END IF; ELSIF X.SQLTYPE='STRING' THEN --處理字符類型,採用GUID類型 IF X.CHARLENGTH>=3999 OR X.CHARLENGTH=0 THEN X.CHARLENGTH:=3999; END IF; Val:='RPAD(SYS_GUID(),'||X.CHARLENGTH||',SYS_GUID())'; ELSE --處理日期類型,採用當前系統日期時間 Val:='SYSDATE'; END IF; Valtxt:=Valtxt||','||Val; END LOOP; pSQLTEXT:='INSERT INTO '||pTBNAME||' ('||SUBSTR(Coltxt,2)||') VALUES ('||SUBSTR(Valtxt,2)||')'; END; PROCEDURE ADD_TEST_DATA --功能:在用戶表中添加測試數據 --參數:DBUSER-用戶名,pTBNAME-表名,pCOUNT-添加條數 --調用:EXECUTE PKG_TESTDATA.ADD_TEST_DATA(NULL,'TABLE3',2); --日期:2013-03-01 ( DBUSER IN VARCHAR2:=USER, pTBNAME IN VARCHAR2, pCOUNT IN NUMBER ) AS pTXT CLOB; BEGIN GET_TEST_DATA(DBUSER,pTBNAME,pTXT); FOR X IN 1..pCOUNT LOOP EXECUTE IMMEDIATE pTXT; END LOOP; EXCEPTION WHEN OTHERS THEN SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'添加測試數據出錯:' ||SQLERRM); RAISE; END; END; / CREATE OR REPLACE PACKAGE PKG_CREATE_PROC AS --功能:獲取添加表記錄的存儲過程文本(注意過程名稱標識符不能超過30個字符) PROCEDURE GET_ADD_PROC( DBUSER IN VARCHAR2, --用戶 pTBNAME IN VARCHAR2, --表名,多個表以','分隔 pISLIKE IN NUMBER:=0, --表名是精確匹配仍是進行模糊搜索,默認爲精確查找 pADDSTR IN VARCHAR2:='ADD_', --過程標識符,默認過程名稱爲標識符加上表名 pPRESTR IN VARCHAR2:='p', --存儲過程參數前置標識符,默認爲小寫字母'p' pSQLTEXT OUT CLOB --返回添加表記錄的存儲過程文本 ); --功能:獲取修改表記錄的存儲過程文本(根據主鍵列修改,注意過程名稱標識符不能超過30個字符) PROCEDURE GET_UPDATE_PROC( DBUSER IN VARCHAR2, --用戶 pTBNAME IN VARCHAR2, --表名,多個表以','分隔 pISLIKE IN NUMBER:=0, --表名是精確匹配仍是進行模糊搜索,默認爲精確查找 pUPPERDATESTR IN VARCHAR2:='UPDATE_',--過程標識符,默認過程名稱爲標識符加上表名 pPRESTR IN VARCHAR2:='p', --存儲過程參數前置標識符,默認爲小寫字母'p' pSQLTEXT OUT CLOB --返回添加表記錄的存儲過程文本 ); --功能:獲取刪除表記錄的存儲過程文本(根據主鍵列刪除,注意過程名稱標識符不能超過30個字符) PROCEDURE GET_DELETE_PROC( DBUSER IN VARCHAR2, --用戶 pTBNAME IN VARCHAR2, --表名,多個表以','分隔 pISLIKE IN NUMBER:=0, --表名是精確匹配仍是進行模糊搜索,默認爲精確查找 pDELETESTR IN VARCHAR2:='DEL_', --過程標識符,默認過程名稱爲標識符加上表名 pPRESTR IN VARCHAR2:='p', --存儲過程參數前置標識符,默認爲小寫字母'p' pSQLTEXT OUT CLOB --返回添加表記錄的存儲過程文本 ); --功能:獲取用戶增長修改刪除標記裏的存儲過程文本(注意過程名稱標識符不能超過30個字符) PROCEDURE GET_DDL_PROC( DBUSER IN VARCHAR2, --用戶 pTBNAME IN VARCHAR2, --表名,多個表以','分隔 pISLIKE IN NUMBER:=0, --表名是精確匹配仍是進行模糊搜索,默認爲精確查找 pADDSTR IN VARCHAR2:='ADD_', --過程標識符,默認過程名稱爲標識符加上表名 pUPPERDATESTR IN VARCHAR2:='UPDATE_',--過程標識符,默認過程名稱爲標識符加上表名 pDELETESTR IN VARCHAR2:='DEL_', --過程標識符,默認過程名稱爲標識符加上表名 pPRESTR IN VARCHAR2:='p', --存儲過程參數前置標識符,默認爲小寫字母'p' pSQLTEXT OUT CLOB --返回添加表記錄的存儲過程文本 ); END; / CREATE OR REPLACE PACKAGE BODY PKG_CREATE_PROC AS PROCEDURE GET_ADD_PROC --功能:獲取添加表記錄的存儲過程文本(注意過程名稱標識符不能超過30個字符) --參數: --調用: /* DECLARE pSQLTEXT CLOB; BEGIN PKG_CREATE_PROC.GET_ADD_PROC(DBUSER=>NULL,pTBNAME=>'USR_INFOTAB,A,B,C,CC',pSQLTEXT=>pSQLTEXT); DBMS_OUTPUT.PUT_LINE(pSQLTEXT); END; */ --日期:2013-02-10 ( DBUSER IN VARCHAR2, --用戶 pTBNAME IN VARCHAR2, --表名,多個表以','分隔 pISLIKE IN NUMBER:=0, --表名是精確匹配仍是進行模糊搜索,默認爲精確查找 pADDSTR IN VARCHAR2:='ADD_', --過程標識符,默認過程名稱爲標識符加上表名 pPRESTR IN VARCHAR2:='p', --存儲過程參數前置標識符,默認爲小寫字母'p' pSQLTEXT OUT CLOB --返回添加表記錄的存儲過程文本 ) AS pUSER VARCHAR2(200):=COALESCE(UPPER(DBUSER),USER); pPROCNAME VARCHAR2(50); BEGIN FOR X IN ( SELECT DISTINCT TABLE_NAME, LISTAGG(' '||pPRESTR||COLUMN_NAME||' IN '||DATA_TYPE,','||CHR(10)) WITHIN GROUP(ORDER BY COLUMN_ID) OVER(PARTITION BY TABLE_NAME) AS PARALIST, LISTAGG(COLUMN_NAME,',') WITHIN GROUP(ORDER BY COLUMN_ID) OVER(PARTITION BY TABLE_NAME) AS COLLIST, LISTAGG(pPRESTR||COLUMN_NAME,',') WITHIN GROUP(ORDER BY COLUMN_ID) OVER(PARTITION BY TABLE_NAME) AS VALLIST FROM SYS.DBA_TAB_COLUMNS WHERE OWNER=pUSER AND ( (pISLIKE=0 AND INSTR(','||pTBNAME||',',','||TABLE_NAME||',',1)>0) OR (pISLIKE=1 AND TABLE_NAME LIKE '%'||pTBNAME||'%') ) ) LOOP pPROCNAME:=SUBSTR(X.TABLE_NAME,0,25); pSQLTEXT:=pSQLTEXT|| 'CREATE OR REPLACE PROCEDURE '||pADDSTR||pPROCNAME||CHR(10)|| '--功能:添加'||X.TABLE_NAME||'表記錄'||CHR(10)|| '--參數:'||CHR(10)|| '--調用:'||CHR(10)|| '--日期:'||TO_CHAR(SYSDATE,'YYYY-MM-DD')||CHR(10)|| '('||CHR(10)|| X.PARALIST||CHR(10)|| ')'||CHR(10)|| 'AS'||CHR(10)|| 'BEGIN'||CHR(10)|| ' INSERT INTO '||X.TABLE_NAME||'('||X.COLLIST||')'||CHR(10)|| ' VALUES('||X.VALLIST||');'||CHR(10)|| ' COMMIT;'||CHR(10)|| ' EXCEPTION'||CHR(10)|| ' WHEN OTHERS THEN'||CHR(10)|| ' ROLLBACK;'||CHR(10)|| 'END '||pADDSTR||pPROCNAME||';'||CHR(10)|| '/'||CHR(10); END LOOP; END; PROCEDURE GET_UPDATE_PROC --功能:獲取修改表記錄的存儲過程文本(根據主鍵列修改,注意標識符不能超過30個字符) --參數: --調用: /* DECLARE pSQLTEXT CLOB; BEGIN PKG_CREATE_PROC.GET_UPDATE_PROC(DBUSER=>NULL,pTBNAME=>'A',pSQLTEXT=>pSQLTEXT); DBMS_OUTPUT.PUT_LINE(pSQLTEXT); END; */ --日期:2013-02-10 ( DBUSER IN VARCHAR2, --用戶 pTBNAME IN VARCHAR2, --表名,多個表以','分隔 pISLIKE IN NUMBER:=0, --表名是精確匹配仍是進行模糊搜索,默認爲精確查找 pUPPERDATESTR IN VARCHAR2:='UPDATE_',--過程標識符,默認過程名稱爲標識符加上表名 pPRESTR IN VARCHAR2:='p', --存儲過程參數前置標識符,默認爲小寫字母'p' pSQLTEXT OUT CLOB --返回添加表記錄的存儲過程文本 ) AS pUSER VARCHAR2(200):=COALESCE(UPPER(DBUSER),USER); pPROCNAME VARCHAR2(50); pWHERE VARCHAR2(4000); BEGIN FOR X IN( SELECT DISTINCT TABLE_NAME, LISTAGG(' '||pPRESTR||COLUMN_NAME||' IN '||DATA_TYPE,','||CHR(10)) WITHIN GROUP(ORDER BY COLUMN_ID) OVER(PARTITION BY TABLE_NAME) AS PARALIST, LISTAGG(CASE ISPRIMARY WHEN 0 THEN COLUMN_NAME||'='||pPRESTR||COLUMN_NAME ELSE '' END,',') WITHIN GROUP(ORDER BY COLUMN_ID) OVER(PARTITION BY TABLE_NAME) AS SETLIST, LISTAGG(CASE ISPRIMARY WHEN 1 THEN COLUMN_NAME||'='||pPRESTR||COLUMN_NAME ELSE '' END,' AND ') WITHIN GROUP(ORDER BY COLUMN_ID) OVER(PARTITION BY TABLE_NAME) AS WHERELIST FROM ( SELECT A.TABLE_NAME,A.COLUMN_NAME,A.DATA_TYPE,A.COLUMN_ID, CASE WHEN B.COLUMN_NAME IS NULL THEN 0 ELSE 1 END ISPRIMARY FROM SYS.DBA_TAB_COLUMNS A LEFT JOIN ( SELECT TA.OWNER,TA.TABLE_NAME,TA.COLUMN_NAME FROM SYS.DBA_CONS_COLUMNS TA JOIN SYS.DBA_CONSTRAINTS TB ON (TA.OWNER=TB.OWNER AND TA.TABLE_NAME=TB.TABLE_NAME AND TA.CONSTRAINT_NAME=TB.CONSTRAINT_NAME) WHERE TB.CONSTRAINT_TYPE='P' ) B ON (A.OWNER=B.OWNER AND A.TABLE_NAME=B.TABLE_NAME AND A.COLUMN_NAME=B.COLUMN_NAME) WHERE A.OWNER=pUSER AND ( (pISLIKE=0 AND INSTR(','||pTBNAME||',',','||A.TABLE_NAME||',',1)>0) OR (pISLIKE=1 AND A.TABLE_NAME LIKE '%'||pTBNAME||'%') ) ) ) LOOP pPROCNAME:=SUBSTR(X.TABLE_NAME,0,25); SELECT DECODE(X.WHERELIST,NULL,' /*WHERE<搜索條件>*/',' WHERE '||X.WHERELIST) INTO pWHERE FROM DUAL; --若是沒有主鍵則去掉WHERE條件 pSQLTEXT:=pSQLTEXT|| 'CREATE OR REPLACE PROCEDURE '||pUPPERDATESTR||pPROCNAME||CHR(10)|| '--功能:修改'||X.TABLE_NAME||'表記錄'||CHR(10)|| '--參數:'||CHR(10)|| '--調用:'||CHR(10)|| '--日期:'||TO_CHAR(SYSDATE,'YYYY-MM-DD')||CHR(10)|| '('||CHR(10)|| X.PARALIST||CHR(10)|| ')'||CHR(10)|| 'AS'||CHR(10)|| 'BEGIN'||CHR(10)|| ' UPDATE '||X.TABLE_NAME||' SET '||X.SETLIST||CHR(10)|| pWHERE||X.WHERELIST||';'||CHR(10)|| ' COMMIT;'||CHR(10)|| ' EXCEPTION'||CHR(10)|| ' WHEN OTHERS THEN'||CHR(10)|| ' ROLLBACK;'||CHR(10)|| 'END '||pUPPERDATESTR||pPROCNAME||';'||CHR(10)|| '/'||CHR(10); END LOOP; END; PROCEDURE GET_DELETE_PROC --功能:獲取刪除表記錄的存儲過程文本(根據主鍵列刪除,注意標識符不能超過30個字符) --參數: --調用: /* DECLARE pSQLTEXT CLOB; BEGIN PKG_CREATE_PROC.GET_DELETE_PROC(DBUSER=>NULL,pTBNAME=>'A,B,C,CC',pSQLTEXT=>pSQLTEXT); DBMS_OUTPUT.PUT_LINE(pSQLTEXT); END; */ --日期:2013-02-10 ( DBUSER IN VARCHAR2, --用戶 pTBNAME IN VARCHAR2, --表名,多個表以','分隔 pISLIKE IN NUMBER:=0, --表名是精確匹配仍是進行模糊搜索,默認爲精確查找 pDELETESTR IN VARCHAR2:='DEL_', --過程標識符,默認過程名稱爲標識符加上表名 pPRESTR IN VARCHAR2:='p', --存儲過程參數前置標識符,默認爲小寫字母'p' pSQLTEXT OUT CLOB --返回添加表記錄的存儲過程文本 ) AS pUSER VARCHAR2(200):=COALESCE(UPPER(DBUSER),USER); pPROCNAME VARCHAR2(50); pWHERE VARCHAR2(4000); pPARA VARCHAR2(4000); BEGIN FOR X IN( SELECT DISTINCT TABLE_NAME, LISTAGG(CASE ISPRIMARY WHEN 1 THEN ' '||pPRESTR||COLUMN_NAME||' IN '||DATA_TYPE ELSE '' END,','||CHR(10)) WITHIN GROUP(ORDER BY COLUMN_ID) OVER(PARTITION BY TABLE_NAME) AS PARALIST, LISTAGG(CASE ISPRIMARY WHEN 1 THEN COLUMN_NAME||'='||pPRESTR||COLUMN_NAME ELSE '' END,' AND ') WITHIN GROUP(ORDER BY COLUMN_ID) OVER(PARTITION BY TABLE_NAME) AS WHERELIST FROM ( SELECT A.TABLE_NAME,A.COLUMN_NAME,A.DATA_TYPE,A.COLUMN_ID, CASE WHEN B.COLUMN_NAME IS NULL THEN 0 ELSE 1 END ISPRIMARY FROM SYS.DBA_TAB_COLUMNS A LEFT JOIN ( SELECT TA.OWNER,TA.TABLE_NAME,TA.COLUMN_NAME FROM SYS.DBA_CONS_COLUMNS TA JOIN SYS.DBA_CONSTRAINTS TB ON (TA.OWNER=TB.OWNER AND TA.TABLE_NAME=TB.TABLE_NAME AND TA.CONSTRAINT_NAME=TB.CONSTRAINT_NAME) WHERE TB.CONSTRAINT_TYPE='P' ) B ON (A.OWNER=B.OWNER AND A.TABLE_NAME=B.TABLE_NAME AND A.COLUMN_NAME=B.COLUMN_NAME) WHERE A.OWNER=pUSER AND ( (pISLIKE=0 AND INSTR(','||pTBNAME||',',','||A.TABLE_NAME||',',1)>0) OR (pISLIKE=1 AND A.TABLE_NAME LIKE '%'||pTBNAME||'%') ) ) ) LOOP pPROCNAME:=SUBSTR(X.TABLE_NAME,0,25); SELECT DECODE(X.WHERELIST,NULL,' /*WHERE<搜索條件>*/',' WHERE '||X.WHERELIST), DECODE(X.WHERELIST,NULL,'','('||CHR(10)||X.PARALIST||CHR(10)||')'||CHR(10)) INTO pWHERE,pPARA FROM DUAL; --若是沒有主鍵則去掉WHERE條件和輸入參數 pSQLTEXT:=pSQLTEXT|| 'CREATE OR REPLACE PROCEDURE '||pDELETESTR||pPROCNAME||CHR(10)|| '--功能:刪除'||X.TABLE_NAME||'表記錄'||CHR(10)|| '--參數:'||CHR(10)|| '--調用:'||CHR(10)|| '--日期:'||TO_CHAR(SYSDATE,'YYYY-MM-DD')||CHR(10)|| pPARA|| 'AS'||CHR(10)|| 'BEGIN'||CHR(10)|| ' DELETE FROM '||X.TABLE_NAME||pWHERE||';'||CHR(10)|| ' COMMIT;'||CHR(10)|| ' EXCEPTION'||CHR(10)|| ' WHEN OTHERS THEN'||CHR(10)|| ' ROLLBACK;'||CHR(10)|| 'END '||pDELETESTR||pPROCNAME||';'||CHR(10)|| '/'||CHR(10); END LOOP; END; PROCEDURE GET_DDL_PROC --功能:獲取用戶增長修改刪除標記裏的存儲過程文本(注意標識符不能超過30個字符) --參數: --調用: /* DECLARE pSQLTEXT CLOB; BEGIN PKG_CREATE_PROC.GET_DDL_PROC(DBUSER=>NULL,pTBNAME=>'A,B,C,CC',pSQLTEXT=>pSQLTEXT); DBMS_OUTPUT.PUT_LINE(pSQLTEXT); END; */ --日期:2013-02-10 ( DBUSER IN VARCHAR2, --用戶 pTBNAME IN VARCHAR2, --表名,多個表以','分隔 pISLIKE IN NUMBER:=0, --表名是精確匹配仍是進行模糊搜索,默認爲精確查找 pADDSTR IN VARCHAR2:='ADD_', --過程標識符,默認過程名稱爲標識符加上表名 pUPPERDATESTR IN VARCHAR2:='UPDATE_',--過程標識符,默認過程名稱爲標識符加上表名 pDELETESTR IN VARCHAR2:='DEL_', --過程標識符,默認過程名稱爲標識符加上表名 pPRESTR IN VARCHAR2:='p', --存儲過程參數前置標識符,默認爲小寫字母'p' pSQLTEXT OUT CLOB --返回添加表記錄的存儲過程文本 ) AS pADDTEXT CLOB; pUPDATETEXT CLOB; pDELETETEXT CLOB; BEGIN GET_ADD_PROC(DBUSER=>DBUSER,pTBNAME=>pTBNAME,pSQLTEXT=>pADDTEXT); --獲取添加表記錄的存儲過程 GET_UPDATE_PROC(DBUSER=>DBUSER,pTBNAME=>pTBNAME,pSQLTEXT=>pUPDATETEXT); --獲取修改表記錄的存儲過程 GET_DELETE_PROC(DBUSER=>DBUSER,pTBNAME=>pTBNAME,pSQLTEXT=>pDELETETEXT); --獲取刪除表記錄的存儲過程 pSQLTEXT:=pADDTEXT||CHR(10)||pUPDATETEXT||CHR(10)||pDELETETEXT; EXCEPTION WHEN OTHERS THEN SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'生成存儲過程出錯:'||SQLERRM) ; ROLLBACK; END; END; / CREATE OR REPLACE PACKAGE PKG_DYNAMIC_SQL AUTHID CURRENT_USER AS --功能:根據傳入的動態查詢SQL語句分析遊標的列數和列名,可用於列名和列數未知的動態遊標列索引取值 PROCEDURE GET_REFCURSOR_COLUMN ( pSQLSTR IN VARCHAR2 --動態查詢的SQL語句 ); --功能:根據傳入的動態遊標來分析該遊標的列數和列名,可用於列名和列數未知的動態遊標列索引取值 PROCEDURE GET_REFCURSOR_COLUMN ( pREFCURSOR IN OUT SYS_REFCURSOR --動態遊標 ); --功能:執行動態sql語句,執行錯誤則回滾並輸出錯誤行號和錯誤消息 PROCEDURE EXECUTE_SQL(pSQL IN CLOB); --功能:集合分頁查詢,返回總行數和分頁結果集 PROCEDURE GET_PAGE_ROWS( pSQL IN CLOB, --分頁查詢sql語句 pCOLLIST IN VARCHAR2, --返回的列 pPAGEINDEX IN INT, --查詢頁索引 pPAGESIZE IN INT, --查詢每頁行數 pTOTALROW OUT INT, --返回總行數 pPAGECURSOR OUT SYS_REFCURSOR --返回分頁數據集 ); --功能:集合分頁查詢,返回總行數和分頁結果集,其中分頁後返回的列與分頁前返回的不一樣 PROCEDURE GET_PAGE_ROWS( pSQL IN CLOB, --分頁查詢sql語句 pCOLLIST1 IN VARCHAR2, --分頁前返回的列 pCOLLIST2 IN VARCHAR2, --分頁後返回的列 pPAGEINDEX IN INT, --查詢頁索引 pPAGESIZE IN INT, --查詢每頁行數 pTOTALROW OUT INT, --返回總行數 pPAGECURSOR OUT SYS_REFCURSOR --返回分頁數據集 ); END; / CREATE OR REPLACE PACKAGE BODY PKG_DYNAMIC_SQL AS PROCEDURE GET_REFCURSOR_COLUMN --功能:根據傳入的動態查詢SQL語句分析遊標的列數和列名,可用於列名和列數未知的動態遊標列索引取值 --參數: --調用:EXEC PKG_DYNAMIC_SQL.GET_REFCURSOR_COLUMN('SELECT * FROM DEV_BASECLASSTAB'); --日期:2014-04-27 ( pSQLSTR IN VARCHAR2 --動態查詢的SQL語句 ) AS pREFCURSOR SYS_REFCURSOR; --動態遊標 pCURSORID INTEGER; --動態遊標ID pCOLUMNCOUNT INTEGER; --遊標的列數 pDESC_TAB DBMS_SQL.DESC_TAB; BEGIN OPEN pREFCURSOR FOR pSQLSTR; pCURSORID:=SYS.DBMS_SQL.TO_CURSOR_NUMBER(pREFCURSOR); SYS.DBMS_SQL.DESCRIBE_COLUMNS(pCURSORID,pCOLUMNCOUNT,pDESC_TAB); FOR I IN 1..pCOLUMNCOUNT LOOP DBMS_OUTPUT.PUT_LINE(pDESC_TAB(I).COL_NAME); END LOOP; SYS.DBMS_SQL.CLOSE_CURSOR(pCURSORID); END; PROCEDURE GET_REFCURSOR_COLUMN --功能:根據傳入的動態遊標來分析該遊標的列數和列名,可用於列名和列數未知的動態遊標列索引取值 --參數: --調用: /* DECLARE pREFCURSOR SYS_REFCURSOR; BEGIN OPEN pREFCURSOR FOR SELECT * FROM DEV_BASECLASSTAB; PKG_DYNAMIC_SQL.GET_REFCURSOR_COLUMN(pREFCURSOR); END; */ --日期:2014-04-27 ( pREFCURSOR IN OUT SYS_REFCURSOR --動態遊標 ) AS pCURSORID INTEGER; --動態遊標ID pCOLUMNCOUNT INTEGER; --遊標的列數 pDESC_TAB DBMS_SQL.DESC_TAB; BEGIN pCURSORID:=SYS.DBMS_SQL.TO_CURSOR_NUMBER(pREFCURSOR); SYS.DBMS_SQL.DESCRIBE_COLUMNS(pCURSORID,pCOLUMNCOUNT,pDESC_TAB); FOR I IN 1..pCOLUMNCOUNT LOOP DBMS_OUTPUT.PUT_LINE(pDESC_TAB(I).COL_NAME); END LOOP; SYS.DBMS_SQL.CLOSE_CURSOR(pCURSORID); END; PROCEDURE EXECUTE_SQL --功能:執行動態sql語句,執行錯誤則回滾並輸出錯誤行號和錯誤消息 --參數:pSQL-查詢sql語句 --調用:EXECUTE PKG_DYNAMIC_SQL.EXECUTE_SQL('CREATE TABLE X'); --日期:2013-03-01 ( pSQL IN CLOB ) AS BEGIN EXECUTE IMMEDIATE pSQL; COMMIT; EXCEPTION WHEN OTHERS THEN SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'執行動態SQL語句出錯:' ||SQLERRM); RAISE; END; PROCEDURE EXECUTE_PLSQL --功能:執行動態pl/sql語句,執行錯誤則回滾並輸出錯誤行號和錯誤消息 --參數:pSQL-查詢sql語句 --調用:EXECUTE PKG_DYNAMIC_SQL.EXECUTE_SQL('INSERT INTO TB VALUES (q'{11}')'); --日期:2013-03-01 ( pSQL IN CLOB ) AS BEGIN --將SQL語句封裝到BEGIN-END匿名塊中,保證不管傳什麼樣的字符串都會被做爲一個有效的PL/SQL塊執行 EXECUTE IMMEDIATE 'BEGIN '||CHR(10)||RTRIM(pSQL,';')||'; '||CHR(10)||'END;'; --注意語句結束必須帶';'結束符,不然報錯 COMMIT; EXCEPTION WHEN OTHERS THEN SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'執行動態PL/SQL語句塊出錯:' ||SQLERRM); ROLLBACK; END; PROCEDURE GET_PAGE_ROWS --功能:集合分頁查詢,返回總行數和分頁結果集 --參數:見下方說明 --調用: /* DECLARE pTOTALROW INT;pPAGECURSOR SYS_REFCURSOR; BEGIN PKG_DYNAMIC_SQL.GET_PAGE_ROWS('SELECT * FROM USER_OBJECTS','OBJECT_NAME,OBJECT_TYPE',1,100,pTOTALROW,pPAGECURSOR); END; */ --日期:2013-02-17 ( pSQL IN CLOB, --分頁查詢sql語句 pCOLLIST IN VARCHAR2, --返回的列 pPAGEINDEX IN INT, --查詢頁索引 pPAGESIZE IN INT, --查詢每頁行數 pTOTALROW OUT INT, --返回總行數 pPAGECURSOR OUT SYS_REFCURSOR --返回分頁數據集 ) AS pNEWPAGEINDEX INT:=pPAGEINDEX; pNEWPAGESIZE INT:=pPAGESIZE; pSTART PLS_INTEGER; pEND PLS_INTEGER; SQLTEXT CLOB; BEGIN IF pPAGEINDEX<1 THEN --頁索引小於1時默認爲選擇第一頁 pNEWPAGEINDEX:=1; END IF; IF pPAGESIZE<1 THEN --頁行數小於1時默認已選擇1行 pNEWPAGESIZE:=1; END IF; pSTART:=(pNEWPAGEINDEX-1)*pNEWPAGESIZE; pEND:=pNEWPAGEINDEX*pNEWPAGESIZE; EXECUTE IMMEDIATE 'SELECT COUNT(1) FROM ('||pSQL||')' INTO pTOTALROW; SQLTEXT:='SELECT '||pCOLLIST||' FROM(SELECT '||pCOLLIST||',ROWNUM FROM('||pSQL||') TA)TB WHERE "ROWNUM">'||pSTART||' AND "ROWNUM"<='||pEND; SYS.DBMS_OUTPUT.PUT_LINE('/*SQL語句:*/'||SQLTEXT); OPEN pPAGECURSOR FOR SQLTEXT; EXCEPTION WHEN OTHERS THEN SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'執行SQL語句出錯:' ||SQLERRM||CHR(10)||'/*SQL語句:*/'||SQLTEXT); NULL; END; PROCEDURE GET_PAGE_ROWS --功能:集合分頁查詢,返回總行數和分頁結果集,其中分頁後返回的列與分頁前返回的不一樣 --參數:見下方說明 --調用: /* DECLARE pTOTALROW INT;pPAGECURSOR SYS_REFCURSOR; BEGIN PKG_DYNAMIC_SQL.GET_PAGE_ROWS('SELECT * FROM USER_OBJECTS','OBJECT_NAME,OBJECT_TYPE',1,100,pTOTALROW,pPAGECURSOR); END; */ --日期:2013-02-17 ( pSQL IN CLOB, --分頁查詢sql語句 pCOLLIST1 IN VARCHAR2, --分頁前返回的列 pCOLLIST2 IN VARCHAR2, --分頁後返回的列 pPAGEINDEX IN INT, --查詢頁索引 pPAGESIZE IN INT, --查詢每頁行數 pTOTALROW OUT INT, --返回總行數 pPAGECURSOR OUT SYS_REFCURSOR --返回分頁數據集 ) AS pNEWPAGEINDEX INT:=pPAGEINDEX; pNEWPAGESIZE INT:=pPAGESIZE; pSTART PLS_INTEGER; pEND PLS_INTEGER; SQLTEXT CLOB; BEGIN IF pPAGEINDEX<1 THEN --頁索引小於1時默認爲選擇第一頁 pNEWPAGEINDEX:=1; END IF; IF pPAGESIZE<1 THEN --頁行數小於1時默認已選擇1行 pNEWPAGESIZE:=1; END IF; pSTART:=(pNEWPAGEINDEX-1)*pNEWPAGESIZE; pEND:=pNEWPAGEINDEX*pNEWPAGESIZE; EXECUTE IMMEDIATE 'SELECT COUNT(1) FROM ('||pSQL||')' INTO pTOTALROW; SQLTEXT:='SELECT '||pCOLLIST2||' FROM(SELECT '||pCOLLIST1||',ROWNUM FROM('||pSQL||') TA)TB WHERE "ROWNUM">'||pSTART||' AND "ROWNUM"<='||pEND; SYS.DBMS_OUTPUT.PUT_LINE('/*SQL語句:*/'||SQLTEXT); OPEN pPAGECURSOR FOR SQLTEXT; EXCEPTION WHEN OTHERS THEN SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'執行SQL語句出錯:' ||SQLERRM||CHR(10)||'/*SQL語句:*/'||SQLTEXT); END; END; / CREATE OR REPLACE PACKAGE PKG_TEST AS --功能:開始計時,保存CPU時間到開始時間字段中 PROCEDURE START_TIMER; --功能:計算消耗的時間(單位:毫秒) FUNCTION ELAPSED_TIME RETURN NUMBER; --功能:輸出執行動態SQL語句所消耗的時間(單位:毫秒) PROCEDURE SHOW_ELAPSED_TIME( pSQLTEXT IN VARCHAR2:=NULL, --SQL語句塊 pSQLTYPE IN NUMBER:=1, --SQL語句類型,默認爲1-動態SQL語句,2-動態PL/SQL語句,其餘-查詢語句 pRESET_IN IN BOOLEAN:=TRUE --是否從新計時,默認每次執行SQL語句均從新計時 ); END; / CREATE OR REPLACE PACKAGE BODY PKG_TEST AS LAST_TIMING NUMBER:=NULL; PROCEDURE START_TIMER --功能:開始計時,保存CPU時間到開始時間字段中 --參數: --調用: --日期:2014-05-22 AS BEGIN LAST_TIMING:=SYS.DBMS_UTILITY.GET_CPU_TIME; END; FUNCTION ELAPSED_TIME --功能:計算消耗的時間(單位:毫秒) --參數: --調用: --日期:2014-05-22 RETURN NUMBER IS END_TIME PLS_INTEGER:=SYS.DBMS_UTILITY.GET_CPU_TIME; BEGIN --因爲函數DBMS_UTILITY.GET_CPU_TIME所返回的數字表明的是從某一個時間點以來所通過的總的秒數,而這個數字會至關大(受限於咱們的操做系統),達到必定程度就會滾動到0後從新開始計數, --所以,若是對於GET_TIME的調用恰巧發生在滾動以前,結束時間-開始時間就會是負值.下面的寫法可有效避免出現負值的狀況. RETURN MOD(END_TIME - LAST_TIMING + POWER (2, 32), POWER (2, 32))*10; END; PROCEDURE SHOW_ELAPSED_TIME --功能:輸出執行動態SQL語句所消耗的時間(單位:毫秒) --參數: --調用: --日期:2014-05-22 ( pSQLTEXT IN VARCHAR2:=NULL, --SQL語句塊 pSQLTYPE IN NUMBER:=1, --SQL語句類型,默認爲1-動態SQL語句,2-動態PL/SQL語句,其餘-查詢語句 pRESET_IN IN BOOLEAN:=TRUE --是否從新計時,默認每次執行SQL語句均從新計時 ) AS pTBNAME VARCHAR2(30); BEGIN IF pRESET_IN THEN START_TIMER; --從新開始計時 END IF; IF pSQLTEXT IS NOT NULL THEN IF pSQLTYPE=1 THEN --執行動態sql語句 EXECUTE IMMEDIATE pSQLTEXT; ELSIF pSQLTYPE=2 THEN --將SQL語句封裝到BEGIN-END匿名塊中,保證不管傳什麼樣的字符串都會被做爲一個有效的PL/SQL塊執行 EXECUTE IMMEDIATE 'BEGIN '||CHR(10)||RTRIM(pSQLTEXT,';')||'; '||CHR(10)||'END;'; --注意語句結束必須帶';'結束符,不然報錯 ELSE --經過建立臨時表的模式進行間接計算查詢SQL語句消耗時間,此方式測算查詢語句時間不許確,最好仍是經過查看執行計劃來分析 pTBNAME:='TMP_'||LPAD(SYS_GUID(),25); EXECUTE IMMEDIATE 'CREATE GLOBAL TEMPORARY TABLE '||pTBNAME||' AS SELECT * FROM('||pSQLTEXT||') TB'; END IF; END IF; SYS.DBMS_OUTPUT.PUT_LINE('執行耗時:'||ELAPSED_TIME||'毫秒!'); IF pTBNAME IS NOT NULL THEN --用完直接刪除臨時表 EXECUTE IMMEDIATE 'DROP TABLE '||pTBNAME; END IF; COMMIT; EXCEPTION WHEN OTHERS THEN SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'執行動態SQL語句出錯:' ||SQLERRM); RAISE; END; END; / create or replace PACKAGE PKG_GET_DDL AS --功能:獲取用戶下對象的源碼,主要利用到dbms_metadata.get_ddl包,也能夠查詢dba_source視圖來進行相關操做 PROCEDURE GET_DDL( pUSER IN VARCHAR2:=USER, --用戶 pREUSER IN VARCHAR2, --轉換爲新的用戶 pMODE IN NUMBER:=0, --是否模糊匹配,0-模糊匹配,1-精確匹配 LIKENAME IN VARCHAR2:=NULL, --模糊搜索條件,返回全部匹配對象的源碼 TAG IN NUMBER:=0, --對象類型 pSQLTEXT OUT CLOB --源碼文本 ); --功能:獲取用戶下具備依賴關係的對象(如函數、過程、視圖、包)的源碼,主要利用到dbms_metadata.get_ddl包,也能夠查詢dba_source視圖來進行相關操做 PROCEDURE GET_DEPEND_DDL( pUSER IN VARCHAR2:=USER, --用戶 pREUSER IN VARCHAR2, --轉換爲新的用戶,默認不轉換 pSQLTEXT OUT CLOB --源碼文本 ); --功能:保存用戶下對象的源碼到單個文件或多個文件中 PROCEDURE SAVE_DDL( pUSER IN VARCHAR2:=USER, --用戶 pREUSER IN VARCHAR2:=NULL, --轉換爲新的用戶,默認不轉換 pMODE IN NUMBER:=0, --是否模糊匹配,0-模糊匹配,1-精確匹配 LIKENAME IN VARCHAR2:=NULL, --模糊搜索條件,返回全部匹配對象的源碼 TAG IN NUMBER:=0, --對象類型 pISMERGE IN NUMBER:=0, --保存到單個文件仍是多個文件,默認爲0-單個文件,其餘-多個文件 DIR IN VARCHAR2:='DATA_PUMP_DIR',--目錄名稱(若是不填,則使用當前數據庫目錄) FILENAME IN VARCHAR:=NULL --單個文件的文件名稱 ); END; / create or replace PACKAGE BODY PKG_GET_DDL AS PROCEDURE GET_DDL --功能:獲取用戶下對象的源碼,主要利用到dbms_metadata.get_ddl包,也能夠查詢dba_source視圖來進行相關操做 --參數: --調用: /* DECLARE pSQLTEXT CLOB; BEGIN PKG_GET_DDL.GET_DDL('DKGLL','',0,'USR_INFOTAB',12,pSQLTEXT); DBMS_OUTPUT.PUT_LINE(pSQLTEXT); PKG_DBMANAGE.CLOB_TO_FILE('BACKDIR','('||TO_CHAR(CURRENT_DATE,'YYYYMMDDHH24')||').sql',1,pSQLTEXT); --保存到文件 END; */ --日期:2013-03-01 ( pUSER IN VARCHAR2:=USER, --用戶 pREUSER IN VARCHAR2, --源對象轉換爲新的用戶 pMODE IN NUMBER:=0, --是否模糊匹配,0-模糊匹配,1-精確匹配 LIKENAME IN VARCHAR2:=NULL, --模糊搜索條件,返回全部匹配對象的源碼 TAG IN NUMBER:=0, --對象類型 pSQLTEXT OUT CLOB --源碼文本 ) --操做均基於指定用戶下進行,其餘用戶不作處理 --0.所有 --1.序列 --2.表(未解決鍵/索引對應關係以及建立前後順序問題,需注意) --3.索引 --4.觸發器 --5.視圖 --6.類型 --7.函數 --8.過程 --9.包 --10.同義詞 --11.JAVA SOURCE --12:實體化視圖 AS pCURROBJTYPE VARCHAR2(200):=' '; pCOUNT INT; DDL_TEXT CLOB; pREPLACEUSER VARCHAR2(200); BEGIN -- --該版本能夠修改對象的擁有者爲新的用戶,但需解決ORA-04030嘗試分配字節時進程內存不足的問題 -- FOR X IN( -- SELECT OBJECT_TYPE,OBJECT_NAME FROM SYS.DBA_OBJECTS -- WHERE OWNER=pUSER -- AND ((pMODE=0 AND OBJECT_NAME LIKE '%'||LIKENAME||'%' OR INSTR(','||LIKENAME||',',','||OBJECT_NAME||',',1)>0) -- OR (pMODE=1 AND OBJECT_NAME=LIKENAME) -- ) AND OBJECT_TYPE IN('SEQUENCE','TABLE','INDEX','TRIGGER','VIEW','TYPE','FUNCTION','PROCEDURE','PACKAGE') -- AND OBJECT_TYPE=DECODE(TAG,0,OBJECT_TYPE,1,'SEQUENCE',2,'TABLE',3,'INDEX',4,'TRIGGER',5,'VIEW',6,'TYPE',7,'FUNCTION',8,'PROCEDURE',9,'PACKAGE') -- AND ((OBJECT_TYPE='TYPE' AND OBJECT_NAME NOT LIKE 'SYS_PLSQL_%') OR (OBJECT_TYPE<>'TYPE')) -- ORDER BY DECODE(OBJECT_TYPE,'SEQUENCE',1,'TABLE',2,'INDEX',3,'TRIGGER',4,'VIEW',5,'TYPE',6,'FUNCTION',7,'PROCEDURE',8,'PACKAGE',9) -- ) -- LOOP -- V_HANDLE:=SYS.DBMS_METADATA.OPEN(X.OBJECT_TYPE); -- SYS.DBMS_METADATA.SET_FILTER(v_HANDLE,'NAME',X.OBJECT_NAME,X.OBJECT_TYPE); -- -- v_TRANS_HANDLE:=SYS.DBMS_METADATA.ADD_TRANSFORM(v_HANDLE,'MODIFY'); -- IF pREUSER IS NOT NULL THEN -- SYS.DBMS_METADATA.SET_REMAP_PARAM(v_TRANS_HANDLE,'REMAP_SCHEMA',pUSER,pREUSER); -- END IF; -- v_TRANS_HANDLE:=SYS.DBMS_METADATA.ADD_TRANSFORM(v_HANDLE,'DDL'); -- -- --確保每一個語句都帶分號 -- SYS.DBMS_METADATA.SET_TRANSFORM_PARAM(v_TRANS_HANDLE,'SQLTERMINATOR',TRUE); -- --若是是獲取表對象的DDL語句,則去除STORAGE、PCTFREE等多餘參數 -- IF X.OBJECT_TYPE='TABLE' THEN -- SYS.DBMS_METADATA.SET_TRANSFORM_PARAM(v_TRANS_HANDLE,'STORAGE',FALSE); -- SYS.DBMS_METADATA.SET_TRANSFORM_PARAM(v_TRANS_HANDLE,'SEGMENT_ATTRIBUTES',FALSE); -- END IF; -- -- DDL_TEXT:=SYS.DBMS_METADATA.FETCH_CLOB(V_HANDLE); -- -- IF X.OBJECT_TYPE<>'TABLE' THEN -- SELECT COUNT(1) INTO pCOUNT FROM DUAL WHERE REGEXP_LIKE(RTRIM(DDL_TEXT),'/$'); -- IF pCOUNT=0 THEN --若是不存在換行結束符則需加上'/' -- DDL_TEXT:=TRIM(DDL_TEXT)||CHR(10)||'/'; -- END IF; -- IF X.OBJECT_TYPE='PACKAGE' THEN --修正包體與包聲明之間沒有換行結束符報錯的BUG -- DDL_TEXT:=REPLACE(DDL_TEXT,'CREATE OR REPLACE PACKAGE BODY','/'||CHR(10)||'CREATE OR REPLACE PACKAGE BODY'); -- END IF; -- ELSIF INSTR(DDL_TEXT,';')=0 THEN -- DDL_TEXT:=TRIM(DDL_TEXT)||';'; -- END IF; -- pSQLTEXT:=pSQLTEXT||DDL_TEXT; -- END LOOP; SELECT DECODE(pREUSER,pUSER,pREUSER,DECODE(pREUSER,NULL,'','"'||pREUSER||'".')) INTO pREPLACEUSER FROM DUAL; FOR X IN ( SELECT DECODE(OBJECT_TYPE,'JAVA SOURCE','JAVA_SOURCE','MATERIALIZED VIEW','MATERIALIZED_VIEW',OBJECT_TYPE) AS OBJECT_TYPE,OBJECT_NAME FROM SYS.DBA_OBJECTS WHERE OWNER=pUSER AND ((pMODE=0 AND OBJECT_NAME LIKE '%'||LIKENAME||'%' OR INSTR(','||LIKENAME||',',','||OBJECT_NAME||',',1)>0) OR (pMODE=1 AND OBJECT_NAME=LIKENAME) ) AND OBJECT_TYPE IN('SEQUENCE','TABLE','INDEX','TRIGGER','VIEW','TYPE','FUNCTION','PROCEDURE','PACKAGE','SYNONYM','JAVA SOURCE','MATERIALIZED VIEW') AND OBJECT_TYPE=DECODE(TAG,0,OBJECT_TYPE,1,'SEQUENCE',2,'TABLE',3,'INDEX',4,'TRIGGER',5,'VIEW',6,'TYPE',7,'FUNCTION',8,'PROCEDURE',9,'PACKAGE',10,'SYNONYM',11,'JAVA SOURCE',12,'MATERIALIZED VIEW') AND ((OBJECT_TYPE='TYPE' AND OBJECT_NAME NOT LIKE 'SYS_PLSQL_%') OR (OBJECT_TYPE<>'TYPE')) ORDER BY DECODE(OBJECT_TYPE,'SEQUENCE',1,'TABLE',2,'INDEX',3,'TRIGGER',4,'VIEW',5,'TYPE',6,'FUNCTION',7,'PROCEDURE',8,'PACKAGE',9,'SYNONYM',10,'JAVA_SOURCE',11,'MATERIALIZED_VIEW',12) ) LOOP --確保每一個語句都帶分號 SYS.DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'SQLTERMINATOR',TRUE); --去除STORAGE、PCTFREE等多餘參數 SYS.DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'STORAGE',FALSE); SYS.DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'SEGMENT_ATTRIBUTES',FALSE); SELECT SYS.dbms_metadata.get_ddl(X.OBJECT_TYPE,X.OBJECT_NAME,pUSER) INTO DDL_TEXT FROM DUAL; IF X.OBJECT_TYPE<>'TABLE' AND X.OBJECT_TYPE<>'INDEX' THEN SELECT COUNT(1) INTO pCOUNT FROM DUAL WHERE REGEXP_LIKE(RTRIM(DDL_TEXT),'/$'); IF pCOUNT=0 THEN --若是不存在換行結束符則需加上'/' DDL_TEXT:=TRIM(DDL_TEXT)||CHR(10)||'/'; END IF; IF X.OBJECT_TYPE='PACKAGE' THEN --修正包體與包聲明之間沒有換行結束符報錯的BUG DDL_TEXT:=REGEXP_REPLACE(DDL_TEXT,'CREATE OR REPLACE PACKAGE BODY "'||pUSER||'".','/'||CHR(10)||'CREATE OR REPLACE PACKAGE BODY '||pREPLACEUSER,1,1); END IF; ELSIF INSTR(DDL_TEXT,';')=0 THEN DDL_TEXT:=TRIM(DDL_TEXT)||';'; END IF; --替換對象的擁有者爲新的用戶,注意:若是爲包、觸發器,則包體、觸發器的修改也須要進行二次替換 IF pREUSER<>pUSER OR pREUSER IS NULL THEN IF (X.OBJECT_TYPE='TABLE' OR X.OBJECT_TYPE='INDEX') THEN --若是是TABLE或INDEX,則須要所有替換對象擁有者以及對象依賴得表的擁有者爲新的用戶 pSQLTEXT:=pSQLTEXT||REPLACE(DDL_TEXT,'"'||pUSER||'".',pREPLACEUSER); ELSE pSQLTEXT:=pSQLTEXT||REGEXP_REPLACE(DDL_TEXT,'"'||pUSER||'".',pREPLACEUSER,1,1); END IF; IF X.OBJECT_TYPE='TRIGGER' THEN pSQLTEXT:=REPLACE(pSQLTEXT,'ALTER TRIGGER "'||pUSER||'".','ALTER TRIGGER '||pREPLACEUSER); END IF; ELSE pSQLTEXT:=pSQLTEXT||DDL_TEXT; END IF; END LOOP; END; PROCEDURE GET_DEPEND_DDL --功能:獲取用戶下具備依賴關係的對象(如函數、視圖、過程、包)的源碼,主要利用到dbms_metadata.get_ddl包,也能夠查詢dba_source視圖來進行相關操做 --參數: --調用: /* DECLARE pSQLTEXT CLOB; BEGIN PKG_GET_DDL.GET_DEPEND_DDL('TEST','',pSQLTEXT); --pREUSER爲空表示導出該源用戶下的全部依賴關係的對象 --DBMS_OUTPUT.PUT_LINE(pSQLTEXT); PKG_DBMANAGE.CLOB_TO_FILE('BACKDIR','('||TO_CHAR(CURRENT_DATE,'YYYYMMDDHH24')||').sql',1,pSQLTEXT); --保存到文件 END; */ --日期:2016-02-16 ( pUSER IN VARCHAR2:=USER, --用戶 pREUSER IN VARCHAR2, --源對象轉換爲新的用戶 pSQLTEXT OUT CLOB --源碼文本 ) AS pCURROBJTYPE VARCHAR2(200):=' '; pCOUNT INT; DDL_TEXT CLOB; pREPLACEUSER VARCHAR2(200); BEGIN --若是替換的用戶名稱爲空,則表示不須要該用戶前綴 SELECT DECODE(pREUSER,pUSER,pREUSER,DECODE(pREUSER,NULL,'','"'||pREUSER||'".')) INTO pREPLACEUSER FROM DUAL; FOR X IN ( WITH TB AS ( SELECT * FROM SYS.DBA_DEPENDENCIES WHERE OWNER=pUSER AND REFERENCED_OWNER=pUSER AND TYPE IN ('FUNCTION','PROCEDURE','VIEW') UNION ALL SELECT * FROM SYS.DBA_DEPENDENCIES WHERE OWNER=pUSER AND REFERENCED_OWNER=pUSER AND REFERENCED_TYPE='PACKAGE' AND TYPE IN ('PACKAGE BODY') AND NAME<>REFERENCED_NAME ) SELECT T1.OWNER,T1.OBJECT_NAME,T1.OBJECT_TYPE,T2.ML,TOP_NAME FROM ( SELECT * FROM SYS.DBA_OBJECTS WHERE OWNER=pUSER AND OBJECT_TYPE IN ('FUNCTION','PROCEDURE','VIEW','PACKAGE') ) T1 LEFT JOIN ( SELECT DISTINCT TOP_NAME,ML FROM ( SELECT REFERENCED_NAME,TOP_NAME,LN,MAX(LN) OVER(PARTITION BY TOP_NAME) AS ML FROM ( SELECT "REFERENCED_NAME",CONNECT_BY_ROOT "REFERENCED_NAME" AS TOP_NAME,LEVEL AS LN FROM TB CONNECT BY PRIOR "REFERENCED_NAME"="NAME" ORDER BY "REFERENCED_NAME",LN ) ) WHERE LN=ML ) T2 ON T1.OBJECT_NAME=T2.TOP_NAME ORDER BY ML,TOP_NAME ) LOOP --確保每一個語句都帶分號 SYS.DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'SQLTERMINATOR',TRUE); --去除STORAGE、PCTFREE等多餘參數 SYS.DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'STORAGE',FALSE); SYS.DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'SEGMENT_ATTRIBUTES',false); SELECT SYS.dbms_metadata.get_ddl(X.OBJECT_TYPE,X.OBJECT_NAME,pUSER) INTO DDL_TEXT FROM DUAL; IF X.OBJECT_TYPE<>'TABLE' AND X.OBJECT_TYPE<>'INDEX' THEN SELECT COUNT(1) INTO pCOUNT FROM DUAL WHERE REGEXP_LIKE(RTRIM(DDL_TEXT),'/$'); IF pCOUNT=0 THEN --若是不存在換行結束符則需加上'/' DDL_TEXT:=TRIM(DDL_TEXT)||CHR(10)||'/'; END IF; IF X.OBJECT_TYPE='PACKAGE' THEN --修正包體與包聲明之間沒有換行結束符報錯的BUG DDL_TEXT:=REGEXP_REPLACE(DDL_TEXT,'CREATE OR REPLACE PACKAGE BODY "'||pUSER||'".','/'||CHR(10)||'CREATE OR REPLACE PACKAGE BODY '||pREPLACEUSER,1,1); END IF; ELSIF INSTR(DDL_TEXT,';')=0 THEN DDL_TEXT:=TRIM(DDL_TEXT)||';'; END IF; --替換對象的擁有者爲新的用戶,注意:若是爲包、觸發器,則包體、觸發器的修改也須要進行二次替換 IF pREUSER<>pUSER OR pREUSER IS NULL THEN pSQLTEXT:=pSQLTEXT||REGEXP_REPLACE(DDL_TEXT,'"'||pUSER||'".',pREPLACEUSER,1,1); IF X.OBJECT_TYPE='TRIGGER' THEN pSQLTEXT:=REPLACE(pSQLTEXT,'ALTER TRIGGER "'||pUSER||'".','ALTER TRIGGER '||pREPLACEUSER); END IF; ELSE pSQLTEXT:=pSQLTEXT||DDL_TEXT; END IF; END LOOP; END; PROCEDURE SAVE_DDL --功能:保存用戶下對象的源碼到單個文件或多個文件中 --參數: --調用: /* BEGIN PKG_GET_DDL.SAVE_DDL ( DBUSER=>NULL, LIKENAME=>'PKG', TAG=>9, pISMERGE=>0, DIR=>'BACKDIR', FILENAME=>'管理包0429.sql' ); END; */ --日期:2014-04-28 ( pUSER IN VARCHAR2:=USER, --用戶 pREUSER IN VARCHAR2:=NULL, --源對象轉換爲新的用戶,默認不轉換 pMODE IN NUMBER:=0, --是否模糊匹配,0-模糊匹配,1-精確匹配 LIKENAME IN VARCHAR2:=NULL, --模糊搜索條件,返回全部匹配對象的源碼 TAG IN NUMBER:=0, --對象類型 pISMERGE IN NUMBER:=0, --保存到單個文件仍是多個文件,默認爲0-單個文件,其餘-多個文件 DIR IN VARCHAR2:='DATA_PUMP_DIR',--目錄名稱(若是不填,則使用當前數據庫目錄) FILENAME IN VARCHAR:=NULL --單個文件的文件名稱 ) AS pCOUNT INT; pSQLTEXT CLOB; BEGIN IF pISMERGE=0 THEN --保存全部對象源碼到單個文件 GET_DDL(pUSER,pREUSER,pMODE,LIKENAME,TAG,pSQLTEXT); --獲取用戶下對象的源碼 PKG_DBMANAGE.CLOB_TO_FILE(DIR,NVL(FILENAME,'源碼('||TO_CHAR(CURRENT_DATE,'YYYYMMDDHH24')||').sql'),1,pSQLTEXT); --保存源碼到文件 ELSE --分別保存對象源碼到單獨的文件中去,單獨文件的名稱取對象名稱 FOR X IN ( SELECT OBJECT_TYPE,OBJECT_NAME FROM SYS.DBA_OBJECTS WHERE OWNER=pUSER AND ((pMODE=0 AND OBJECT_NAME LIKE '%'||LIKENAME||'%' OR INSTR(','||LIKENAME||',',','||OBJECT_NAME||',',1)>0) OR (pMODE=1 AND OBJECT_NAME=LIKENAME) ) AND OBJECT_TYPE IN('SEQUENCE','TABLE','INDEX','TRIGGER','VIEW','TYPE','FUNCTION','PROCEDURE','PACKAGE') AND OBJECT_TYPE=DECODE(TAG,0,OBJECT_TYPE,1,'SEQUENCE',2,'TABLE',3,'INDEX',4,'TRIGGER',5,'VIEW',6,'TYPE',7,'FUNCTION',8,'PROCEDURE',9,'PACKAGE') AND ((OBJECT_TYPE='TYPE' AND OBJECT_NAME NOT LIKE 'SYS_PLSQL_%') OR (OBJECT_TYPE<>'TYPE')) ORDER BY DECODE(OBJECT_TYPE,'SEQUENCE',1,'TABLE',2,'INDEX',3,'TRIGGER',4,'VIEW',5,'TYPE',6,'FUNCTION',7,'PROCEDURE',8,'PACKAGE',9) ) LOOP PKG_GET_DDL.GET_DDL(pUSER,pREUSER,1,X.OBJECT_NAME,TAG,pSQLTEXT); PKG_DBMANAGE.CLOB_TO_FILE(DIR,X.OBJECT_NAME||'('||TO_CHAR(CURRENT_DATE,'YYYYMMDDHH24')||').sql',1,pSQLTEXT); END LOOP; END IF; END; END; / create or replace PACKAGE PKG_COMPAREDB AS --功能:基於指定用戶下修改列類型,暫時只處理CLOB類型、NVARCHR到其餘類型的轉換等 PROCEDURE UPDATE_COL_TYPE( pUSER IN VARCHAR2, pTABLENAME IN VARCHAR2, pCOLNAME IN VARCHAR2, pNEWCOLTYPE IN VARCHAR2, pOLDCOLTYPE IN VARCHAR2:=NULL, pATTR IN VARCHAR2, pNULLTEXT IN VARCHAR2, pSQLTEXT OUT CLOB ); --功能:獲取對比修改序列的語句 PROCEDURE COMPARE_SEQUENCE( pSOURCEUSER IN VARCHAR2, --源用戶名 pTARGETUSER IN VARCHAR2, --目標用戶名 pSEQUENCENAME IN VARCHAR2:=NULL, --源序列名,能夠爲一個或多個序列,多個序列以','分隔,爲空則選擇全部序列 pSQLTEXT OUT CLOB ); --功能:獲取對比修改表的SQL語句,注意:此處pSOURCEUSER,pTARGETUSER,pTABLENAME默認所有爲大寫.因爲獲取源碼權限問題,該過程只能在源用戶庫上執行 PROCEDURE COMPARE_TABLE( pSOURCEUSER IN VARCHAR2, --源用戶名 pTARGETUSER IN VARCHAR2, --目標用戶名 pTABLENAME IN VARCHAR2:=NULL, --源表,能夠爲一張或多張表,多個表以','分隔,爲空則選擇結構類型一致的全部表 pDROPTABLE IN NUMBER:=1, --是否刪除表:0-不刪除,其餘-刪除,默認-刪除 pSQLTEXT OUT CLOB ); --功能:因爲觸發器錯誤可能致使系統異常,須要對觸發器進行比對處理 PROCEDURE COMPARE_TRIGGER( pSOURCEUSER IN VARCHAR2, --源用戶名 pTARGETUSER IN VARCHAR2, --目標用戶名 pSQLTEXT OUT CLOB ); --功能:獲取對比修改JOB的SQL語句 PROCEDURE COMPARE_JOB( pSOURCEUSER IN VARCHAR2, --源用戶名 pTARGETUSER IN VARCHAR2, --目標用戶名 pTAG IN PLS_INTEGER, --0-比較,1:不比較,直接獲取全部源碼 pSQLTEXT OUT CLOB ); --功能:獲取對比修改SCHEDULER JOB的SQL語句 PROCEDURE COMPARE_SCHEDULER( pSOURCEUSER IN VARCHAR2, --源用戶名 pTARGETUSER IN VARCHAR2, --目標用戶名 pTAG IN PLS_INTEGER, --0-比較,1:不比較,直接獲取全部源碼 pSQLTEXT OUT CLOB ); --功能:獲取對比修改數據庫對象的SQL語句.注意因爲獲取源碼權限問題,該過程只能在源用戶庫上執行 PROCEDURE COMPARE_DB( pSOURCEUSER IN VARCHAR2, --源用戶名 pTARGETUSER IN VARCHAR2, --目標用戶名 pOBJTYPE IN NUMBER, --對象類型,0-對比表、序列、類型,1-導出全部具備依賴關係的對象(視圖、函數、過程、包),2-在1的基礎上導出全部觸發器 pDROPTABLE IN NUMBER:=1, --是否刪除表:0-不刪除,其餘-刪除,默認-刪除 pSQLTEXT OUT CLOB ); END; / create or replace PACKAGE BODY "PKG_COMPAREDB" AS PROCEDURE UPDATE_COL_TYPE --功能:基於指定用戶下修改列類型,暫時只處理CLOB類型、NVARCHR到其餘類型以及NUMBER類型的轉換等 --注意:若是該列有主外鍵、索引、約束則會修改失敗 --參數:pUSER-數據庫用戶,pTABLENAME-表名,pNEWCOLTYPE-修改以後的列類型,pOLDCOLTYPE-修改以前的列類型(若是爲空,則不對原始類型作特定處理),pCOLNAME-要修改的原始列名 --調用: /* DECLARE PUSER VARCHAR2(200); PTABLENAME VARCHAR2(200); PCOLNAME VARCHAR2(200); PNEWCOLTYPE VARCHAR2(200); pATTR VARCHAR2(200); PSQLTEXT CLOB; BEGIN PUSER := 'DKGLL'; PTABLENAME := 'ALM_ALARMDEVICE'; PCOLNAME := 'DVRNAME'; PNEWCOLTYPE := 'VARCHAR2(64 BYTE)'; pATTR :=' DEFAULT ''21''''211'' NOT NULL '; PKG_COMPAREDB.UPDATE_COL_TYPE( PUSER => PUSER, PTABLENAME => PTABLENAME, PCOLNAME => PCOLNAME, PNEWCOLTYPE => PNEWCOLTYPE, pATTR => pATTR, pNULLTEXT => 'NOT NULL', PSQLTEXT => PSQLTEXT ); DBMS_OUTPUT.PUT_LINE('PSQLTEXT = ' || PSQLTEXT); END; */ --日期:2016-01-27 ( pUSER IN VARCHAR2, pTABLENAME IN VARCHAR2, pCOLNAME IN VARCHAR2, pNEWCOLTYPE IN VARCHAR2, pOLDCOLTYPE IN VARCHAR2:=NULL, pATTR IN VARCHAR2, pNULLTEXT IN VARCHAR2, pSQLTEXT OUT CLOB ) AS pCOUNT PLS_INTEGER; pDATACOUNT NUMBER:=9999; pCOMMCOUNT PLS_INTEGER; pCOLTYPE VARCHAR2(50); pMIDTB VARCHAR2(30); pNEWCOLTYPE1 VARCHAR2(30); pCOMMENT VARCHAR2(4000); BEGIN SELECT COUNT(1) INTO pCOUNT FROM SYS.DBA_TAB_COLUMNS WHERE OWNER=pUSER AND TABLE_NAME=pTABLENAME AND COLUMN_NAME=pCOLNAME AND DATA_TYPE NOT LIKE '%CLOB'; IF pCOUNT=1 THEN --表、列存在而且列不爲CLOB類型則進行修改 SELECT CASE WHEN pNEWCOLTYPE LIKE '%CLOB' OR pNEWCOLTYPE LIKE '%NUMBER%' OR pOLDCOLTYPE LIKE 'N%CHAR%' OR pOLDCOLTYPE LIKE '%NUMBER%' THEN pNEWCOLTYPE ELSE 'CLOB' END INTO pNEWCOLTYPE1 FROM DUAL; SELECT COUNT(1) INTO pCOUNT FROM SYS.DBA_TAB_COLUMNS WHERE OWNER=pUSER AND TABLE_NAME=pTABLENAME AND COLUMN_NAME=pCOLNAME AND DATA_TYPE='LONG'; IF pNEWCOLTYPE LIKE '%NUMBER%' OR pOLDCOLTYPE LIKE '%NUMBER%' THEN EXECUTE IMMEDIATE 'SELECT COUNT(1) FROM "'||pUSER||'"."'||pTABLENAME||'" WHERE '||pCOLNAME||' IS NOT NULL ' INTO pDATACOUNT; END IF; --非LONG類型、NUMBER字段不爲空時須要經過創建中間列的方式進行修改 --注意:此處需解決原有列的主外鍵、約束、默認值、索引、列註釋等問題 IF pCOUNT=0 AND pDATACOUNT>0 THEN --pMIDTB:='MID_'||TO_CHAR(SYSTIMESTAMP,'YYYYMMDDHH24MISSFF3'); pMIDTB:='MID_'||SUBSTR(REPLACE(SYS.DBMS_RANDOM.VALUE(1,9),'.',''),1,16); pSQLTEXT:='ALTER TABLE "'||pUSER||'"."'||pTABLENAME||'" ADD '||pMIDTB||' '||pNEWCOLTYPE1||pATTR||';'; IF pATTR LIKE '%NOT NULL%' THEN pSQLTEXT:=pSQLTEXT||CHR(10)||'DELETE "'||pUSER||'"."'||pTABLENAME||'" WHERE "'||pCOLNAME||'" IS NULL;'; END IF; pSQLTEXT:=pSQLTEXT||CHR(10)||'UPDATE "'||pUSER||'"."'||pTABLENAME||'" SET '||pMIDTB||'=TO_CHAR("'||pCOLNAME||'");'; pSQLTEXT:=pSQLTEXT||CHR(10)||'ALTER TABLE "'||pUSER||'"."'||pTABLENAME||'" DROP COLUMN "'||pCOLNAME||'";'; pSQLTEXT:=pSQLTEXT||CHR(10)||'ALTER TABLE "'||pUSER||'"."'||pTABLENAME||'" RENAME COLUMN '||pMIDTB||' TO "'||pCOLNAME||'";'; SELECT COUNT(1) INTO pCOMMCOUNT FROM SYS.DBA_COL_COMMENTS WHERE OWNER=pUSER AND TABLE_NAME=pTABLENAME AND COLUMN_NAME=pCOLNAME; IF pCOMMCOUNT>0 THEN SELECT 'COMMENT ON COLUMN "'||pUSER||'"."'||TABLE_NAME||'"."'||COLUMN_NAME||'" IS '''||REPLACE(COMMENTS,'''','''''')||''';' INTO pCOMMENT FROM SYS.DBA_COL_COMMENTS WHERE OWNER=pUSER AND TABLE_NAME=pTABLENAME AND COLUMN_NAME=pCOLNAME; pSQLTEXT:=pSQLTEXT||CHR(10)||pCOMMENT; END IF; ELSE --LONG類型可直接修改成CLOB類型,NUMBER類型爲空時也能夠修改成其餘類型 pSQLTEXT:='ALTER TABLE "'||pUSER||'"."'||pTABLENAME||'" MODIFY ("'||pCOLNAME||'" '||pNEWCOLTYPE||pNULLTEXT||');'; END IF; END IF; END; PROCEDURE COMPARE_SEQUENCE --功能:獲取對比修改序列的語句 --參數: --調用: /* DECLARE pSQLTEXT CLOB; BEGIN PKG_COMPAREDB.COMPARE_SEQUENCE('TEST','',NULL,pSQLTEXT); --DBMS_OUTPUT.PUT_LINE(pSQLTEXT); PKG_DBMANAGE.CLOB_TO_FILE('BACKDIR','('||TO_CHAR(CURRENT_DATE,'YYYYMMDDHH24')||').sql','1',pSQLTEXT); END; */ --日期:2016-02-10 ( pSOURCEUSER IN VARCHAR2, --源用戶名 pTARGETUSER IN VARCHAR2, --目標用戶名 pSEQUENCENAME IN VARCHAR2:=NULL, --源序列名,能夠爲一個或多個序列,多個序列以','分隔,爲空則選擇全部序列 pSQLTEXT OUT CLOB ) AS pSEQTEXT VARCHAR2(1000); pREPLACEUSER VARCHAR2(200); pMIN_VALUE1 NUMBER; --源序列最小值 pMIN_VALUE2 NUMBER; --目標序列最小值 pMAX_VALUE1 NUMBER; pMAX_VALUE2 NUMBER; pINCREMENT_BY1 NUMBER; pINCREMENT_BY2 NUMBER; pCACHE_SIZE1 NUMBER; pCACHE_SIZE2 NUMBER; pORDER_FLAG1 CHAR(10); pORDER_FLAG2 CHAR(10); pCYCLE_FLAG1 CHAR(10); pCYCLE_FLAG2 CHAR(10); BEGIN --若是目標用戶爲空,則表示不須要該用戶前綴 SELECT DECODE(pTARGETUSER,NULL,'','"'||pTARGETUSER||'".') INTO pREPLACEUSER FROM DUAL; --1:源序列存在而目標序列不存在則添加 FOR X IN ( SELECT * FROM SYS.DBA_SEQUENCES TA WHERE SEQUENCE_OWNER=pSOURCEUSER AND (INSTR(','||pSEQUENCENAME||',',','||SEQUENCE_NAME||',',1)>0 OR pSEQUENCENAME IS NULL) AND NOT EXISTS ( SELECT * FROM SYS.DBA_SEQUENCES WHERE SEQUENCE_OWNER=pTARGETUSER AND SEQUENCE_NAME=TA.SEQUENCE_NAME ) ) LOOP SELECT 'CREATE SEQUENCE '||pREPLACEUSER||'"'||X.SEQUENCE_NAME||'" MINVALUE '||X.MIN_VALUE||' MAXVALUE '||X.MAX_VALUE|| ' INCREMENT BY '||X.INCREMENT_BY||' START WITH '||X.LAST_NUMBER|| DECODE(X.CACHE_SIZE,0,' NOCACHE',' CACHE '||X.CACHE_SIZE)|| DECODE(X.ORDER_FLAG,'Y',' ORDER',' NOORDER')|| DECODE(X.CYCLE_FLAG,'Y',' CYCLE',' NOCYCLE')||';' INTO pSEQTEXT FROM DUAL; IF pSQLTEXT IS NOT NULL THEN pSQLTEXT:=pSQLTEXT||CHR(10)||pSEQTEXT; ELSE pSQLTEXT:=pSEQTEXT; END IF; END LOOP; --2:源序列不存在而目標序列存在則刪除 FOR X IN ( SELECT * FROM SYS.DBA_SEQUENCES TA WHERE SEQUENCE_OWNER=pTARGETUSER AND (INSTR(','||pSEQUENCENAME||',',','||SEQUENCE_NAME||',',1)>0 OR pSEQUENCENAME IS NULL) AND NOT EXISTS ( SELECT * FROM SYS.DBA_SEQUENCES WHERE SEQUENCE_OWNER=pSOURCEUSER AND SEQUENCE_NAME=TA.SEQUENCE_NAME ) ) LOOP pSQLTEXT:=pSQLTEXT||CHR(10)||'DROP SEQUENCE '||pREPLACEUSER||X.SEQUENCE_NAME||';'; END LOOP; --3:原序列、目標序列均存在且源序列的屬性與目標序列的屬性不一樣則進行修改,因爲序列屬性可能依賴於業務數據的變化,故暫定一旦序列創建,不在單獨修改序列的屬性 END; PROCEDURE COMPARE_TRIGGER --功能:因爲觸發器錯誤可能致使系統異常,須要對觸發器進行比對處理 --參數: --調用: /* DECLARE pSQLTEXT CLOB; BEGIN PKG_COMPAREDB.COMPARE_TRIGGER('DKGLL','',pSQLTEXT); --DBMS_OUTPUT.PUT_LINE(pSQLTEXT); PKG_DBMANAGE.CLOB_TO_FILE('BACKDIR','('||TO_CHAR(CURRENT_DATE,'YYYYMMDDHH24')||').sql','1',pSQLTEXT); END; */ --日期:2016-02-18 ( pSOURCEUSER IN VARCHAR2, --源用戶名 pTARGETUSER IN VARCHAR2, --目標用戶名 pSQLTEXT OUT CLOB ) AS BEGIN --1:源TRIGGER不存在而目標TRIGGER存在則刪除 --2:源TRIGGER與目標TRIGGER的狀態不一致需進行修改 FOR X IN ( SELECT 'DROP TRIGGER "'||pTARGETUSER||'"."'||TRIGGER_NAME||'";' AS TRIGTEXT FROM SYS.DBA_TRIGGERS TA WHERE OWNER=pTARGETUSER AND NOT EXISTS ( SELECT * FROM SYS.DBA_TRIGGERS WHERE OWNER=pSOURCEUSER AND TRIGGER_NAME=TA.TRIGGER_NAME ) UNION ALL SELECT 'ALTER TRIGGER "'||pTARGETUSER||'".'||TA.TRIGGER_NAME||TA.STATUS AS TRIGTEXT FROM SYS.DBA_TRIGGERS TA JOIN SYS.DBA_TRIGGERS TB ON (TA.OWNER=pTARGETUSER AND TB.OWNER=pSOURCEUSER AND TA.TRIGGER_NAME=TB.TRIGGER_NAME AND TA.STATUS<>TB.STATUS) ) LOOP IF pSQLTEXT IS NOT NULL THEN pSQLTEXT:=pSQLTEXT||CHR(10)||X.TRIGTEXT; ELSE pSQLTEXT:=X.TRIGTEXT; END IF; END LOOP; END; PROCEDURE COMPARE_JOB --功能:獲取對比修改JOB的SQL語句 --參數: --調用: /* DECLARE pSQLTEXT CLOB; BEGIN PKG_COMPAREDB.COMPARE_JOB('TEST','',pSQLTEXT); DBMS_OUTPUT.PUT_LINE(pSQLTEXT); --PKG_DBMANAGE.CLOB_TO_FILE('BACKDIR','('||TO_CHAR(CURRENT_DATE,'YYYYMMDDHH24')||').sql','1',pSQLTEXT); END; */ --日期:2016-02-18 ( pSOURCEUSER IN VARCHAR2, --源用戶名 pTARGETUSER IN VARCHAR2, --目標用戶名 pTAG IN PLS_INTEGER, --0-比較,1:不比較,直接獲取全部源碼 pSQLTEXT OUT CLOB ) AS pJOBTEXT VARCHAR2(2000); pREPLACEUSER VARCHAR2(200); BEGIN SELECT NVL(pTARGETUSER,USER) INTO pREPLACEUSER FROM DUAL; --原則上一個JOB經過WHAT(幹什麼),INTERVAL(執行間隔時間)來區分 --1:源JOB存在而目標JOB不存在則添加 FOR X IN ( SELECT * FROM SYS.DBA_JOBS TA WHERE LOG_USER=pSOURCEUSER AND PRIV_USER=pSOURCEUSER AND SCHEMA_USER=pSOURCEUSER AND ( NOT EXISTS ( SELECT * FROM SYS.DBA_JOBS WHERE pTAG=0 AND LOG_USER=pTARGETUSER AND PRIV_USER=pTARGETUSER AND SCHEMA_USER=pTARGETUSER AND UPPER("WHAT")=UPPER(TA."WHAT") AND UPPER("INTERVAL")=UPPER(TA."INTERVAL") ) OR pTAG=1 ) ) LOOP pJOBTEXT:='DECLARE JOBNO NUMBER;'||CHR(10)|| ' pCOUNT PLS_INTEGER;'||CHR(10)|| 'BEGIN'||CHR(10)|| ' SELECT COUNT(1) INTO pCOUNT FROM SYS.DBA_JOBS TA WHERE LOG_USER='''||pREPLACEUSER||''' AND PRIV_USER='''||pREPLACEUSER||''' AND SCHEMA_USER='''||pREPLACEUSER||''' AND WHAT='''||X.WHAT||''' AND interval= '''||X.INTERVAL||''';'||CHR(10)|| ' IF pCOUNT = 0 THEN'||CHR(10)|| ' SYS.DBMS_JOB.SUBMIT(job => JOBNO,'||CHR(10)|| ' what => '''||X.WHAT||''','||CHR(10)|| ' next_date => TO_DATE('''||TO_CHAR(X.NEXT_DATE,'YYYY-MM-DD HH24:MI:SS')||''',''YYYY-MM-DD HH24:MI:SS''),'||CHR(10)|| ' interval => '''||X.INTERVAL||''');'||CHR(10)|| ' COMMIT;'||CHR(10)|| ' END IF;'||CHR(10)|| 'END;'||CHR(10)|| '/'; IF pSQLTEXT IS NOT NULL THEN pSQLTEXT:=pSQLTEXT||CHR(10)||pJOBTEXT; ELSE pSQLTEXT:=pJOBTEXT; END IF; END LOOP; --2:源JOB不存在而目標JOB存在則刪除 FOR X IN ( SELECT * FROM SYS.DBA_JOBS TA WHERE LOG_USER=pTARGETUSER AND PRIV_USER=pTARGETUSER AND SCHEMA_USER=pTARGETUSER AND NOT EXISTS ( SELECT * FROM SYS.DBA_JOBS WHERE LOG_USER=pSOURCEUSER AND PRIV_USER=pSOURCEUSER AND SCHEMA_USER=pSOURCEUSER AND UPPER("WHAT")=UPPER(TA."WHAT") AND UPPER("INTERVAL")=UPPER(TA."INTERVAL") ) ) LOOP pJOBTEXT:='DECLARE pCOUNT PLS_INTEGER;'||CHR(10)|| 'BEGIN'||CHR(10)|| ' SELECT COUNT(1) INTO pCOUNT FROM SYS.DBA_JOBS TA WHERE LOG_USER='''||pREPLACEUSER||''' AND PRIV_USER='''||pREPLACEUSER||''' AND SCHEMA_USER='''||pREPLACEUSER||''' AND WHAT='''||X.WHAT||''' AND interval= '''||X.INTERVAL||''';'||CHR(10)|| ' IF pCOUNT <> 0 THEN'||CHR(10)|| ' DBMS_JOB.REMOVE('||X.JOB||'); '||CHR(10)|| ' COMMIT;'||CHR(10)|| ' END IF;'||CHR(10)|| 'END;'||CHR(10)|| '/'; IF pSQLTEXT IS NOT NULL THEN pSQLTEXT:=pSQLTEXT||CHR(10)||pJOBTEXT; ELSE pSQLTEXT:=pJOBTEXT; END IF; END LOOP; END; PROCEDURE COMPARE_SCHEDULER --功能:獲取對比修改SCHEDULER JOB的SQL語句 --參數: --調用: /* DECLARE pSQLTEXT CLOB; BEGIN PKG_COMPAREDB.COMPARE_SCHEDULER('TEST','DKGLL',1,pSQLTEXT); DBMS_OUTPUT.PUT_LINE(pSQLTEXT); --PKG_DBMANAGE.CLOB_TO_FILE('BACKDIR','('||TO_CHAR(CURRENT_DATE,'YYYYMMDDHH24')||').sql','1',pSQLTEXT); END; */ --日期:2016-02-18 ( pSOURCEUSER IN VARCHAR2, --源用戶名 pTARGETUSER IN VARCHAR2, --目標用戶名 pTAG IN PLS_INTEGER, --0-比較,1:不比較,直接獲取全部源碼, pSQLTEXT OUT CLOB ) AS pREPLACEUSER VARCHAR2(200); pSCHEDULERTEXT VARCHAR2(4000); pCREATEJOBTEXT VARCHAR2(4000); pATTRTEXT VARCHAR2(4000); pLOGLEVEL VARCHAR2(200); BEGIN SELECT NVL(pTARGETUSER,USER) INTO pREPLACEUSER FROM DUAL; --1:源SCHEDULER JOB存在而目標SCHEDULER JOB不存在則添加 FOR X IN ( SELECT * FROM SYS.DBA_SCHEDULER_JOBS TA WHERE OWNER=pSOURCEUSER AND ( NOT EXISTS ( SELECT * FROM SYS.DBA_SCHEDULER_JOBS WHERE pTAG=0 AND OWNER=pTARGETUSER AND UPPER("JOB_NAME")=UPPER(TA."JOB_NAME") ) OR pTAG=1 ) ) LOOP pCREATEJOBTEXT := ''; pATTRTEXT := ''; SELECT DECODE(X.LOGGING_LEVEL,'OFF','LOGGING_OFF','FAILED RUNS','LOGGING_FAILED_RUNS','RUNS','LOGGING_RUNS','FULL','LOGGING_FULL') INTO pLOGLEVEL FROM DUAL; pCREATEJOBTEXT := ' DBMS_SCHEDULER.CREATE_JOB ('||CHR(10)|| ' job_name => ''"'||pREPLACEUSER||'"."'||X.JOB_NAME||'"'','||CHR(10)|| ' job_type => '''||X.JOB_TYPE||''','||CHR(10)|| ' job_action => '''||pREPLACEUSER||'.'||LTRIM(X.JOB_ACTION,pSOURCEUSER||'.')||''','||CHR(10)|| ' number_of_arguments => '||X.number_of_arguments||','||CHR(10)|| ' start_date => TO_TIMESTAMP_TZ('''||TO_CHAR(X.START_DATE,'YYYY-MM-DD HH24:MI:SS:FF4')||''',''YYYY-MM-DD HH24:MI:SS.FF TZR''),'||CHR(10)|| ' repeat_interval => '''||X.REPEAT_INTERVAL||''','||CHR(10)|| ' end_date => TO_TIMESTAMP_TZ('''||TO_CHAR(X.END_DATE,'YYYY-MM-DD HH24:MI:SS:FF4')||''',''YYYY-MM-DD HH24:MI:SS.FF TZR''),'||CHR(10)|| ' enabled => '||X.ENABLED||','||CHR(10)|| ' auto_drop => '||X.AUTO_DROP||','||CHR(10)|| ' comments => '''||X.COMMENTS||''');'||CHR(10); IF X.RESTARTABLE IS NOT NULL THEN pATTRTEXT := pATTRTEXT||CHR(10)||' DBMS_SCHEDULER.SET_ATTRIBUTE( '||CHR(10)|| ' name => ''"'||pREPLACEUSER||'"."'||X.JOB_NAME||'"'','||CHR(10)|| ' attribute => ''restartable'', value => '||X.RESTARTABLE||');'||CHR(10); END IF; --並行查詢暫時有問題 -- IF X.RESTARTABLE IS NOT NULL THEN -- pATTRTEXT := pATTRTEXT||CHR(10)||' DBMS_SCHEDULER.SET_ATTRIBUTE( '||CHR(10)|| -- ' name => ''"'||pREPLACEUSER||'"."'||X.JOB_NAME||'"'','||CHR(10)|| -- ' attribute => ''parallel_instances'', value => '||X.RESTARTABLE||');'||CHR(10); -- END IF; IF X.job_priority IS NOT NULL THEN pATTRTEXT := pATTRTEXT||CHR(10)||' DBMS_SCHEDULER.SET_ATTRIBUTE( '||CHR(10)|| ' name => ''"'||pREPLACEUSER||'"."'||X.JOB_NAME||'"'','||CHR(10)|| ' attribute => ''job_priority'', value => '||X.job_priority||');'||CHR(10); END IF; IF pLOGLEVEL IS NOT NULL THEN pATTRTEXT := pATTRTEXT||CHR(10)||' DBMS_SCHEDULER.SET_ATTRIBUTE( '||CHR(10)|| ' name => ''"'||pREPLACEUSER||'"."'||X.JOB_NAME||'"'','||CHR(10)|| ' attribute => ''logging_level'', value => DBMS_SCHEDULER.'||pLOGLEVEL||');'||CHR(10); END IF; IF X.INSTANCE_ID IS NOT NULL THEN pATTRTEXT := pATTRTEXT||CHR(10)||' DBMS_SCHEDULER.SET_ATTRIBUTE( '||CHR(10)|| ' name => ''"'||pREPLACEUSER||'"."'||X.JOB_NAME||'"'','||CHR(10)|| ' attribute => ''instance_id'', value => '||X.INSTANCE_ID||');'||CHR(10); END IF; IF X.MAX_FAILURES IS NOT NULL THEN pATTRTEXT := pATTRTEXT||CHR(10)||' DBMS_SCHEDULER.SET_ATTRIBUTE( '||CHR(10)|| ' name => ''"'||pREPLACEUSER||'"."'||X.JOB_NAME||'"'','||CHR(10)|| ' attribute => ''max_failures'', value => '||X.MAX_FAILURES||');'||CHR(10); END IF; IF X.MAX_RUNS IS NOT NULL THEN pATTRTEXT := pATTRTEXT||CHR(10)||' DBMS_SCHEDULER.SET_ATTRIBUTE( '||CHR(10)|| ' name => ''"'||pREPLACEUSER||'"."'||X.JOB_NAME||'"'','||CHR(10)|| ' attribute => ''max_runs'', value => '||X.MAX_RUNS||');'||CHR(10); END IF; IF X.max_run_duration IS NOT NULL THEN pATTRTEXT := pATTRTEXT||CHR(10)||' DBMS_SCHEDULER.SET_ATTRIBUTE( '||CHR(10)|| ' name => ''"'||pREPLACEUSER||'"."'||X.JOB_NAME||'"'','||CHR(10)|| ' attribute => ''max_run_duration'', value => to_dsinterval('''||X.max_run_duration||'''));'||CHR(10); END IF; IF X.SCHEDULE_LIMIT IS NOT NULL THEN pATTRTEXT := pATTRTEXT||CHR(10)||' DBMS_SCHEDULER.SET_ATTRIBUTE( '||CHR(10)|| ' name => ''"'||pREPLACEUSER||'"."'||X.JOB_NAME||'"'','||CHR(10)|| ' attribute => ''SCHEDULE_LIMIT'', value => to_dsinterval('''||X.SCHEDULE_LIMIT||'''));'||CHR(10); END IF; pSCHEDULERTEXT := 'DECLARE pCOUNT PLS_INTEGER;'||CHR(10)|| 'BEGIN'||CHR(10)|| ' SELECT COUNT(1) INTO pCOUNT FROM SYS.DBA_SCHEDULER_JOBS TA WHERE OWNER='''||pREPLACEUSER||''' AND UPPER("JOB_NAME")=UPPER('''||X.JOB_NAME||''');'||CHR(10)|| ' IF pCOUNT = 0 THEN'||CHR(10)||pCREATEJOBTEXT||pATTRTEXT||CHR(10)|| ' DBMS_SCHEDULER.enable('||CHR(10)|| ' name => ''"'||pREPLACEUSER||'"."'||X.JOB_NAME||'"'');'||CHR(10)|| ' END IF;'||CHR(10)|| 'END;'||CHR(10)|| '/'; IF pSQLTEXT IS NOT NULL THEN pSQLTEXT:=pSQLTEXT||CHR(10)||pSCHEDULERTEXT; ELSE pSQLTEXT:=pSCHEDULERTEXT; END IF; END LOOP; --2:源SCHEDULER JOB不存在而目標SCHEDULER JOB存在則刪除 FOR X IN ( SELECT * FROM SYS.DBA_SCHEDULER_JOBS TA WHERE OWNER=pTARGETUSER AND NOT EXISTS ( SELECT * FROM SYS.DBA_SCHEDULER_JOBS WHERE OWNER=pSOURCEUSER AND UPPER("JOB_NAME")=UPPER(TA."JOB_NAME") ) ) LOOP pSCHEDULERTEXT := 'DECLARE pCOUNT PLS_INTEGER;'||CHR(10)|| 'BEGIN'||CHR(10)|| ' SELECT COUNT(1) INTO pCOUNT FROM SYS.DBA_SCHEDULER_JOBS TA WHERE OWNER='''||pREPLACEUSER||''' AND UPPER("JOB_NAME")=UPPER('''||X.JOB_NAME||''');'||CHR(10)|| ' IF pCOUNT <> 0 THEN'||CHR(10)|| ' DBMS_SCHEDULER.DROP_JOB(job_name => ''"'||X.JOB_NAME||'"'','||CHR(10)|| ' defer => false,'||CHR(10)|| ' force => false);'||CHR(10)|| ' END IF;'||CHR(10)|| 'END;'||CHR(10)|| '/'; IF pSQLTEXT IS NOT NULL THEN pSQLTEXT:=pSQLTEXT||CHR(10)||pSCHEDULERTEXT; ELSE pSQLTEXT:=pSCHEDULERTEXT; END IF; END LOOP; END; PROCEDURE COMPARE_TABLE --功能:獲取對比修改表的SQL語句,注意:此處pSOURCEUSER,pTARGETUSER,pTABLENAME默認所有爲大寫.因爲獲取源碼權限問題,該過程只能在源用戶庫上執行 --參數: --調用: /* DECLARE pSQLTEXT CLOB; BEGIN PKG_COMPAREDB.COMPARE_TABLE('TEST','DKGLL','',1,pSQLTEXT); --pTARGETUSER爲空表示導出該源用戶下的全部表 --DBMS_OUTPUT.PUT_LINE(pSQLTEXT); PKG_DBMANAGE.CLOB_TO_FILE('BACKDIR','('||TO_CHAR(CURRENT_DATE,'YYYYMMDDHH24')||').sql','1',pSQLTEXT); END; */ --日期:2016-02-10 ( pSOURCEUSER IN VARCHAR2, --源用戶名 pTARGETUSER IN VARCHAR2, --目標用戶名 pTABLENAME IN VARCHAR2:=NULL, --源表,能夠爲一張或多張表,多個表以','分隔,爲空則選擇結構類型一致的全部表 pDROPTABLE IN NUMBER:=1, --是否刪除表:0-不刪除,其餘-刪除,默認-刪除 pSQLTEXT OUT CLOB ) AS pINDEX PLS_INTEGER; pCOUNT PLS_INTEGER; pCOUNT1 PLS_INTEGER; pCOUNT2 PLS_INTEGER; pATTR VARCHAR2(2000); pUPDATECOL VARCHAR2(4000); pREPLACEUSER VARCHAR2(200); --替換目標用戶的文本,如"DKGLL". pSOURCECODE CLOB; --源DDL源碼 pTARGETCODE CLOB; --目標DDL源碼 pTBCOMMENT VARCHAR2(4000); --表註釋文本 pFOREIGN VARCHAR2(2000); --外鍵語句 pPRIMARY VARCHAR2(2000); --依賴主鍵部分語句 pREBULIDFORRIGN VARCHAR2(2000):=''; --重建外鍵語句 pRULECODE VARCHAR2(4000); --約束(檢查、惟一)語句 pTAG CHAR(20); --標誌是否須要修改 BEGIN pINDEX:=0; --若是目標用戶爲空,則表示不須要該用戶前綴 SELECT DECODE(pTARGETUSER,NULL,'','"'||pTARGETUSER||'".') INTO pREPLACEUSER FROM DUAL; --1:源表存在而目標表不存在則添加,須要解決主外鍵的依賴關係,經過遞歸外鍵依賴表的鏈路進行排序,先添加主鍵表,再添加外鍵表 FOR X IN ( WITH TB AS ( SELECT TB.CONSTRAINT_NAME,TB.CONSTRAINT_TYPE,TB.TABLE_NAME,TC.CONSTRAINT_NAME AS R_CONSTRAINT_NAME,TC.TABLE_NAME AS R_TABLE_NAME,TC.CONSTRAINT_TYPE AS R_CONSTRAINT_TYPE FROM SYS.DBA_CONSTRAINTS TB LEFT JOIN SYS.DBA_CONSTRAINTS TC ON (TB.R_OWNER=TC.OWNER AND TB.R_CONSTRAINT_NAME=TC.CONSTRAINT_NAME) WHERE TB.OWNER=pSOURCEUSER AND TB.CONSTRAINT_TYPE IN('P','R') AND (INSTR(','||pTABLENAME||',',','||TB.TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL) AND TB.TABLE_NAME<>TC.TABLE_NAME --加上此條件是爲了防止當表中外鍵列依賴於本表主鍵列是會在下邊的查詢中報conect by循環錯誤 ) SELECT T1.*,T2.ML FROM ( SELECT * FROM SYS.DBA_TABLES TA WHERE OWNER=pSOURCEUSER AND (INSTR(','||pTABLENAME||',',','||TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL) AND NOT EXISTS ( SELECT * FROM SYS.DBA_TABLES WHERE OWNER=pTARGETUSER AND TABLE_NAME=TA.TABLE_NAME ) ) T1 LEFT JOIN ( SELECT * FROM ( SELECT DISTINCT TABLE_NAME,ML FROM ( SELECT TABLE_NAME,TOPTABLE_NAME,LN,MAX(LN) OVER(PARTITION BY TABLE_NAME) AS ML FROM ( SELECT DISTINCT TABLE_NAME,CONNECT_BY_ROOT TABLE_NAME AS TOPTABLE_NAME,LEVEL AS LN FROM TB CONNECT BY PRIOR TABLE_NAME=R_TABLE_NAME ORDER BY TABLE_NAME,LN ) ) WHERE LN=ML ) ) T2 ON T1.TABLE_NAME=T2.TABLE_NAME ORDER BY NVL(ML,-1),T1.TABLE_NAME ) LOOP SELECT COUNT(1) INTO pCOUNT2 FROM SYS.DBA_OBJECTS WHERE OWNER=pSOURCEUSER AND OBJECT_NAME=X.TABLE_NAME AND OBJECT_TYPE='MATERIALIZED VIEW'; IF pCOUNT2=0 THEN IF pINDEX=0 THEN pSQLTEXT:='--開始添加新表--------------------------------------------------------------------'; END IF; pINDEX:=pINDEX+1; --1.1:獲取建表的源碼 PKG_GET_DDL.GET_DDL(pSOURCEUSER,pTARGETUSER,1,X.TABLE_NAME,2,pSOURCECODE); pSQLTEXT:=pSQLTEXT||pSOURCECODE; --1.2:獲取列註釋 FOR Y IN ( SELECT 'COMMENT ON COLUMN '||pREPLACEUSER||'"'||TABLE_NAME||'"."'||COLUMN_NAME||'" IS '''||REPLACE(COMMENTS,'''','''''')||''';' AS COLCOMMENT FROM SYS.DBA_COL_COMMENTS WHERE OWNER=pSOURCEUSER AND TABLE_NAME=X.TABLE_NAME AND COMMENTS IS NOT NULL ) LOOP pSQLTEXT:=pSQLTEXT||CHR(10)||Y.COLCOMMENT; END LOOP; --1.3:獲取表註釋 SELECT COUNT(1) INTO pCOUNT FROM SYS.DBA_TAB_COMMENTS WHERE OWNER=pSOURCEUSER AND TABLE_NAME=X.TABLE_NAME AND COMMENTS IS NOT NULL; IF pCOUNT=1 THEN SELECT 'COMMENT ON TABLE '||pREPLACEUSER||'"'||TABLE_NAME||'" IS '''||REPLACE(COMMENTS,'''','''''')||''';' INTO pTBCOMMENT FROM SYS.DBA_TAB_COMMENTS WHERE OWNER=pSOURCEUSER AND TABLE_NAME=X.TABLE_NAME AND COMMENTS IS NOT NULL; pSQLTEXT:=pSQLTEXT||CHR(10)||pTBCOMMENT||CHR(10); ELSE pSQLTEXT:=pSQLTEXT||CHR(10); END IF; --1.4:獲取索引源碼 FOR Y IN ( SELECT INDEX_NAME FROM SYS.DBA_INDEXES TA WHERE OWNER=pSOURCEUSER AND TABLE_NAME=X.TABLE_NAME AND INDEX_NAME NOT LIKE 'BIN$%' AND INDEX_TYPE NOT IN('LOB') AND NOT EXISTS ( SELECT * FROM SYS.DBA_CONSTRAINTS WHERE OWNER=pSOURCEUSER AND TABLE_NAME=TA.TABLE_NAME AND INDEX_NAME=TA.INDEX_NAME ) ) LOOP PKG_GET_DDL.GET_DDL(pSOURCEUSER,pTARGETUSER,1,Y.INDEX_NAME,3,pSOURCECODE); pSQLTEXT:=pSQLTEXT||pSOURCECODE; END LOOP; END IF; END LOOP; IF pINDEX>0 THEN pSQLTEXT:=pSQLTEXT||CHR(10)||('--添加新表結束!-------------------------------------------------------------------')||CHR(10); pINDEX:=0; END IF; IF pDROPTABLE<>0 THEN --2:源表不存在而目標表存在則刪除表,須要解決主外鍵的依賴關係,經過遞歸外鍵依賴表的鏈路進行排序,先刪除外鍵表,再刪除主鍵表 --此處:若是目的數據庫包含OPENFIRE表,建議最好進行過濾,不然會致使出現問題 FOR X IN ( WITH TB AS ( SELECT TB.CONSTRAINT_NAME,TB.CONSTRAINT_TYPE,TB.TABLE_NAME,TC.CONSTRAINT_NAME AS R_CONSTRAINT_NAME,TC.TABLE_NAME AS R_TABLE_NAME,TC.CONSTRAINT_TYPE AS R_CONSTRAINT_TYPE FROM SYS.DBA_CONSTRAINTS TB LEFT JOIN SYS.DBA_CONSTRAINTS TC ON (TB.R_OWNER=TC.OWNER AND TB.R_CONSTRAINT_NAME=TC.CONSTRAINT_NAME) WHERE TB.OWNER=pTARGETUSER AND TB.CONSTRAINT_TYPE IN('P','R') AND (INSTR(','||pTABLENAME||',',','||TB.TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL) AND TB.TABLE_NAME<>TC.TABLE_NAME --加上此條件是爲了防止當表中外鍵列依賴於本表主鍵列是會在下邊的查詢中報conect by循環錯誤 ) SELECT T1.*,T2.ML FROM ( SELECT * FROM SYS.DBA_TABLES TA WHERE OWNER=pTARGETUSER AND (INSTR(','||pTABLENAME||',',','||TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL) AND NOT EXISTS ( SELECT * FROM SYS.DBA_TABLES WHERE OWNER=pSOURCEUSER AND TABLE_NAME=TA.TABLE_NAME ) ) T1 LEFT JOIN ( SELECT * FROM ( SELECT DISTINCT TABLE_NAME,ML FROM ( SELECT TABLE_NAME,TOPTABLE_NAME,LN,MAX(LN) OVER(PARTITION BY TABLE_NAME) AS ML FROM ( SELECT DISTINCT TABLE_NAME,CONNECT_BY_ROOT TABLE_NAME AS TOPTABLE_NAME,LEVEL AS LN FROM TB CONNECT BY PRIOR TABLE_NAME=R_TABLE_NAME ORDER BY TABLE_NAME,LN ) ) WHERE LN=ML ) ) T2 ON T1.TABLE_NAME=T2.TABLE_NAME ORDER BY ML DESC,T1.TABLE_NAME ) LOOP IF X.TABLE_NAME NOT LIKE 'OF%' THEN --OPENFIRE表的表以OF開頭 SELECT COUNT(1) INTO pCOUNT2 FROM SYS.DBA_OBJECTS WHERE OWNER=pTARGETUSER AND OBJECT_NAME=X.TABLE_NAME AND OBJECT_TYPE='MATERIALIZED VIEW'; IF pCOUNT2=0 THEN IF pINDEX=0 THEN pSQLTEXT:=pSQLTEXT||CHR(10)||('--開始刪除沒必要要的表---------------------------------------------------------------'); END IF; pINDEX:=pINDEX+1; --pSQLTEXT:=pSQLTEXT||CHR(10)||'DROP TABLE "'||pTARGETUSER||'".'||X.TABLE_NAME||';'; pSQLTEXT:=pSQLTEXT||CHR(10)||'EXEC PKG_DBMANAGE.DROP_OBJECT('''||pTARGETUSER||''','''||X.TABLE_NAME||''');'; END IF; END IF; END LOOP; IF pINDEX>0 THEN pSQLTEXT:=pSQLTEXT||CHR(10)||('--刪除沒必要要的表結束!--------------------------------------------------------------')||CHR(10); pINDEX:=0; END IF; END IF; DELETE FROM TEMP_TAB_COLUMNS; --3:修改表列類型、表註釋、列註釋.特例:臨時表與普通表不能重名,不然修改沒法按照主外鍵的鏈路順序進行重建,只能簡單的進行刪除重建 FOR X IN ( SELECT TA.*,TB.TEMPORARY AS TEMPORARY2 FROM ( SELECT * FROM SYS.DBA_TABLES TA WHERE OWNER=pTARGETUSER AND (INSTR(','||pTABLENAME||',',','||TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL) ) TA JOIN ( SELECT * FROM SYS.DBA_TABLES TA WHERE OWNER=pSOURCEUSER AND (INSTR(','||pTABLENAME||',',','||TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL) ) TB ON TA.TABLE_NAME=TB.TABLE_NAME ) LOOP --表類型相同 IF X.TEMPORARY=X.TEMPORARY2 THEN --修改表列類型 INSERT INTO TEMP_TAB_COLUMNS(OWNER,TABLE_NAME,COLUMN_NAME,DATA_TYPE,ORACLETYPE,NULLABLE,DATA_DEFAULT,COLUMN_ID) SELECT OWNER,TABLE_NAME,COLUMN_NAME,DATA_TYPE, CASE WHEN DATA_TYPE IN('NUMBER') THEN REPLACE(DATA_TYPE||'('||NVL(TO_CHAR(DATA_PRECISION),'*') ||','||NVL(TO_CHAR(DATA_SCALE),'*') ||')','(*,*)','') WHEN DATA_TYPE IN ('VARCHAR2','NVARCHAR2','CHAR','NCHAR') THEN DATA_TYPE||'('||CHAR_LENGTH||')' WHEN DATA_TYPE IN ('FLOAT') THEN DATA_TYPE||'('||DATA_PRECISION||')' ELSE DATA_TYPE END AS ORACLETYPE,NULLABLE,TO_LOB(DATA_DEFAULT) AS DATA_DEFAULT,COLUMN_ID FROM SYS.DBA_TAB_COLUMNS WHERE OWNER IN (pSOURCEUSER,pTARGETUSER) AND TABLE_NAME=X.TABLE_NAME AND (INSTR(','||pTABLENAME||',',','||TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL) ORDER BY TABLE_NAME,COLUMN_ID; FOR Y1 IN ( SELECT 'ALTER TABLE '||pREPLACEUSER||'"'||X.TABLE_NAME||'"'|| DECODE(OPRTYPE,'ADD',' ADD "'||COLUMN_NAME1||'" '||ORACLETYPE1,'MOD',' MODIFY "'||COLUMN_NAME1||'" '||ORACLETYPE1,'DROP',' DROP COLUMN '||COLUMN_NAME2,'') AS SQLTEXT, DECODE(NULLABLE1,NULLABLE2,'',DECODE(NULLABLE1,'N',' NOT NULL','Y',' NULL')) AS NULL_SQLTEXT, DECODE(DATA_DEFAULT1,'NULL','',' DEFAULT '||DATA_DEFAULT1) AS DATA_DEFAULT, 'ALTER TABLE '||pREPLACEUSER||'"'||X.TABLE_NAME||'" MODIFY ("'||COLUMN_NAME1||'" DEFAULT '||DECODE(DATA_DEFAULT1,'NULL','NULL',DATA_DEFAULT1)||');' AS DEFAULT_SQLTEXT,OPRTYPE, DATA_DEFAULT1,DATA_DEFAULT2,NULLABLE1,ORACLETYPE1,DATA_TYPE1,DATA_TYPE2,COLUMN_NAME1,COLUMN_ID1,COLUMN_ID2 FROM ( SELECT TA.TABLE_NAME, TA.COLUMN_NAME AS COLUMN_NAME1,TA.DATA_TYPE AS DATA_TYPE1,TA.ORACLETYPE AS ORACLETYPE1,TA.NULLABLE AS NULLABLE1,TA.DATA_DEFAULT AS DATA_DEFAULT1, TC.COLUMN_NAME AS COLUMN_NAME2,TC.DATA_TYPE AS DATA_TYPE2,TC.ORACLETYPE AS ORACLETYPE2,TC.NULLABLE AS NULLABLE2,TC.DATA_DEFAULT AS DATA_DEFAULT2, CASE WHEN TC.ORACLETYPE||TC.NULLABLE IS NULL THEN 'ADD' WHEN TA.ORACLETYPE||TA.NULLABLE IS NULL THEN 'DROP' WHEN NVL(TC.ORACLETYPE||TC.NULLABLE,' ')<>TA.ORACLETYPE||TA.NULLABLE THEN 'MOD' ELSE '' END AS OPRTYPE,TA.COLUMN_ID AS COLUMN_ID1,TC.COLUMN_ID AS COLUMN_ID2 FROM ( SELECT TABLE_NAME,COLUMN_NAME,DATA_TYPE,ORACLETYPE,TRIM(NULLABLE) AS NULLABLE,TO_CHAR(NVL(DATA_DEFAULT,'NULL')) AS DATA_DEFAULT,COLUMN_ID FROM TEMP_TAB_COLUMNS WHERE OWNER=pSOURCEUSER AND TABLE_NAME=X.TABLE_NAME ) TA FULL JOIN ( SELECT TABLE_NAME,COLUMN_NAME,DATA_TYPE,ORACLETYPE,TRIM(NULLABLE) AS NULLABLE,TO_CHAR(NVL(DATA_DEFAULT,'NULL')) AS DATA_DEFAULT,COLUMN_ID FROM TEMP_TAB_COLUMNS WHERE OWNER=pTARGETUSER AND TABLE_NAME=X.TABLE_NAME ) TC ON (TA.TABLE_NAME=TC.TABLE_NAME AND TA.COLUMN_NAME=TC.COLUMN_NAME) ) WHERE OPRTYPE IS NOT NULL OR ASCII(DATA_DEFAULT1)<>ASCII(DATA_DEFAULT2) ORDER BY DECODE(OPRTYPE,'ADD',1,'MOD',2,'DROP',3),COLUMN_ID1,COLUMN_ID2 ) LOOP IF Y1.OPRTYPE IS NOT NULL AND (Y1.DATA_TYPE2 NOT LIKE '%CLOB' OR Y1.DATA_TYPE2 IS NULL) THEN --此處暫時不處理CLOB類型到其餘類型的轉化 pINDEX:=pINDEX+1; IF pINDEX=1 THEN pSQLTEXT:=pSQLTEXT||CHR(10)||('--開始修改表類型、列類型、表註釋、列註釋----------------------------------------------'); END IF; --此處暫時只處理(其餘類型到CLOB的類型轉換、NVARCHR到其餘類型的轉換等)問題 --注意:若是該列有主外鍵、索引、約束則會修改失敗 IF (Y1.OPRTYPE='MOD' AND (Y1.DATA_TYPE1 LIKE '%CLOB' OR Y1.DATA_TYPE1 LIKE '%NUMBER%' OR Y1.DATA_TYPE2 LIKE 'N%CHAR%' OR Y1.DATA_TYPE2 LIKE '%NUMBER%')) THEN --DBMS_OUTPUT.PUT_LINE(pTARGETUSER||','||X.TABLE_NAME||','||Y1.COLUMN_NAME1||','||Y1.DATA_TYPE1||','||Y1.NULL_SQLTEXT||' '||Y1.DATA_DEFAULT||pUPDATECOL); pUPDATECOL:=''; IF Y1.DATA_TYPE1 NOT LIKE '%NUMBER%' THEN SELECT DECODE(Y1.NULLABLE1,'N',NVL(Y1.DATA_DEFAULT,' DEFAULT ''''')||' NOT NULL','Y',Y1.DATA_DEFAULT||' NULL') INTO pATTR FROM DUAL; ELSE SELECT DECODE(Y1.NULLABLE1,'N',NVL(Y1.DATA_DEFAULT,' DEFAULT 0')||' NOT NULL','Y',Y1.DATA_DEFAULT||' NULL') INTO pATTR FROM DUAL; END IF; IF Y1.DATA_TYPE1 LIKE '%CLOB' THEN UPDATE_COL_TYPE(pTARGETUSER,X.TABLE_NAME,Y1.COLUMN_NAME1,Y1.DATA_TYPE1,NULL,pATTR,Y1.NULL_SQLTEXT,pUPDATECOL); ELSIF Y1.DATA_TYPE1 LIKE '%NUMBER%' OR Y1.DATA_TYPE2 LIKE 'N%CHAR%' OR Y1.DATA_TYPE2 LIKE '%NUMBER%' THEN UPDATE_COL_TYPE(pTARGETUSER,X.TABLE_NAME,Y1.COLUMN_NAME1,Y1.ORACLETYPE1,Y1.DATA_TYPE2,pATTR,Y1.NULL_SQLTEXT,pUPDATECOL); END IF; IF pUPDATECOL IS NOT NULL THEN --判斷生成修改的語句是否有效,無效則語句爲NULL pSQLTEXT:=pSQLTEXT||CHR(10)||pUPDATECOL; --若是不爲空的字段自己沒有設置默認值,則須要將默認值改回NULL IF Y1.NULLABLE1='N' AND Y1.DATA_DEFAULT IS NULL THEN pSQLTEXT:=pSQLTEXT||CHR(10)||'ALTER TABLE '||pREPLACEUSER||'"'||X.TABLE_NAME||'" MODIFY ("'||Y1.COLUMN_NAME1||'" DEFAULT NULL);'; END IF; END IF; ELSIF Y1.OPRTYPE<>'DROP' THEN IF Y1.OPRTYPE='MOD' AND Y1.NULL_SQLTEXT LIKE '%NOT NULL%' THEN --若是要修改的列原先爲null,現改成not null,則須要刪除字段值爲null的記錄 pSQLTEXT:=pSQLTEXT||CHR(10)||'DELETE '||pREPLACEUSER||'"'||X.TABLE_NAME||'" WHERE "'||Y1.COLUMN_NAME1||'" IS NULL;'; END IF; pSQLTEXT:=pSQLTEXT||CHR(10)||Y1.SQLTEXT||Y1.DATA_DEFAULT||Y1.NULL_SQLTEXT||';'; ELSE pSQLTEXT:=pSQLTEXT||CHR(10)||Y1.SQLTEXT||';'; END IF; END IF; IF (ASCII(Y1.DATA_DEFAULT1)<>ASCII(Y1.DATA_DEFAULT2) AND NOT (Y1.OPRTYPE='MOD' AND (Y1.DATA_TYPE1 LIKE '%CLOB' OR Y1.DATA_TYPE1 LIKE '%NUMBER%' OR Y1.DATA_TYPE2 LIKE 'N%CHAR%' OR Y1.DATA_TYPE2 LIKE '%NUMBER%'))) THEN pINDEX:=pINDEX+1; IF pINDEX=1 THEN pSQLTEXT:=pSQLTEXT||CHR(10)||('--開始修改表列類型、表註釋、列註釋---------------------------------------------------'); END IF; pSQLTEXT:=pSQLTEXT||CHR(10)||Y1.DEFAULT_SQLTEXT; END IF; END LOOP; --修改表註釋 FOR Y2 IN ( SELECT 'COMMENT ON TABLE '||pREPLACEUSER||'"'||TABLE_NAME||'" IS '''||REPLACE(COMMENTS,'''','''''')||''';' AS SQLTEXT FROM ( SELECT TA.TABLE_NAME,TA.COMMENTS,CASE WHEN NVL(TA.COMMENTS,' ')<>NVL(TB.COMMENTS,' ') THEN 'MOD' ELSE '' END AS OPETYPE FROM ( SELECT * FROM SYS.DBA_TAB_COMMENTS WHERE OWNER=pSOURCEUSER AND TABLE_NAME=X.TABLE_NAME ) TA LEFT JOIN ( SELECT * FROM SYS.DBA_TAB_COMMENTS WHERE OWNER=pTARGETUSER AND TABLE_NAME=X.TABLE_NAME ) TB ON TA.TABLE_NAME=TB.TABLE_NAME ) WHERE OPETYPE IS NOT NULL ) LOOP pINDEX:=pINDEX+1; IF pINDEX=1 THEN pSQLTEXT:=pSQLTEXT||CHR(10)||('--開始修改表類型、列類型、表註釋、列註釋----------------------------------------------'); END IF; pSQLTEXT:=pSQLTEXT||CHR(10)||Y2.SQLTEXT; END LOOP; --修改列註釋 FOR Y3 IN ( SELECT 'COMMENT ON COLUMN '||pREPLACEUSER||'"'||TABLE_NAME||'"."'||COLUMN_NAME||'" IS '''||REPLACE(COMMENTS,'''','''''')||''';' AS SQLTEXT FROM ( SELECT TA.TABLE_NAME,TA.COLUMN_NAME,TA.COMMENTS,CASE WHEN NVL(TA.COMMENTS,' ')<>NVL(TB.COMMENTS,' ') THEN 'MOD' ELSE '' END AS OPETYPE FROM ( SELECT * FROM SYS.DBA_COL_COMMENTS WHERE OWNER=pSOURCEUSER AND TABLE_NAME=X.TABLE_NAME ) TA LEFT JOIN ( SELECT * FROM SYS.DBA_COL_COMMENTS WHERE OWNER=pTARGETUSER AND TABLE_NAME=X.TABLE_NAME ) TB ON TA.TABLE_NAME=TB.TABLE_NAME AND TA.COLUMN_NAME=TB.COLUMN_NAME ) WHERE OPETYPE IS NOT NULL ) LOOP pINDEX:=pINDEX+1; IF pINDEX=1 THEN pSQLTEXT:=pSQLTEXT||CHR(10)||('--開始修改表類型、列類型、表註釋、列註釋----------------------------------------------'); END IF; pSQLTEXT:=pSQLTEXT||CHR(10)||Y3.SQLTEXT; END LOOP; --表類型不一樣則修改表類型(刪除重建) ELSE --刪除表 pSQLTEXT:=pSQLTEXT||CHR(10)||'EXEC PKG_DBMANAGE.DROP_OBJECT('''||pTARGETUSER||''','''||X.TABLE_NAME||''');'; --重建表,操做步驟與第1步如出一轍 SELECT COUNT(1) INTO pCOUNT2 FROM SYS.DBA_OBJECTS WHERE OWNER=pSOURCEUSER AND OBJECT_NAME=X.TABLE_NAME AND OBJECT_TYPE='MATERIALIZED VIEW'; IF pCOUNT2=0 THEN pINDEX:=pINDEX+1; IF pINDEX=1 THEN pSQLTEXT:=pSQLTEXT||CHR(10)||('--開始修改表類型、列類型、表註釋、列註釋----------------------------------------------'); END IF; --1.1:獲取建表的源碼 PKG_GET_DDL.GET_DDL(pSOURCEUSER,pTARGETUSER,1,X.TABLE_NAME,2,pSOURCECODE); pSQLTEXT:=pSQLTEXT||pSOURCECODE; --1.2:獲取列註釋 FOR Y IN ( SELECT 'COMMENT ON COLUMN '||pREPLACEUSER||'"'||TABLE_NAME||'"."'||COLUMN_NAME||'" IS '''||REPLACE(COMMENTS,'''','''''')||''';' AS COLCOMMENT FROM SYS.DBA_COL_COMMENTS WHERE OWNER=pSOURCEUSER AND TABLE_NAME=X.TABLE_NAME AND COMMENTS IS NOT NULL ) LOOP pSQLTEXT:=pSQLTEXT||CHR(10)||Y.COLCOMMENT; END LOOP; --1.3:獲取表註釋 SELECT COUNT(1) INTO pCOUNT FROM SYS.DBA_TAB_COMMENTS WHERE OWNER=pSOURCEUSER AND TABLE_NAME=X.TABLE_NAME AND COMMENTS IS NOT NULL; IF pCOUNT=1 THEN SELECT 'COMMENT ON TABLE '||pREPLACEUSER||'"'||TABLE_NAME||'" IS '''||REPLACE(COMMENTS,'''','''''')||''';' INTO pTBCOMMENT FROM SYS.DBA_TAB_COMMENTS WHERE OWNER=pSOURCEUSER AND TABLE_NAME=X.TABLE_NAME AND COMMENTS IS NOT NULL; pSQLTEXT:=pSQLTEXT||CHR(10)||pTBCOMMENT||CHR(10); ELSE pSQLTEXT:=pSQLTEXT||CHR(10); END IF; --1.4:獲取索引源碼 FOR Y IN ( SELECT INDEX_NAME FROM SYS.DBA_INDEXES TA WHERE OWNER=pSOURCEUSER AND TABLE_NAME=X.TABLE_NAME AND INDEX_NAME NOT LIKE 'BIN$%' AND INDEX_TYPE NOT IN('LOB') AND NOT EXISTS ( SELECT * FROM SYS.DBA_CONSTRAINTS WHERE OWNER=pSOURCEUSER AND TABLE_NAME=TA.TABLE_NAME AND INDEX_NAME=TA.INDEX_NAME ) ) LOOP PKG_GET_DDL.GET_DDL(pSOURCEUSER,pTARGETUSER,1,Y.INDEX_NAME,3,pSOURCECODE); pSQLTEXT:=pSQLTEXT||pSOURCECODE; END LOOP; END IF; END IF; END LOOP; IF pINDEX>0 THEN pSQLTEXT:=pSQLTEXT||CHR(10)||('--修改表類型、列類型、表註釋、列註釋結束!---------------------------------------------')||CHR(10); pINDEX:=0; END IF; --4:源外鍵不存在而目標外鍵存在則刪除 FOR X IN ( SELECT * FROM SYS.DBA_CONSTRAINTS TA WHERE OWNER=pTARGETUSER AND CONSTRAINT_TYPE='R' AND TABLE_NAME NOT LIKE 'BIN$%' AND TA.CONSTRAINT_NAME NOT LIKE 'BIN$%' AND (INSTR(','||pTABLENAME||',',','||TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL) AND NOT EXISTS ( SELECT * FROM SYS.DBA_CONSTRAINTS WHERE OWNER=pSOURCEUSER AND CONSTRAINT_TYPE='R' AND TABLE_NAME NOT LIKE 'BIN$%' AND CONSTRAINT_NAME NOT LIKE 'BIN$%' AND (INSTR(','||pTABLENAME||',',','||TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL) AND TABLE_NAME=TA.TABLE_NAME ) AND EXISTS ( SELECT * FROM SYS.DBA_TABLES WHERE OWNER=pSOURCEUSER AND TABLE_NAME=TA.TABLE_NAME ) AND EXISTS ( SELECT * FROM SYS.DBA_TABLES WHERE OWNER=pTARGETUSER AND TABLE_NAME=TA.TABLE_NAME ) ) LOOP IF pINDEX=0 THEN pSQLTEXT:=pSQLTEXT||CHR(10)||('--開始刪除沒必要要的外鍵-------------------------------------------------------------'); END IF; pINDEX:=pINDEX+1; --pSQLTEXT:=pSQLTEXT||CHR(10)||'ALTER TABLE "'||pTARGETUSER||'".'||X.TABLE_NAME||' DROP CONSTRAINT "'||X.CONSTRAINT_NAME||'";'; pSQLTEXT:=pSQLTEXT||CHR(10)||'EXEC PKG_DBMANAGE.DROP_CONSTRAINT('''||pTARGETUSER||''','''||X.TABLE_NAME||''','''||X.CONSTRAINT_NAME||''');'; END LOOP; IF pINDEX>0 THEN pSQLTEXT:=pSQLTEXT||CHR(10)||('--刪除沒必要要的外鍵結束!------------------------------------------------------------')||CHR(10); pINDEX:=0; END IF; --5:源主鍵存在而目標主鍵不存在則添加 FOR X IN ( SELECT * FROM SYS.DBA_CONSTRAINTS TA WHERE OWNER=pSOURCEUSER AND CONSTRAINT_TYPE='P' AND TABLE_NAME NOT LIKE 'BIN$%' AND TA.CONSTRAINT_NAME NOT LIKE 'BIN$%' AND (INSTR(','||pTABLENAME||',',','||TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL) AND NOT EXISTS ( SELECT * FROM SYS.DBA_CONSTRAINTS WHERE OWNER=pTARGETUSER AND CONSTRAINT_TYPE='P' AND TABLE_NAME NOT LIKE 'BIN$%' AND TA.CONSTRAINT_NAME NOT LIKE 'BIN$%' AND (INSTR(','||pTABLENAME||',',','||TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL) AND TABLE_NAME=TA.TABLE_NAME ) AND EXISTS ( SELECT * FROM SYS.DBA_TABLES WHERE OWNER=pSOURCEUSER AND TABLE_NAME=TA.TABLE_NAME ) AND EXISTS ( SELECT * FROM SYS.DBA_TABLES WHERE OWNER=pTARGETUSER AND TABLE_NAME=TA.TABLE_NAME ) ) LOOP IF pINDEX=0 THEN pSQLTEXT:=pSQLTEXT||CHR(10)||'--開始添加新的主鍵----------------------------------------------------------------'; END IF; pINDEX:=pINDEX+1; SELECT 'DELETE FROM '||pREPLACEUSER||'"'||TABLE_NAME||'" A WHERE NOT EXISTS('||CHR(10)|| ' SELECT * FROM ('||CHR(10)|| ' SELECT MAX(ROWID) OVER(PARTITION BY '||COLLIST||') AS MAXROWID FROM '||pREPLACEUSER||'"'||TABLE_NAME||'"'||CHR(10)|| ' ) WHERE MAXROWID=A.ROWID'||CHR(10)|| ');'||CHR(10)|| 'ALTER TABLE '||pREPLACEUSER||'"'||TABLE_NAME||'" ADD CONSTRAINT "'||CONSTRAINT_NAME||'" PRIMARY KEY('||COLLIST||') ENABLE;' INTO pPRIMARY FROM ( SELECT DISTINCT TABLE_NAME,CONSTRAINT_NAME,LISTAGG('"'||COLUMN_NAME||'"',',') WITHIN GROUP(ORDER BY POSITION) OVER(PARTITION BY TABLE_NAME) AS COLLIST FROM SYS.DBA_CONS_COLUMNS WHERE OWNER=pSOURCEUSER AND CONSTRAINT_NAME=X.CONSTRAINT_NAME ); pSQLTEXT:=pSQLTEXT||CHR(10)||pPRIMARY; END LOOP; IF pINDEX>0 THEN pSQLTEXT:=pSQLTEXT||CHR(10)||('--添加新的主鍵結束!---------------------------------------------------------------')||CHR(10); pINDEX:=0; END IF; --6:源外鍵存在而目標外鍵不存在則添加 FOR X IN ( SELECT * FROM SYS.DBA_CONSTRAINTS TA WHERE OWNER=pSOURCEUSER AND CONSTRAINT_TYPE='R' AND TABLE_NAME NOT LIKE 'BIN$%' AND TA.CONSTRAINT_NAME NOT LIKE 'BIN$%' AND (INSTR(','||pTABLENAME||',',','||TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL) AND NOT EXISTS ( SELECT * FROM SYS.DBA_CONSTRAINTS WHERE OWNER=pTARGETUSER AND CONSTRAINT_TYPE='R' AND TABLE_NAME NOT LIKE 'BIN$%' AND CONSTRAINT_NAME NOT LIKE 'BIN$%' AND (INSTR(','||pTABLENAME||',',','||TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL) AND TABLE_NAME=TA.TABLE_NAME ) AND EXISTS ( SELECT * FROM SYS.DBA_TABLES WHERE OWNER=pSOURCEUSER AND TABLE_NAME=TA.TABLE_NAME ) AND EXISTS ( SELECT * FROM SYS.DBA_TABLES WHERE OWNER=pTARGETUSER AND TABLE_NAME=TA.TABLE_NAME ) ) LOOP IF pINDEX=0 THEN pSQLTEXT:=pSQLTEXT||CHR(10)||('--開始添加新的外鍵----------------------'); END IF; pINDEX:=pINDEX+1; SELECT '"'||TABLE_NAME||'" ('||COLLIST||') ' INTO pPRIMARY FROM ( SELECT DISTINCT TABLE_NAME,CONSTRAINT_NAME,LISTAGG('"'||COLUMN_NAME||'"',',') WITHIN GROUP(ORDER BY POSITION) OVER(PARTITION BY TABLE_NAME) AS COLLIST FROM SYS.DBA_CONS_COLUMNS WHERE CONSTRAINT_NAME=X.R_CONSTRAINT_NAME AND OWNER=pSOURCEUSER ); SELECT 'ALTER TABLE '||pREPLACEUSER||'"'||TABLE_NAME||'" ADD CONSTRAINT "'||CONSTRAINT_NAME||'" FOREIGN KEY('||COLLIST||') REFERENCES '||pPRIMARY||DECODE(X.DELETE_RULE,'CASCADE','ON DELETE CASCADE ',' ')||'ENABLE;' INTO pFOREIGN FROM ( SELECT DISTINCT TABLE_NAME,CONSTRAINT_NAME,LISTAGG('"'||COLUMN_NAME||'"',',') WITHIN GROUP(ORDER BY POSITION) OVER(PARTITION BY TABLE_NAME) AS COLLIST FROM SYS.DBA_CONS_COLUMNS WHERE CONSTRAINT_NAME=X.CONSTRAINT_NAME AND OWNER=pSOURCEUSER ); pSQLTEXT:=pSQLTEXT||CHR(10)||pFOREIGN; END LOOP; IF pINDEX>0 THEN pSQLTEXT:=pSQLTEXT||CHR(10)||('--添加新的外鍵結束!----------------------')||CHR(10); pINDEX:=0; END IF; --7:源主鍵不存在而目標主鍵存在則刪除 FOR X IN ( SELECT * FROM SYS.DBA_CONSTRAINTS TA WHERE OWNER=pTARGETUSER AND CONSTRAINT_TYPE='P' AND TABLE_NAME NOT LIKE 'BIN$%' AND TA.CONSTRAINT_NAME NOT LIKE 'BIN$%' AND (INSTR(','||pTABLENAME||',',','||TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL) AND NOT EXISTS ( SELECT * FROM SYS.DBA_CONSTRAINTS WHERE OWNER=pSOURCEUSER AND CONSTRAINT_TYPE='P' AND TABLE_NAME NOT LIKE 'BIN$%' AND CONSTRAINT_NAME NOT LIKE 'BIN$%' AND (INSTR(','||pTABLENAME||',',','||TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL) AND TABLE_NAME=TA.TABLE_NAME ) AND EXISTS ( SELECT * FROM SYS.DBA_TABLES WHERE OWNER=pSOURCEUSER AND TABLE_NAME=TA.TABLE_NAME ) AND EXISTS ( SELECT * FROM SYS.DBA_TABLES WHERE OWNER=pTARGETUSER AND TABLE_NAME=TA.TABLE_NAME ) ) LOOP IF pINDEX=0 THEN pSQLTEXT:=pSQLTEXT||CHR(10)||('--開始刪除沒必要要的主鍵----------------------'); END IF; pINDEX:=pINDEX+1; --pSQLTEXT:=pSQLTEXT||CHR(10)||'ALTER TABLE "'||pTARGETUSER||'".'||X.TABLE_NAME||' DROP CONSTRAINT '||X.CONSTRAINT_NAME||';'; pSQLTEXT:=pSQLTEXT||CHR(10)||'EXEC PKG_DBMANAGE.DROP_CONSTRAINT('''||pTARGETUSER||''','''||X.TABLE_NAME||''','''||X.CONSTRAINT_NAME||''');'; END LOOP; IF pINDEX>0 THEN pSQLTEXT:=pSQLTEXT||CHR(10)||('--刪除沒必要要的主鍵結束!----------------------')||CHR(10); pINDEX:=0; END IF; --8:主鍵列、外鍵列修改的邏輯:先刪除全部有變更的外鍵,再刪除全部有變更的主鍵,再從新添加主鍵,最後從新添加新的外鍵;若是隻是主外鍵名稱不相同,則從新改名便可 --8.1:刪除全部有變更的外鍵 --注意:此處若是外鍵名稱不相同,只須要從新改名 FOR X IN ( SELECT * FROM ( SELECT TABLE_NAME,OLD_CONSTRAINT_NAME,NEW_CONSTRAINT_NAME,R_TABLE_NAME,FORIGNCOL,PRIMARYKEY,OPERATETYPE,DELETE_RULE,DENSE_RANK() OVER(PARTITION BY TABLE_NAME,OLD_CONSTRAINT_NAME ORDER BY OPERATETYPE DESC) AS DC FROM ( SELECT T2.TABLE_NAME,T4.CONSTRAINT_NAME AS OLD_CONSTRAINT_NAME,T2.CONSTRAINT_NAME AS NEW_CONSTRAINT_NAME,T2.R_TABLE_NAME,T2.COLLIST AS FORIGNCOL,T4.COLLIST AS PRIMARYKEY, DECODE(T2.R_TABLE_NAME||'('||T2.COLLIST||')'||NVL(T2.DELETE_RULE,' '),T4.R_TABLE_NAME||'('||T4.COLLIST||')'||NVL(T4.DELETE_RULE,' '),DECODE(T2.CONSTRAINT_NAME,T4.CONSTRAINT_NAME,'','RENAME'),'DROP') AS OPERATETYPE,T2.DELETE_RULE FROM ( SELECT DISTINCT TABLE_NAME,CONSTRAINT_NAME,DELETE_RULE,LISTAGG('"'||COLUMN_NAME||'"',',') WITHIN GROUP(ORDER BY POSITION) OVER(PARTITION BY TABLE_NAME,CONSTRAINT_NAME) AS COLLIST, R_TABLE_NAME,LISTAGG('"'||R_COULMN_NAME||'"',',') WITHIN GROUP(ORDER BY POSITION) OVER(PARTITION BY TABLE_NAME,CONSTRAINT_NAME) AS R_COLLIST FROM ( SELECT TA.TABLE_NAME,TA.CONSTRAINT_NAME,TA.DELETE_RULE,TB.COLUMN_NAME,TA.R_CONSTRAINT_NAME,TC.TABLE_NAME AS R_TABLE_NAME,TD.COLUMN_NAME AS R_COULMN_NAME,TB.POSITION FROM SYS.DBA_CONSTRAINTS TA JOIN SYS.DBA_CONS_COLUMNS TB ON (TA.OWNER=TB.OWNER AND TA.CONSTRAINT_NAME=TB.CONSTRAINT_NAME AND TA.TABLE_NAME=TB.TABLE_NAME ) JOIN SYS.DBA_CONSTRAINTS TC ON (TA.R_OWNER=TC.OWNER AND TA.R_CONSTRAINT_NAME=TC.CONSTRAINT_NAME) JOIN SYS.DBA_CONS_COLUMNS TD ON (TC.OWNER=TD.OWNER AND TC.CONSTRAINT_NAME=TD.CONSTRAINT_NAME AND TD.TABLE_NAME=TC.TABLE_NAME AND TB.POSITION=TD.POSITION) WHERE TA.OWNER=pSOURCEUSER AND TA.CONSTRAINT_TYPE='R' AND TA.R_OWNER=pSOURCEUSER AND TC.CONSTRAINT_TYPE='P' AND TA.TABLE_NAME NOT LIKE 'BIN$%' AND TA.CONSTRAINT_NAME NOT LIKE 'BIN$%' AND TC.TABLE_NAME NOT LIKE 'BIN$%' AND TC.CONSTRAINT_NAME NOT LIKE 'BIN$%' ) T1 ) T2 JOIN ( SELECT DISTINCT TABLE_NAME,CONSTRAINT_NAME,DELETE_RULE,LISTAGG('"'||COLUMN_NAME||'"',',') WITHIN GROUP(ORDER BY POSITION) OVER(PARTITION BY TABLE_NAME,CONSTRAINT_NAME) AS COLLIST, R_TABLE_NAME,LISTAGG('"'||R_COULMN_NAME||'"',',') WITHIN GROUP(ORDER BY POSITION) OVER(PARTITION BY TABLE_NAME,CONSTRAINT_NAME) AS R_COLLIST FROM ( SELECT TA.TABLE_NAME,TA.CONSTRAINT_NAME,TA.DELETE_RULE,TB.COLUMN_NAME,TA.R_CONSTRAINT_NAME,TC.TABLE_NAME AS R_TABLE_NAME,TD.COLUMN_NAME AS R_COULMN_NAME,TB.POSITION FROM SYS.DBA_CONSTRAINTS TA JOIN SYS.DBA_CONS_COLUMNS TB ON (TA.OWNER=TB.OWNER AND TA.CONSTRAINT_NAME=TB.CONSTRAINT_NAME AND TA.TABLE_NAME=TB.TABLE_NAME ) JOIN SYS.DBA_CONSTRAINTS TC ON (TA.R_OWNER=TC.OWNER AND TA.R_CONSTRAINT_NAME=TC.CONSTRAINT_NAME) JOIN SYS.DBA_CONS_COLUMNS TD ON (TC.OWNER=TD.OWNER AND TC.CONSTRAINT_NAME=TD.CONSTRAINT_NAME AND TD.TABLE_NAME=TC.TABLE_NAME AND TB.POSITION=TD.POSITION) WHERE TA.OWNER=pTARGETUSER AND TA.CONSTRAINT_TYPE='R' AND TA.R_OWNER=pTARGETUSER AND TC.CONSTRAINT_TYPE='P' AND TA.TABLE_NAME NOT LIKE 'BIN$%' AND TA.CONSTRAINT_NAME NOT LIKE 'BIN$%' AND TC.TABLE_NAME NOT LIKE 'BIN$%' AND TC.CONSTRAINT_NAME NOT LIKE 'BIN$%' ) T3 ) T4 ON T2.TABLE_NAME=T4.TABLE_NAME ) ) WHERE OPERATETYPE IS NOT NULL AND DC=1 ) LOOP IF pINDEX=0 THEN pSQLTEXT:=pSQLTEXT||CHR(10)||('--開始更新全部有變更的外鍵----------------------------------------------------------'); END IF; pINDEX:=pINDEX+1; IF X.OPERATETYPE='DROP' THEN pSQLTEXT:=pSQLTEXT||CHR(10)||'ALTER TABLE '||pREPLACEUSER||'"'||X.TABLE_NAME||'" DROP CONSTRAINT "'||X.OLD_CONSTRAINT_NAME||'";'; SELECT pREBULIDFORRIGN||CHR(10)||'ALTER TABLE '||pREPLACEUSER||'"'||X.TABLE_NAME||'" ADD CONSTRAINT "'||X.NEW_CONSTRAINT_NAME||'" FOREIGN KEY('||X.FORIGNCOL||') REFERENCES "'|| X.R_TABLE_NAME||'" ('||X.PRIMARYKEY||') '||DECODE(X.DELETE_RULE,'CASCADE','ON DELETE CASCADE ',' ')||'ENABLE;' INTO pREBULIDFORRIGN FROM DUAL; ELSE pSQLTEXT:=pSQLTEXT||CHR(10)||'ALTER TABLE '||pREPLACEUSER||'"'||X.TABLE_NAME||'" RENAME CONSTRAINT '||X.OLD_CONSTRAINT_NAME||' TO '||X.NEW_CONSTRAINT_NAME||';'; END IF; END LOOP; IF pINDEX>0 THEN pSQLTEXT:=pSQLTEXT||CHR(10)||('--更新全部有變更的外鍵結束!---------------------------------------------------------')||CHR(10); pINDEX:=0; END IF; --8.2:刪除全部有變更的主鍵,同時添加新的主鍵 --注意:此處若是主鍵名稱不相同,只須要從新改名 FOR X IN ( SELECT * FROM ( SELECT TA.TABLE_NAME,TB.CONSTRAINT_NAME AS OLD_CONSTRAINT_NAME,TA.CONSTRAINT_NAME AS NEW_CONSTRAINT_NAME,TA.COLLIST, DECODE(TA.COLLIST,TB.COLLIST,DECODE(TA.CONSTRAINT_NAME,TB.CONSTRAINT_NAME,'','RENAME'),'DROP') AS OPERATETYPE FROM ( SELECT DISTINCT TABLE_NAME,CONSTRAINT_NAME,LISTAGG('"'||COLUMN_NAME||'"',',') WITHIN GROUP(ORDER BY POSITION) OVER(PARTITION BY TABLE_NAME) AS COLLIST FROM ( SELECT TB.TABLE_NAME,TB.CONSTRAINT_NAME,TB.COLUMN_NAME,POSITION FROM SYS.DBA_CONSTRAINTS TA JOIN SYS.DBA_CONS_COLUMNS TB ON (TA.OWNER=TB.OWNER AND TA.CONSTRAINT_NAME=TB.CONSTRAINT_NAME) WHERE TA.OWNER=pSOURCEUSER AND TA.CONSTRAINT_TYPE='P' AND TA.TABLE_NAME NOT LIKE 'BIN$%' AND TA.CONSTRAINT_NAME NOT LIKE 'BIN$%' AND (INSTR(','||pTABLENAME||',',','||TA.TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL) ) ) TA JOIN ( SELECT DISTINCT TABLE_NAME,CONSTRAINT_NAME,LISTAGG('"'||COLUMN_NAME||'"',',') WITHIN GROUP(ORDER BY POSITION) OVER(PARTITION BY TABLE_NAME) AS COLLIST FROM ( SELECT TB.TABLE_NAME,TB.CONSTRAINT_NAME,TB.COLUMN_NAME,POSITION FROM SYS.DBA_CONSTRAINTS TA JOIN SYS.DBA_CONS_COLUMNS TB ON (TA.OWNER=TB.OWNER AND TA.CONSTRAINT_NAME=TB.CONSTRAINT_NAME) WHERE TA.OWNER=pTARGETUSER AND TA.CONSTRAINT_TYPE='P' AND TA.TABLE_NAME NOT LIKE 'BIN$%' AND TA.CONSTRAINT_NAME NOT LIKE 'BIN$%' AND (INSTR(','||pTABLENAME||',',','||TA.TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL) ) ) TB ON TA.TABLE_NAME=TB.TABLE_NAME ) WHERE OPERATETYPE IS NOT NULL ) LOOP IF pINDEX=0 THEN pSQLTEXT:=pSQLTEXT||CHR(10)||('--開始更新有變更的主鍵-------------------------------------------------------------'); END IF; pINDEX:=pINDEX+1; --注意:此處需判斷主鍵以及主鍵索引是否存在,如主鍵不存在但主鍵索引存在,需刪除主鍵索引 --因爲存儲過程當中沒法獲取其餘用戶的源碼,暫定刪除主鍵索引,重建主鍵 IF X.OPERATETYPE='DROP' THEN --保存修改主鍵的語句 SELECT COUNT(1) INTO pCOUNT FROM SYS.DBA_CONSTRAINTS WHERE OWNER=pTARGETUSER AND CONSTRAINT_NAME=X.OLD_CONSTRAINT_NAME; SELECT COUNT(1) INTO pCOUNT1 FROM SYS.DBA_INDEXES WHERE OWNER=pTARGETUSER AND INDEX_NAME=X.OLD_CONSTRAINT_NAME; IF pCOUNT=1 THEN --主鍵存在須要刪除主鍵和主鍵索引級鏈刪除 pSQLTEXT:=pSQLTEXT||CHR(10)||'ALTER TABLE '||pREPLACEUSER||'"'||X.TABLE_NAME||'" DROP CONSTRAINT '||X.OLD_CONSTRAINT_NAME||' cascade drop index;'; ELSIF pCOUNT1=1 THEN --主鍵不存在但主鍵索引存在,需刪除主鍵索引 pSQLTEXT:=pSQLTEXT||CHR(10)||'DROP INDEX '||pREPLACEUSER||X.OLD_CONSTRAINT_NAME||';'; END IF; pSQLTEXT:=pSQLTEXT||CHR(10)||'ALTER TABLE '||pREPLACEUSER||'"'||X.TABLE_NAME||'" ADD CONSTRAINT "'||X.NEW_CONSTRAINT_NAME||'" PRIMARY KEY('||X.COLLIST||') ENABLE;'; ELSE pSQLTEXT:=pSQLTEXT||CHR(10)||'ALTER TABLE '||pREPLACEUSER||'"'||X.TABLE_NAME||'" RENAME CONSTRAINT '||X.OLD_CONSTRAINT_NAME||' TO '||X.NEW_CONSTRAINT_NAME||';'; END IF; END LOOP; IF pINDEX>0 THEN pSQLTEXT:=pSQLTEXT||CHR(10)||('--更新有變更的主鍵結束!------------------------------------------------------------')||CHR(10); pINDEX:=0; END IF; --8.3:從新添加新的外鍵 IF pREBULIDFORRIGN IS NOT NULL THEN pSQLTEXT:=pSQLTEXT||CHR(10)||('--開始從新添加新的外鍵-------------------------------------------------------------'); pSQLTEXT:=pSQLTEXT||pREBULIDFORRIGN; pSQLTEXT:=pSQLTEXT||CHR(10)||('--從新添加新的外鍵結束!------------------------------------------------------------'); END IF; --9:源約束(檢查、惟一)不存在而目標約束存在則刪除 --注意:因爲在DBA_CONSTRAINTS中檢查約束、非空約束類型均爲'C',很難加以區分,暫時能夠查詢出GENERATED='USER NAME'爲檢查約束,GENERATED='GENERATED NAME'爲非空約束 --注意:若是約束存在可是約束的列不相同也須要刪除重建 FOR X IN ( SELECT DISTINCT * FROM ( SELECT TA.CONSTRAINT_NAME,TA.TABLE_NAME,LISTAGG(T1.COLUMN_NAME,',') WITHIN GROUP(ORDER BY T1.COLUMN_NAME) OVER(PARTITION BY TA.CONSTRAINT_NAME,TA.TABLE_NAME) AS COL_LIST,TA.CONSTRAINT_TYPE FROM SYS.DBA_CONSTRAINTS TA JOIN SYS.DBA_CONS_COLUMNS T1 ON (TA.OWNER=T1.OWNER AND TA.CONSTRAINT_NAME=T1.CONSTRAINT_NAME) WHERE TA.OWNER=pTARGETUSER AND ((TA.GENERATED='USER NAME' AND TA.CONSTRAINT_TYPE='C') OR TA.CONSTRAINT_TYPE='U') AND TA.TABLE_NAME NOT LIKE 'BIN$%' AND TA.CONSTRAINT_NAME NOT LIKE 'BIN$%' AND (INSTR(','||pTABLENAME||',',','||TA.TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL) ) C1 WHERE NOT EXISTS ( SELECT * FROM ( SELECT TB.CONSTRAINT_NAME,TB.TABLE_NAME,LISTAGG(T2.COLUMN_NAME,',') WITHIN GROUP(ORDER BY T2.COLUMN_NAME) OVER(PARTITION BY TB.CONSTRAINT_NAME,TB.TABLE_NAME) AS COL_LIST,TB.CONSTRAINT_TYPE FROM SYS.DBA_CONSTRAINTS TB JOIN SYS.DBA_CONS_COLUMNS T2 ON (TB.OWNER=T2.OWNER AND TB.CONSTRAINT_NAME=T2.CONSTRAINT_NAME) WHERE TB.OWNER=pSOURCEUSER AND ((TB.GENERATED='USER NAME' AND TB.CONSTRAINT_TYPE='C') OR TB.CONSTRAINT_TYPE='U') AND TB.TABLE_NAME NOT LIKE 'BIN$%' AND TB.CONSTRAINT_NAME NOT LIKE 'BIN$%' AND (INSTR(','||pTABLENAME||',',','||TB.TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL) ) C2 WHERE C2.CONSTRAINT_NAME=C1.CONSTRAINT_NAME AND C2.CONSTRAINT_TYPE=C1.CONSTRAINT_TYPE AND C2.TABLE_NAME=C1.TABLE_NAME AND C2.COL_LIST=C1.COL_LIST ) AND EXISTS ( SELECT * FROM SYS.DBA_TABLES WHERE OWNER=pSOURCEUSER AND TABLE_NAME=C1.TABLE_NAME ) AND EXISTS ( SELECT * FROM SYS.DBA_TABLES WHERE OWNER=pTARGETUSER AND TABLE_NAME=C1.TABLE_NAME ) ) LOOP IF pINDEX=0 THEN pSQLTEXT:=pSQLTEXT||CHR(10)||('--開始刪除沒必要要的約束-------------------------------------------------------------'); END IF; pINDEX:=pINDEX+1; --pSQLTEXT:=pSQLTEXT||CHR(10)||'ALTER TABLE "'||pTARGETUSER||'".'||X.TABLE_NAME||' DROP CONSTRAINT "'||X.CONSTRAINT_NAME||'";'; pSQLTEXT:=pSQLTEXT||CHR(10)||'EXEC PKG_DBMANAGE.DROP_CONSTRAINT('''||pTARGETUSER||''','''||X.TABLE_NAME||''','''||X.CONSTRAINT_NAME||''');'; END LOOP; IF pINDEX>0 THEN pSQLTEXT:=pSQLTEXT||CHR(10)||('--刪除沒必要要的約束結束!------------------------------------------------------------')||CHR(10); pINDEX:=0; END IF; --10:源約束(檢查、惟一)存在而目標約束不存在則添加 --注意:因爲在DBA_CONSTRAINTS中檢查約束、非空約束類型均爲'C',很難加以區分,暫時能夠查詢出GENERATED='USER NAME'爲檢查約束,GENERATED='GENERATED NAME'爲非空約束 --注意:若是約束存在可是約束的列不相同也須要刪除重建 FOR X IN ( SELECT DISTINCT * FROM ( SELECT TA.CONSTRAINT_NAME,TA.TABLE_NAME,LISTAGG(T1.COLUMN_NAME,',') WITHIN GROUP(ORDER BY T1.COLUMN_NAME) OVER(PARTITION BY TA.CONSTRAINT_NAME,TA.TABLE_NAME) AS COL_LIST,TA.CONSTRAINT_TYPE FROM SYS.DBA_CONSTRAINTS TA JOIN SYS.DBA_CONS_COLUMNS T1 ON (TA.OWNER=T1.OWNER AND TA.CONSTRAINT_NAME=T1.CONSTRAINT_NAME) WHERE TA.OWNER=pSOURCEUSER AND ((TA.GENERATED='USER NAME' AND TA.CONSTRAINT_TYPE='C') OR TA.CONSTRAINT_TYPE='U') AND TA.TABLE_NAME NOT LIKE 'BIN$%' AND TA.CONSTRAINT_NAME NOT LIKE 'BIN$%' AND (INSTR(','||pTABLENAME||',',','||TA.TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL) ) C1 WHERE NOT EXISTS ( SELECT * FROM ( SELECT TB.CONSTRAINT_NAME,TB.TABLE_NAME,LISTAGG(T2.COLUMN_NAME,',') WITHIN GROUP(ORDER BY T2.COLUMN_NAME) OVER(PARTITION BY TB.CONSTRAINT_NAME,TB.TABLE_NAME) AS COL_LIST,TB.CONSTRAINT_TYPE FROM SYS.DBA_CONSTRAINTS TB JOIN SYS.DBA_CONS_COLUMNS T2 ON (TB.OWNER=T2.OWNER AND TB.CONSTRAINT_NAME=T2.CONSTRAINT_NAME) WHERE TB.OWNER=pTARGETUSER AND ((TB.GENERATED='USER NAME' AND TB.CONSTRAINT_TYPE='C') OR TB.CONSTRAINT_TYPE='U') AND TB.TABLE_NAME NOT LIKE 'BIN$%' AND TB.CONSTRAINT_NAME NOT LIKE 'BIN$%' AND (INSTR(','||pTABLENAME||',',','||TB.TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL) ) C2 WHERE C2.CONSTRAINT_NAME=C1.CONSTRAINT_NAME AND C2.CONSTRAINT_TYPE=C1.CONSTRAINT_TYPE AND C2.TABLE_NAME=C1.TABLE_NAME AND C2.COL_LIST=C1.COL_LIST ) AND EXISTS ( SELECT * FROM SYS.DBA_TABLES WHERE OWNER=pSOURCEUSER AND TABLE_NAME=C1.TABLE_NAME ) AND EXISTS ( SELECT * FROM SYS.DBA_TABLES WHERE OWNER=pTARGETUSER AND TABLE_NAME=C1.TABLE_NAME ) ) LOOP IF pINDEX=0 THEN pSQLTEXT:=pSQLTEXT||CHR(10)||('--開始添加新的約束----------------------------------------------------------------'); END IF; pINDEX:=pINDEX+1; IF X.CONSTRAINT_TYPE='U' THEN --惟一約束 pRULECODE:='ALTER TABLE '||pREPLACEUSER||'"'||X.TABLE_NAME||'" ADD CONSTRAINT "'||X.CONSTRAINT_NAME||'" UNIQUE('||X.COL_LIST||') ENABLE;'; ELSE --檢查約束 FOR R IN --此處循環寫法是爲了解決long類型字段在查詢語句中沒法進行拼接的問題 ( SELECT SEARCH_CONDITION FROM SYS.DBA_CONSTRAINTS WHERE OWNER=pSOURCEUSER AND TABLE_NAME=X.TABLE_NAME AND CONSTRAINT_NAME=X.CONSTRAINT_NAME ) LOOP pRULECODE:='ALTER TABLE '||pREPLACEUSER||'"'||X.TABLE_NAME||'" ADD CONSTRAINT "'||X.CONSTRAINT_NAME||'" CHECK ('||R.SEARCH_CONDITION||') ENABLE;'; END LOOP; END IF; pSQLTEXT:=pSQLTEXT||CHR(10)||pRULECODE; END LOOP; IF pINDEX>0 THEN pSQLTEXT:=pSQLTEXT||CHR(10)||('--添加新的約束結束!---------------------------------------------------------------')||CHR(10); pINDEX:=0; END IF; --11:源索引不存在而目標索引存在則刪除 FOR X IN ( SELECT DISTINCT TA.INDEX_NAME FROM SYS.DBA_INDEXES TA JOIN SYS.DBA_IND_COLUMNS TB ON TA.OWNER=TB.INDEX_OWNER AND TA.TABLE_NAME=TB.TABLE_NAME AND TA.INDEX_NAME=TB.INDEX_NAME WHERE TA.OWNER=pTARGETUSER AND TA.TABLE_NAME NOT LIKE 'BIN$%' AND TA.INDEX_NAME NOT LIKE 'BIN$%' AND INDEX_TYPE NOT IN('LOB') AND (INSTR(','||pTABLENAME||',',','||TA.TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL) AND NOT EXISTS ( SELECT * FROM SYS.DBA_INDEXES T1 JOIN SYS.DBA_IND_COLUMNS T2 ON T1.OWNER=T2.INDEX_OWNER AND T1.TABLE_NAME=T2.TABLE_NAME AND T1.INDEX_NAME=T2.INDEX_NAME WHERE OWNER=pSOURCEUSER AND T1.TABLE_NAME NOT LIKE 'BIN$%' AND T1.INDEX_NAME NOT LIKE 'BIN$%' AND T1.TABLE_NAME=TA.TABLE_NAME AND T1.INDEX_NAME=TA.INDEX_NAME ) AND NOT EXISTS ( SELECT * FROM SYS.DBA_CONSTRAINTS WHERE OWNER=pTARGETUSER AND TABLE_NAME=TA.TABLE_NAME AND INDEX_NAME=TA.INDEX_NAME ) AND EXISTS ( SELECT * FROM SYS.DBA_TABLES WHERE OWNER=pSOURCEUSER AND TABLE_NAME=TA.TABLE_NAME ) AND EXISTS ( SELECT * FROM SYS.DBA_TABLES WHERE OWNER=pTARGETUSER AND TABLE_NAME=TA.TABLE_NAME ) ) LOOP IF pINDEX=0 THEN pSQLTEXT:=pSQLTEXT||CHR(10)||('--開始刪除沒必要要的索引-------------------------------------------------------------'); END IF; pINDEX:=pINDEX+1; pSQLTEXT:=pSQLTEXT||CHR(10)||'EXEC PKG_DBMANAGE.DROP_INDEX('''||pTARGETUSER||''','''||X.INDEX_NAME||''');'; END LOOP; IF pINDEX>0 THEN pSQLTEXT:=pSQLTEXT||CHR(10)||('--刪除沒必要要的索引結束!------------------------------------------------------------')||CHR(10); pINDEX:=0; END IF; --12:源索引存在而目標索引不存在則添加 FOR X IN ( SELECT DISTINCT TA.INDEX_NAME FROM SYS.DBA_INDEXES TA JOIN SYS.DBA_IND_COLUMNS TB ON TA.OWNER=TB.INDEX_OWNER AND TA.TABLE_NAME=TB.TABLE_NAME AND TA.INDEX_NAME=TB.INDEX_NAME WHERE TA.OWNER=pSOURCEUSER AND TA.TABLE_NAME NOT LIKE 'BIN$%' AND TA.INDEX_NAME NOT LIKE 'BIN$%' AND TA.INDEX_TYPE NOT IN('LOB') AND TA.INDEX_TYPE NOT IN('LOB') AND (INSTR(','||pTABLENAME||',',','||TA.TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL) AND NOT EXISTS ( SELECT * FROM SYS.DBA_INDEXES T1 JOIN SYS.DBA_IND_COLUMNS T2 ON T1.OWNER=T2.INDEX_OWNER AND T1.TABLE_NAME=T2.TABLE_NAME AND T1.INDEX_NAME=T2.INDEX_NAME WHERE OWNER=pTARGETUSER AND T1.TABLE_NAME NOT LIKE 'BIN$%' AND T1.INDEX_NAME NOT LIKE 'BIN$%' AND T1.TABLE_NAME=TA.TABLE_NAME AND T1.INDEX_NAME=TA.INDEX_NAME ) AND NOT EXISTS ( SELECT * FROM SYS.DBA_CONSTRAINTS WHERE OWNER=pSOURCEUSER AND TABLE_NAME=TA.TABLE_NAME AND INDEX_NAME=TA.INDEX_NAME ) AND EXISTS ( SELECT * FROM SYS.DBA_TABLES WHERE OWNER=pSOURCEUSER AND TABLE_NAME=TA.TABLE_NAME ) AND EXISTS ( SELECT * FROM SYS.DBA_TABLES WHERE OWNER=pTARGETUSER AND TABLE_NAME=TA.TABLE_NAME ) ) LOOP IF pINDEX=0 THEN pSQLTEXT:=pSQLTEXT||CHR(10)||('--開始添加新的索引-----------------------------------------------------------------'); END IF; pINDEX:=pINDEX+1; PKG_GET_DDL.GET_DDL(pSOURCEUSER,pTARGETUSER,1,X.INDEX_NAME,3,pSOURCECODE); pSQLTEXT:=pSQLTEXT||pSOURCECODE; END LOOP; IF pINDEX>0 THEN pSQLTEXT:=pSQLTEXT||CHR(10)||('--添加新的索引結束!---------------------------------------------------------------')||CHR(10); pINDEX:=0; END IF; --13:索引修改的邏輯:先刪除全部有變更的索引,再從新添加新的索引 --遍歷索引的每一列,判斷列名、順序、排序等是否一致,若是不一致,則刪除重建, --注意:函數索引的列名通常爲「SYS_」,須要從DBA_IND_EXPRESSIONS對應查找到原始列名 DELETE FROM TEMP_COLUMN_EXPRESSION; INSERT INTO TEMP_COLUMN_EXPRESSION(INDEX_OWNER,INDEX_NAME,INDEX_TYPE,UNIQUENESS,COMPRESSION,TABLE_NAME,TABLE_TYPE,COLUMN_NAME,COLUMN_EXPRESSION,COLUMN_POSITION,DESCEND) SELECT TB.INDEX_OWNER,TB.INDEX_NAME,TA.INDEX_TYPE,TA.UNIQUENESS,TA.COMPRESSION,Ta.TABLE_NAME,TA.TABLE_TYPE,TB.COLUMN_NAME,TO_LOB(TC.COLUMN_EXPRESSION) AS COLUMN_EXPRESSION,TB.COLUMN_POSITION,TB.DESCEND FROM SYS.DBA_INDEXES TA JOIN SYS.DBA_IND_COLUMNS TB ON (TA.INDEX_NAME=TB.INDEX_NAME AND TA.TABLE_NAME=TB.TABLE_NAME AND TA.OWNER=TB.INDEX_OWNER) LEFT JOIN SYS.DBA_IND_EXPRESSIONS TC ON ( TB.INDEX_OWNER=TC.INDEX_OWNER AND TB.TABLE_OWNER=TC.INDEX_OWNER AND TB.INDEX_NAME=TC.INDEX_NAME AND TB.TABLE_NAME=TC.TABLE_NAME AND TB.COLUMN_POSITION=TC.COLUMN_POSITION ) WHERE ((TA.OWNER=pTARGETUSER AND TB.INDEX_OWNER=pTARGETUSER AND TB.TABLE_OWNER=pTARGETUSER) OR (TA.OWNER=pSOURCEUSER AND TB.INDEX_OWNER=pSOURCEUSER AND TB.TABLE_OWNER=pSOURCEUSER)) AND TA.TABLE_NAME NOT LIKE 'BIN$%' AND TA.INDEX_NAME NOT LIKE 'BIN$%' AND (INSTR(','||pTABLENAME||',',','||TA.TABLE_NAME||',',1)>0 OR pTABLENAME IS NULL) AND NOT EXISTS ( SELECT * FROM SYS.DBA_CONSTRAINTS WHERE OWNER=TA.OWNER AND CONSTRAINT_NAME=TA.INDEX_NAME AND TABLE_NAME=TA.TABLE_NAME ); FOR X IN ( SELECT DISTINCT T1.INDEX_NAME FROM ( SELECT DISTINCT INDEX_NAME,TABLE_NAME,UNIQUENESS,LISTAGG(COLUMN_NAME||' '||DESCEND,',') WITHIN GROUP(ORDER BY COLUMN_POSITION) OVER(PARTITION BY INDEX_NAME,TABLE_NAME) AS COL_SORT FROM ( SELECT INDEX_NAME,UNIQUENESS,TABLE_NAME,TO_CHAR(NVL(COLUMN_EXPRESSION,COLUMN_NAME)) AS COLUMN_NAME,DESCEND,COLUMN_POSITION FROM TEMP_COLUMN_EXPRESSION T1 WHERE INDEX_OWNER=pSOURCEUSER ) ) T1 JOIN ( SELECT DISTINCT INDEX_NAME,TABLE_NAME,UNIQUENESS,LISTAGG(COLUMN_NAME||' '||DESCEND,',') WITHIN GROUP(ORDER BY COLUMN_POSITION) OVER(PARTITION BY INDEX_NAME,TABLE_NAME) AS COL_SORT FROM ( SELECT INDEX_NAME,UNIQUENESS,TABLE_NAME,TO_CHAR(NVL(COLUMN_EXPRESSION,COLUMN_NAME)) AS COLUMN_NAME,DESCEND,COLUMN_POSITION FROM TEMP_COLUMN_EXPRESSION T1 WHERE INDEX_OWNER=pTARGETUSER ) ) T2 ON T1.TABLE_NAME=T2.TABLE_NAME AND T1.INDEX_NAME=T2.INDEX_NAME WHERE T1.COL_SORT<>T2.COL_SORT ) LOOP --獲取索引源碼 PKG_GET_DDL.GET_DDL(pSOURCEUSER,pTARGETUSER,1,X.INDEX_NAME,3,pSOURCECODE); IF pINDEX=0 THEN pSQLTEXT:=pSQLTEXT||CHR(10)||('--開始更新有變更的索引-------------------------------------------------------------'); END IF; pINDEX:=pINDEX+1; --刪除舊的索引 pSQLTEXT:=pSQLTEXT||CHR(10)||'DROP INDEX '||pREPLACEUSER||X.INDEX_NAME||';'; --添加新的索引 pSQLTEXT:=pSQLTEXT||pSQLTEXT||pSOURCECODE; END LOOP; IF pINDEX>0 THEN pSQLTEXT:=pSQLTEXT||CHR(10)||('--更新有變更的索引結束!------------------------------------------------------------'); pINDEX:=0; END IF; END; PROCEDURE COMPARE_DB --功能:獲取對比修改數據庫對象的SQL語句.注意因爲獲取源碼權限問題,該過程只能在源用戶庫上執行 --參數: --調用: /* DECLARE pSQLTEXT CLOB; BEGIN SYS.DBMS_OUTPUT.ENABLE(999999); PKG_COMPAREDB.COMPARE_DB('DKGLL','',1,pSQLTEXT); --DBMS_OUTPUT.PUT_LINE(pSQLTEXT); PKG_DBMANAGE.CLOB_TO_FILE('BACKDIR','('||TO_CHAR(CURRENT_DATE,'YYYYMMDDHH24')||').sql','1',pSQLTEXT); END; */ ( pSOURCEUSER IN VARCHAR2, --源用戶名 pTARGETUSER IN VARCHAR2, --目標用戶名 pOBJTYPE IN NUMBER, --對象類型:0-對比表、序列、處理觸發器的異常等,1-導出全部具備依賴關係的對象(視圖、函數、過程、包)以及其餘能夠進行replace的對象,2-導出全部job、調度 pDROPTABLE IN NUMBER:=1, --是否刪除表:0-不刪除,其餘-刪除,默認-刪除 pSQLTEXT OUT CLOB ) --當前須要導出的對象按照順序以下: --1:表 --2:序列 --3:類型 --4:目錄 --5:同義詞 --6:JAVA SOURCE --7:實體化視圖 --8:視圖、函數、過程、包 --9:觸發器 --10:JOB --11:調度程序 AS pSQLTEXT0 CLOB; BEGIN IF pOBJTYPE=0 THEN --1:對比表 COMPARE_TABLE(pSOURCEUSER,pTARGETUSER,NULL,pDROPTABLE,pSQLTEXT0); IF pSQLTEXT0 IS NOT NULL THEN pSQLTEXT:=pSQLTEXT0; END IF; --2:對比序列 COMPARE_SEQUENCE(pSOURCEUSER,pTARGETUSER,NULL,pSQLTEXT0); IF pSQLTEXT0 IS NOT NULL THEN pSQLTEXT:=pSQLTEXT||CHR(10)||pSQLTEXT0; END IF; --3:處理觸發器形成的異常等 COMPARE_TRIGGER(pSOURCEUSER,pTARGETUSER,pSQLTEXT0); IF pSQLTEXT0 IS NOT NULL THEN pSQLTEXT:=pSQLTEXT||CHR(10)||pSQLTEXT0; END IF; ELSIF pOBJTYPE=1 THEN --4:目錄 --4:導出類型 PKG_GET_DDL.GET_DDL(pSOURCEUSER,pTARGETUSER,0,NULL,6,pSQLTEXT0); IF pSQLTEXT0 IS NOT NULL THEN pSQLTEXT:='EXECUTE PKG_DBMANAGE.DROP_ALL_OBJECT(USER,''5'');'||CHR(10)||pSQLTEXT0; END IF; --5:同義詞 PKG_GET_DDL.GET_DDL(pSOURCEUSER,pTARGETUSER,0,NULL,10,pSQLTEXT0); IF pSQLTEXT0 IS NOT NULL THEN pSQLTEXT:=pSQLTEXT||CHR(10)||pSQLTEXT0; END IF; --6:JAVA SOURCE PKG_GET_DDL.GET_DDL(pSOURCEUSER,pTARGETUSER,0,NULL,11,pSQLTEXT0); IF pSQLTEXT0 IS NOT NULL THEN pSQLTEXT:=pSQLTEXT||CHR(10)||REPLACE(pSQLTEXT0,'CREATE JAVA SOURCE','CREATE OR REPLACE JAVA SOURCE'); END IF; --7:實體化視圖 PKG_GET_DDL.GET_DDL(pSOURCEUSER,pTARGETUSER,0,NULL,12,pSQLTEXT0); IF pSQLTEXT0 IS NOT NULL THEN pSQLTEXT:=pSQLTEXT||CHR(10)||pSQLTEXT0; END IF; --8:導出全部具備依賴關係的對象(視圖、函數、過程、包) PKG_GET_DDL.GET_DEPEND_DDL(pSOURCEUSER,pTARGETUSER,pSQLTEXT0); IF pSQLTEXT0 IS NOT NULL THEN pSQLTEXT:=pSQLTEXT||CHR(10)||pSQLTEXT0; END IF; --9:導出全部觸發器 PKG_GET_DDL.GET_DDL(pSOURCEUSER,pTARGETUSER,0,NULL,4,pSQLTEXT0); IF pSQLTEXT0 IS NOT NULL THEN pSQLTEXT:=pSQLTEXT||CHR(10)||pSQLTEXT0; END IF; ELSIF pOBJTYPE=2 THEN --10:JOB COMPARE_JOB(pSOURCEUSER,pTARGETUSER,1,pSQLTEXT0); IF pSQLTEXT0 IS NOT NULL THEN pSQLTEXT:=pSQLTEXT||CHR(10)||pSQLTEXT0; END IF; --11:調度程序 COMPARE_SCHEDULER(pSOURCEUSER,pTARGETUSER,1,pSQLTEXT0); IF pSQLTEXT0 IS NOT NULL THEN pSQLTEXT:=pSQLTEXT||CHR(10)||pSQLTEXT0; END IF; END IF; END; END; / CREATE OR REPLACE PACKAGE "PKG_SESSION" AS --功能:設置上下文 PROCEDURE SET_CONTEXT( KEY IN VARCHAR2, VALUE IN VARCHAR2 ); --功能:查詢當前會話的詳細信息 PROCEDURE GET_SESSION(pCURSOR OUT SYS_REFCURSOR); --功能:建立審計用戶操做表 PROCEDURE CREATE_AUDIO_TABLE; --功能:獲取審計表DDL操做的觸發器文本(根據主鍵列修改,注意標識符不能超過30個字符) PROCEDURE CREATE_AUDIO_TRIG( pTBNAME IN VARCHAR2, --表名,多個表以','分隔 pSQLTEXT OUT CLOB --返回審計表的觸發器文本 ); END; / CREATE OR REPLACE PACKAGE BODY "PKG_SESSION" AS PROCEDURE SET_CONTEXT --功能:設置上下文 --參數:KEY-屬性名,VALUE-屬性的值 --調用: /* --首先必須建立一個context,名稱與存儲過程當中SET_CONTEXT的第一個參數名稱相同 CREATE OR REPLACE CONTEXT DBCONTEXT USING PKG_SESSION; EXEC PKG_SESSION.SET_CONTEXT('NAME','郭君'); */ --日期:2015-08-8 ( KEY IN VARCHAR2, VALUE IN VARCHAR2 ) AS BEGIN DBMS_SESSION.SET_CONTEXT('DBCONTEXT',KEY,VALUE); END; PROCEDURE GET_SESSION --功能:查詢當前會話的詳細信息 --參數:pCURSOR-返回數據集 --調用: /* DECLARE pCURSOR SYS_REFCURSOR; BEGIN PKG_SESSION.GET_SESSION(pCURSOR); END; */ --日期:2018-08-8 ( pCURSOR OUT SYS_REFCURSOR ) AS BEGIN OPEN pCURSOR FOR SELECT SYS_CONTEXT('USERENV','TERMINAL') terminal, SYS_CONTEXT('USERENV','IP_ADDRESS') ip_address, SYS_CONTEXT('USERENV','LANGUAGE') language, SYS_CONTEXT('USERENV','SESSIONID') sessionid, SYS_CONTEXT('USERENV','INSTANCE') instance, SYS_CONTEXT('USERENV','ENTRYID') entryid, SYS_CONTEXT('USERENV','ISDBA') isdba, SYS_CONTEXT('USERENV','NLS_TERRITORY') nls_territory, SYS_CONTEXT('USERENV','NLS_CURRENCY') nls_currency, SYS_CONTEXT('USERENV','NLS_CALENDAR') nls_calendar, SYS_CONTEXT('USERENV','NLS_DATE_FORMAT') nls_date_format, SYS_CONTEXT('USERENV','NLS_DATE_LANGUAGE') nls_date_language, SYS_CONTEXT('USERENV','NLS_SORT') nls_sort, SYS_CONTEXT('USERENV','CURRENT_USER') current_user, SYS_CONTEXT('USERENV','CURRENT_USERID') current_userid, SYS_CONTEXT('USERENV','SESSION_USER') session_user, SYS_CONTEXT('USERENV','SESSION_USERID') session_userid, SYS_CONTEXT('USERENV','PROXY_USER') proxy_user, SYS_CONTEXT('USERENV','PROXY_USERID') proxy_userid, SYS_CONTEXT('USERENV','DB_DOMAIN') db_domain, SYS_CONTEXT('USERENV','DB_NAME') db_name, SYS_CONTEXT('USERENV','HOST') host, SYS_CONTEXT('USERENV','OS_USER') os_user, SYS_CONTEXT('USERENV','EXTERNAL_NAME') external_name, SYS_CONTEXT('USERENV','NETWORK_PROTOCOL') network_protocol, SYS_CONTEXT('USERENV','BG_JOB_ID') bg_job_id, SYS_CONTEXT('USERENV','FG_JOB_ID') fg_job_id, SYS_CONTEXT('USERENV','AUTHENTICATION_TYPE') authentication_type, SYS_CONTEXT('USERENV','AUTHENTICATION_DATA') authentication_data FROM DUAL; END; PROCEDURE CREATE_AUDIO_TABLE --功能:建立審計用戶操做表 --參數: --調用:EXEC PKG_SESSION.CREATE_AUDIO_TABLE; --日期:2018-08-8 AS pCOUNT NUMBER; pSQL VARCHAR2(4000); BEGIN SELECT COUNT(1) INTO pCOUNT FROM SYS.DBA_TABLES WHERE OWNER=USER AND TABLE_NAME='AUDIT_DDL_SQL'; IF pCOUNT=0 THEN --用戶操做表不存在則建立 pSQL:=q'{CREATE TABLE AUDIT_DDL_SQL ( ID NUMBER, SQL VARCHAR2(4000), ADDDATE DATE, TERMINAL VARCHAR2(200), IP_ADDRESS VARCHAR2(30), HOST VARCHAR2(200), OS_USER VARCHAR2(200), DB_NAME VARCHAR2(30), PROGRAM VARCHAR2(200), MODULE VARCHAR2(200), LANGUAGE VARCHAR2(200), NETWORK_PROTOCOL VARCHAR2(200), CONSTRAINT "PK_AUDIT_DDL_SQL" PRIMARY KEY ("ID") )}'; EXECUTE IMMEDIATE pSQL; EXECUTE IMMEDIATE q'{COMMENT ON COLUMN AUDIT_DDL_SQL."ID" IS '自增ID'}'; EXECUTE IMMEDIATE q'{COMMENT ON COLUMN AUDIT_DDL_SQL."SQL" IS '執行的DDL語句'}'; EXECUTE IMMEDIATE q'{COMMENT ON COLUMN AUDIT_DDL_SQL."ADDDATE" IS '執行日期時間'}'; EXECUTE IMMEDIATE q'{COMMENT ON COLUMN AUDIT_DDL_SQL."TERMINAL" IS '終端'}'; EXECUTE IMMEDIATE q'{COMMENT ON COLUMN AUDIT_DDL_SQL."IP_ADDRESS" IS 'IP地址'}'; EXECUTE IMMEDIATE q'{COMMENT ON COLUMN AUDIT_DDL_SQL."HOST" IS '主機名'}'; EXECUTE IMMEDIATE q'{COMMENT ON COLUMN AUDIT_DDL_SQL."OS_USER" IS '系統登陸用戶名'}'; EXECUTE IMMEDIATE q'{COMMENT ON COLUMN AUDIT_DDL_SQL."DB_NAME" IS '數據庫名稱'}'; EXECUTE IMMEDIATE q'{COMMENT ON COLUMN AUDIT_DDL_SQL."PROGRAM" IS '調用程序名'}'; EXECUTE IMMEDIATE q'{COMMENT ON COLUMN AUDIT_DDL_SQL."MODULE" IS '調用程序名'}'; EXECUTE IMMEDIATE q'{COMMENT ON COLUMN AUDIT_DDL_SQL."LANGUAGE" IS '字符集'}'; EXECUTE IMMEDIATE q'{COMMENT ON COLUMN AUDIT_DDL_SQL."NETWORK_PROTOCOL" IS '鏈接方式(TCP/IPC)'}'; END IF; SELECT COUNT(1) INTO pCOUNT FROM SYS.DBA_SEQUENCES WHERE SEQUENCE_OWNER=USER AND SEQUENCE_NAME='DDL_SQL_SEQ'; IF pCOUNT=0 THEN --序列不存在則建立該序列 EXECUTE IMMEDIATE 'CREATE SEQUENCE DDL_SQL_SEQ MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 1 CACHE 10 NOORDER NOCYCLE'; END IF; COMMIT; EXCEPTION WHEN OTHERS THEN SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'執行錯誤:' ||SQLERRM); END; PROCEDURE CREATE_AUDIO_TRIG --功能:獲取審計表DDL操做的觸發器文本(根據主鍵列修改,注意標識符不能超過30個字符) --參數:pTBNAME-表名,多個表以','分隔,pSQLTEXT-返回審計表DDL操做的觸發器文本 --調用: /* DECLARE pSQLTEXT CLOB; BEGIN PKG_SESSION.CREATE_AUDIO_TRIG('DEV_BASETAB',pSQLTEXT); DBMS_OUTPUT.PUT_LINE(pSQLTEXT); END; */ --日期:2015-08-8 ( pTBNAME IN VARCHAR2, --表名,多個表以','分隔 pSQLTEXT OUT CLOB --返回審計表的觸發器文本 ) AS pSTR1 VARCHAR2(4000); pSTR2 VARCHAR2(4000); pSTR3 VARCHAR2(4000); pSTR4 VARCHAR2(4000); pSTR5 VARCHAR2(4000); pSTR6 VARCHAR2(4000); pSTR7 VARCHAR2(4000); pSTR8 VARCHAR2(4000); pSTR9 VARCHAR2(4000); pINSERT VARCHAR2(4000); pUPDATE VARCHAR2(4000); pDELETE VARCHAR2(4000); BEGIN /* --針對單表的的審計操做,經過觸發器捕捉用戶操做,並將操做的DDL語句錄入到審計表中供分析,觸發器的格式以下: CREATE OR REPLACE TRIGGER 觸發器名稱 BEFORE INSERT OR UPDATE OR DELETE ON 表名 FOR EACH ROW DECLARE v_ID VARCHAR2(64); v_NAME VARCHAR2(64); v_AGE VARCHAR2(30); v_BIRTHDAY VARCHAR2(30); v_SQLTEXT VARCHAR2(4000); BEGIN SELECT DECODE(:NEW."ID",NULL,'NULL',''''||:NEW."ID"||''''), DECODE(:NEW."NAME",NULL,'NULL',''''||:NEW."NAME"||''''), DECODE(:NEW."AGE",NULL,'NULL',:NEW."AGE"), DECODE(:NEW."BIRTHDAY",NULL,'NULL','TO_DATE('''||TO_CHAR(:NEW."BIRTHDAY",'YYYY-MM-DD HH24:MI:SS')||''',''YYYY-MM-DD HH24:MI:SS'')') INTO v_ID,v_NAME,v_AGE,v_BIRTHDAY FROM DUAL; IF INSERTING THEN v_SQLTEXT:=INSERT語句; ELSIF UPDATING THEN v_SQLTEXT:=UPDATE語句; ELSE v_SQLTEXT:=DELETE語句; END IF; --錄入到審計表中 INSERT INTO LDAPSYNCCMDCACHE VALUES(LDAPSYNCCMDCACHE_SEQ.NEXTVAL,v_SQLTEXT,SYSDATE); END; */ FOR TB IN ( SELECT TABLE_NAME FROM SYS.DBA_TABLES WHERE OWNER=USER AND (INSTR(','||pTBNAME||',',','||TABLE_NAME||',',1)>0) ) LOOP FOR X IN ( SELECT A.COLUMN_NAME,CASE WHEN DATA_TYPE LIKE '%CHAR%' THEN DATA_LENGTH ELSE 30 END AS CHARLEN,MAX(LENGTH(A.COLUMN_NAME)) OVER(ORDER BY 1) AS COLNAMELEN,COUNT(A.COLUMN_NAME) OVER(ORDER BY 1) AS CN,A.COLUMN_ID, CASE WHEN DATA_TYPE LIKE '%CHAR%' THEN 'DECODE(:NEW."'||A.COLUMN_NAME||'",NULL,''NULL'',''''''''||:NEW."'||A.COLUMN_NAME||'"||'''''''')' WHEN DATA_TYPE='NUMBER' THEN 'DECODE(:NEW."'||A.COLUMN_NAME||'",NULL,''NULL'',:NEW."'||A.COLUMN_NAME||'")' WHEN DATA_TYPE='DATE' THEN 'DECODE(:NEW."'||A.COLUMN_NAME||'",NULL,''NULL'',''TO_DATE(''''''||TO_CHAR(:NEW."'||A.COLUMN_NAME||'",''YYYY-MM-DD HH24:MI:SS'')||'''''',''''YYYY-MM-DD HH24:MI:SS'''')'')' ELSE NULL END AS VAL, CASE WHEN B.COLUMN_NAME IS NULL THEN 0 ELSE 1 END ISPRIMARY FROM SYS.DBA_TAB_COLUMNS A LEFT JOIN ( SELECT TA.OWNER,TA.TABLE_NAME,TA.COLUMN_NAME FROM SYS.DBA_CONS_COLUMNS TA JOIN SYS.DBA_CONSTRAINTS TB ON (TA.OWNER=TB.OWNER AND TA.TABLE_NAME=TB.TABLE_NAME AND TA.CONSTRAINT_NAME=TB.CONSTRAINT_NAME) WHERE TB.CONSTRAINT_TYPE='P' ) B ON (A.OWNER=B.OWNER AND A.TABLE_NAME=B.TABLE_NAME AND A.COLUMN_NAME=B.COLUMN_NAME) WHERE A.OWNER=USER AND A.TABLE_NAME=TB.TABLE_NAME AND A.DATA_TYPE NOT LIKE '%LOB' AND A.DATA_TYPE NOT LIKE '%LONG' ORDER BY A.COLUMN_ID ) LOOP pSTR1:=pSTR1||' v_'||X.COLUMN_NAME||LPAD(' ',X.COLNAMELEN-LENGTH(X.COLUMN_NAME)+1,' ')||'VARCHAR2('||X.CHARLEN||');'||CHR(10); SELECT pSTR2||' '||X.VAL||DECODE(X.CN,X.COLUMN_ID,'',','||CHR(10)), pSTR3||'v_'||X.COLUMN_NAME||DECODE(X.CN,X.COLUMN_ID,'',','), pSTR4||X.COLUMN_NAME||DECODE(X.CN,X.COLUMN_ID,'',','), pSTR5||'v_'||X.COLUMN_NAME||DECODE(X.CN,X.COLUMN_ID,'','||'',''||') INTO pSTR2,pSTR3,pSTR4,pSTR5 FROM DUAL; IF X.ISPRIMARY=0 THEN pSTR6:=pSTR6||X.COLUMN_NAME||'=''||v_'||X.COLUMN_NAME||'||'','; ELSE pSTR7:=pSTR7||X.COLUMN_NAME||'=''||v_'||X.COLUMN_NAME||' AND '; pSTR8:=pSTR8||X.COLUMN_NAME||'=''''''||:OLD.'||X.COLUMN_NAME||'||'''''''' AND '; END IF; END LOOP; pSTR9:=' SELECT'||pSTR2||CHR(10)|| ' INTO '||pSTR3||' FROM DUAL;'; pINSERT:=' v_SQLTEXT:=''INSERT INTO '||TB.TABLE_NAME||'('||pSTR4||') VALUES(''||'||CHR(10)|| ' '||pSTR5||'||'')'';'; pUPDATE:=' v_SQLTEXT:=''UPDATE '||TB.TABLE_NAME||' SET '||SUBSTR(pSTR6,1,LENGTH(pSTR6)-4)||'||'||CHR(10)|| ' '' WHERE '||SUBSTR(pSTR7,1,LENGTH(pSTR7)-5)||';'; pDELETE:=' v_SQLTEXT:=''DELETE FROM '||TB.TABLE_NAME||' WHERE '||SUBSTR(pSTR8,1,LENGTH(pSTR8)-5)||';'; pSQLTEXT:=pSQLTEXT|| 'CREATE OR REPLACE TRIGGER '||TB.TABLE_NAME||'_AUDIT'||CHR(10)|| 'BEFORE INSERT OR UPDATE OR DELETE ON '||TB.TABLE_NAME||' --審計用戶對該表的增刪改操做'||CHR(10)|| 'FOR EACH ROW'||CHR(10)|| 'DECLARE'||CHR(10)|| pSTR1||' v_SQLTEXT VARCHAR2(4000);'||CHR(10)|| 'BEGIN'||CHR(10)|| pSTR9||CHR(10)|| ' /*'||CHR(10)|| ' 插入時往歷史表存放的新插入的數據'||CHR(10)|| ' 修改時往歷史表存放的修改後的數據'||CHR(10)|| ' 刪除時往歷史表存放的刪除以前的數據'||CHR(10)|| ' */'||CHR(10)|| ' IF INSERTING THEN'||CHR(10)|| pINSERT||CHR(10)|| ' ELSIF UPDATING THEN'||CHR(10)|| pUPDATE||CHR(10)|| ' ELSE'||CHR(10)|| pDELETE||CHR(10)|| ' END IF;'||CHR(10)|| ' INSERT INTO AUDIT_DDL_SQL(ID,SQL,ADDDATE,TERMINAL,IP_ADDRESS,HOST,OS_USER,DB_NAME,PROGRAM,MODULE,LANGUAGE,NETWORK_PROTOCOL)'||CHR(10)|| ' SELECT DDL_SQL_SEQ.NEXTVAL,v_SQLTEXT,SYSDATE,SYS_CONTEXT(''USERENV'',''TERMINAL''),SYS_CONTEXT(''USERENV'',''IP_ADDRESS''),SYS_CONTEXT(''USERENV'',''HOST''),SYS_CONTEXT(''USERENV'',''OS_USER''),'||CHR(10)|| ' SYS_CONTEXT(''USERENV'',''DB_NAME''),PROGRAM,MODULE,SYS_CONTEXT(''USERENV'',''LANGUAGE''),SYS_CONTEXT(''USERENV'',''NETWORK_PROTOCOL'') FROM v$session WHERE AUDSID=SYS_CONTEXT(''USERENV'',''SESSIONID'');'||CHR(10)|| 'END;'||CHR(10)|| '/'||CHR(10); END LOOP; --DBMS_OUTPUT.PUT_LINE(pSQLTEXT); END; END; / CREATE OR REPLACE PACKAGE "PKG_SELECT" AS --定義表、列記錄類型 TYPE TBCOL IS RECORD ( TABLENAME VARCHAR2(60), --表名 COLUMNNAME VARCHAR2(60), --列名 SELECTSQL VARCHAR2(2000) --查詢語句 ); --定義表、列記錄集合類型 TYPE TBCOLLIST IS TABLE OF TBCOL; --功能:查詢整個數據庫中某個特定值所在的表和字段 FUNCTION FINDVALUEINDB( pVAL IN VARCHAR2, --查找的特定值 pMODEL IN NUMBER:=0 --匹配模式,0-精確匹配,1-左匹配,2-左右模糊匹配,默認精確匹配 ) RETURN TBCOLLIST PIPELINED; END; / CREATE OR REPLACE PACKAGE BODY "PKG_SELECT" AS FUNCTION FINDVALUEINDB --功能:查詢整個數據庫中某個特定值所在的表和字段 --參數: --調用:SELECT * FROM TABLE(PKG_SELECT.FINDVALUEINDB('管理',1)) --日期:2014-12-10 ( pVAL IN VARCHAR2, --查找的特定值 pMODEL IN NUMBER:=0 --匹配模式,0-左匹配,1-左右模糊匹配,其餘--精確匹配,默認左匹配 ) RETURN TBCOLLIST PIPELINED IS pSQL VARCHAR2(200); --保存要執行的SQL語句 pREGSTR VARCHAR2(200); --保存左右匹配的綁定變量值 pCOUNT NUMBER; --統計表列的值等於傳遞特定值的數量 INFO TBCOL; --保存的記錄類型 BEGIN FOR X IN ( SELECT A.TABLE_NAME,A.COLUMN_NAME FROM SYS.USER_TAB_COLUMNS A JOIN SYS.USER_TABLES B ON A.TABLE_NAME=B.TABLE_NAME WHERE A.DATA_TYPE='VARCHAR2' AND A.CHAR_LENGTH>=LENGTHB(pVAL) AND B.TEMPORARY='N' ORDER BY A.TABLE_NAME,A.COLUMN_NAME ) LOOP pSQL:='SELECT COUNT(1) FROM "'||X.TABLE_NAME||'" WHERE "'||X.COLUMN_NAME||'" LIKE :1'; SELECT DECODE(pMODEL,1,'%','')||pVAL||DECODE(pMODEL,0,'%',1,'%','') INTO pREGSTR FROM DUAL; EXECUTE IMMEDIATE pSQL INTO pCOUNT USING pREGSTR; IF pCOUNT>=1 THEN INFO.TABLENAME:=X.TABLE_NAME; INFO.COLUMNNAME:=X.COLUMN_NAME; INFO.SELECTSQL:='SELECT "'||X.COLUMN_NAME||'" FROM "'||X.TABLE_NAME||'" WHERE "'||X.COLUMN_NAME||'" LIKE '''||pREGSTR||''''; PIPE ROW(INFO); END IF; END LOOP; RETURN; END; END; / CREATE OR REPLACE PACKAGE "PKG_BACKUP" AS --功能:備份指定用戶下的表數據 PROCEDURE EXPORT_DB ( pUSER IN VARCHAR2 := USER, pDIR IN VARCHAR2 := 'DATA_PUMP_DIR', pFILENAME IN VARCHAR2 := NULL ); END; / CREATE OR REPLACE PACKAGE BODY "PKG_BACKUP" AS PROCEDURE EXPORT_DB --功能:備份指定用戶下的表數據 --參數: --調用: /* EXEC PKG_BACKUP.EXPORT_DB; */ --日期:2016-03-11 ( pUSER IN VARCHAR2 := USER, pDIR IN VARCHAR2 := 'DATA_PUMP_DIR', pFILENAME IN VARCHAR2 := NULL ) AS l_backname VARCHAR2(200); l_dp_handle NUMBER; BEGIN SYS.DBMS_OUTPUT.ENABLE(999999); l_backname := 'TBS1-'||TO_CHAR(CURRENT_DATE,'YYYYMMDDHH24')||'.DMP'; DBMS_OUTPUT.PUT_LINE(l_backname); --version={COMPATIBLE|LATEST|version_string} --version:爲COMPATIBLE時,會根據初始化參數COMPATIBLE生成對象元數據;爲LATEST時會根據數據庫的實際版本生成對象元數據;version_string用於指定數據庫版本字符串 l_dp_handle := DBMS_DATAPUMP.open (operation => 'EXPORT' , job_mode => 'TABLE' , remote_link => NULL , version => 'LATEST'); DBMS_DATAPUMP.add_file (handle => l_dp_handle , filename => l_backname , directory => pDIR , filetype => 1 , reusefile => 1); --爲1表示覆蓋更新 DBMS_DATAPUMP.add_file (handle => l_dp_handle , filename => 'empdp.log' , directory => pDIR , filetype => 3); --若是非當前賬戶,使用下面的過濾條件,即特定schema下的特定表,如爲當前賬戶,此過濾條件可省略 DBMS_DATAPUMP.METADATA_FILTER (HANDLE => l_dp_handle , name => 'SCHEMA_EXPR' , value => 'IN ('''||pUSER||''')'); DBMS_DATAPUMP.set_parameter(handle => l_dp_handle ,name => 'KEEP_MASTER' ,value => 0); DBMS_DATAPUMP.set_parameter(handle => l_dp_handle ,name => 'INCLUDE_METADATA' ,value => 1); DBMS_DATAPUMP.set_parameter(handle => l_dp_handle ,name => 'DATA_ACCESS_METHOD' ,value => 'AUTOMATIC'); DBMS_DATAPUMP.set_parameter(handle => l_dp_handle ,name => 'ESTIMATE' ,value => 'BLOCKS'); --設定並行度 DBMS_DATAPUMP.set_parallel (l_dp_handle, 2); DBMS_DATAPUMP.start_job (handle => l_dp_handle ,skip_current => 0 ,abort_step => 0 ); DBMS_DATAPUMP.detach (l_dp_handle); END; END; / CREATE OR REPLACE PACKAGE PKG_MAIL AUTHID CURRENT_USER IS --功能:用oracle發送郵件 PROCEDURE SEND_EMAIL( P_SENDOR VARCHAR2, --發送人郵件地址 P_RECEIVER VARCHAR2, --接收人郵件地址,能夠同時發送到多個地址上,地址之間用","或者";"隔開 P_SUB VARCHAR2, --郵件標題 P_CONTENT VARCHAR2, --郵件正文,能夠爲文本或者HTML。 p_CONTENTTYPE VARCHAR2, --郵件正文類型,1或者txt-表示文本,2或者html表示爲html P_FILENAME VARCHAR2 DEFAULT NULL, --附件名稱,必須包含完整的路徑,如"d:\temp\a.txt"。能夠有多個附件,地址之間用","或者";"隔開 P_ENCODE VARCHAR2 DEFAULT 'bit 7', --附件編碼轉換格式,其中 p_encode='bit 7' 表示文本類型附件,p_encode='base64' 表示二進制類型附件 --注意: -- 一、對於文本類型的附件,不能用base64的方式發送,不然出錯 -- 二、對於多個附件只能用同一種格式發送 P_SERVER VARCHAR2, --郵件服務器地址,能夠是域名或者IP P_PORT NUMBER DEFAULT 25, --郵件服務器端口,默認國內未加密的SMTP端口爲25 P_NEED_SMTP INT DEFAULT 0, --是否須要smtp認證,0表示不須要,1表示須要 P_USER VARCHAR2 DEFAULT NULL, --smtp驗證須要的用戶名 P_PASS VARCHAR2 DEFAULT NULL --smtp驗證須要的密碼 ); END; / CREATE OR REPLACE PACKAGE BODY PKG_MAIL AS PROCEDURE SEND_EMAIL --功能:用oracle發送郵件 --參數: --調用: --日期:2017-03-05 ( P_SENDOR VARCHAR2, --發送人郵件地址 P_RECEIVER VARCHAR2, --接收人郵件地址,能夠同時發送到多個地址上,地址之間用","或者";"隔開 P_SUB VARCHAR2, --郵件標題 P_CONTENT VARCHAR2, --郵件正文,能夠爲文本或者HTML。 p_CONTENTTYPE VARCHAR2, --郵件正文類型,1或者txt-表示文本,2或者html表示爲html P_FILENAME VARCHAR2 DEFAULT NULL, --附件名稱,必須包含完整的路徑,如"d:\temp\a.txt"。能夠有多個附件,地址之間用","或者";"隔開 P_ENCODE VARCHAR2 DEFAULT 'bit 7', --附件編碼轉換格式,其中 p_encode='bit 7' 表示文本類型附件,p_encode='base64' 表示二進制類型附件 --注意: -- 一、對於文本類型的附件,不能用base64的方式發送,不然出錯 -- 二、對於多個附件只能用同一種格式發送 P_SERVER VARCHAR2, --郵件服務器地址,能夠是域名或者IP P_PORT NUMBER DEFAULT 25, --郵件服務器端口,默認國內未加密的SMTP端口爲25 P_NEED_SMTP INT DEFAULT 0, --是否須要smtp認證,0表示不須要,1表示須要 P_USER VARCHAR2 DEFAULT NULL, --smtp驗證須要的用戶名 P_PASS VARCHAR2 DEFAULT NULL --smtp驗證須要的密碼 ) AS /* 主要功能:一、支持多收件人。 二、支持中文 三、支持抄送人 四、支持大於32K的附件 五、支持多行正文 六、支持多附件 七、支持文本附件和二進制附件 八、支持HTML格式 注意:若是不是sys用戶操做,需開啓ACL權限,步驟以下: BEGIN DBMS_NETWORK_ACL_ADMIN.CREATE_ACL ( acl => 'email_server_permissions.xml', description => 'Enables network permissions for the e-mail server', principal => 'PKGTEST',--進行操做的數據庫用戶且用戶要大寫 is_grant => TRUE, privilege => 'connect'); END; BEGIN DBMS_NETWORK_ACL_ADMIN.assign_acl ( acl => 'email_server_permissions.xml', host => 'smtp.mxhichina.com', lower_port => 25, upper_port => NULL); COMMIT; END; SELECT host, lower_port, upper_port, acl FROM sys.dba_network_acls; BEGIN dbms_network_acl_admin.add_privilege( acl => 'utlpkg.xml', principal =>'PKGTEST',--進行操做的數據庫用戶且用戶要大寫 is_grant => TRUE, privilege => 'connect'); END; SELECT acl, principal, privilege, is_grant, TO_CHAR(start_date, 'DD-MON-YYYY') AS start_date, TO_CHAR(end_date, 'DD-MON-YYYY') AS end_date FROM sys.dba_network_acl_privileges; /* /* 調用示例:測試採用新浪郵箱發送已經過 declare phtml varchar2(4000); begin phtml:=q'[ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Oracle導出HTML郵件</title> <style type="text/css"> *{margin:0;padding:0} body{width:867px; margin:0 auto;background:#2c383e url(images/bgindex.jpg) repeat-x;} h2{text-align:center;height:50px;line-height:50px;letter-spacing:2px;} #content{ width:580px; height:850px; float:left; background:#fff url(images/weline.gif) repeat-y left top; padding-left:20px;} #content h1{background:url(images/job.gif) no-repeat left 20px; height:60px;text-indent:-9999px;} #content table{width:540px;line-height:30px;font-size:12px; background:#ccc; border-collapse:collapse} #content table tr {text-align:center; background:#fff} #content table tr th{font-weight:normal; background:#eee;border:1px solid gray} #content table tr:hover{background:#CC0} #content table tr td{border:1px solid gray} #content table tr td a{ text-decoration:none} #content table tr td a:hover{ text-decoration:underline} #content .contentp1{text-align:center; margin-top:30px; font-size:12px;margin-bottom:30px} #content .contentp2{width:540px;font-size:12px;text-align:right;height:25px;line-height:25px} </style> </head> <body> <div id="content"> <h2>數據表格展現</h2> <table> <tr><th>序號</th><th>職位名稱</th><th>招聘人數</th><th>工做地點</th><th>有效時間</th><th>職位描述</th></th> <tr><td>1</td><td>保安人員</td><td>3至4人</td><td>武漢</td><td>2016.12.08</td><td><a href="#">查看</a></td></tr> <tr><td>2</td><td>項目技術人員</td><td>18人</td><td>北京</td><td>2016.10.08</td><td><a href="#">查看</a></td></tr> <tr><td>3</td><td>總經理助理</td><td>3人</td><td>溫州</td><td>2016.07.11</td><td><a href="#">查看</a></td></tr> <tr><td>4</td><td>銷售表明</td><td>40人</td><td>溫州</td><td>2016.07.11</td><td><a href="#">查看</a></td></tr> <tr><td>5</td><td>客服</td><td>15人</td><td>溫州</td><td>2016.07.11</td><td><a href="#">查看</a></td></tr> </table> <p class="contentp1">共計:5 條記錄 頁次:1/1 每頁:5 條 上一頁/下一頁</p> <p class="contentp2">來源:Oracle數據庫</p> <p class="contentp2">記錄人:dkgll</p> </div> </body> </html> ]'; PKG_MAIL.SEND_EMAIL('dkgll@sina.com','xx@qq.com,xx@126.com,xx@sina.com','Oracle導出HTMl郵件',phtml,2,'C:\index.html,E:\XXXX.txt','bit 7','smtp.sina.com',25,1,'yy@sina.com','****'); END; */ L_CONTYPE VARCHAR2(20); L_CRLF VARCHAR2(2) := UTL_TCP.CRLF; L_SENDORADDRESS VARCHAR2(4000); L_SPLITE VARCHAR2(10) := '++'; BOUNDARY CONSTANT VARCHAR2(256) := '-----BYSUK'; FIRST_BOUNDARY CONSTANT VARCHAR2(256) := '--' || BOUNDARY || L_CRLF; LAST_BOUNDARY CONSTANT VARCHAR2(256) := '--' || BOUNDARY || '--' || L_CRLF; MULTIPART_MIME_TYPE CONSTANT VARCHAR2(256) := 'multipart/mixed; boundary="' || BOUNDARY || '"'; /* 如下部分是發送大二進制附件時用到的變量 */ L_FIL BFILE; L_FILE_LEN NUMBER; L_MODULO NUMBER; L_PIECES NUMBER; L_FILE_HANDLE UTL_FILE.FILE_TYPE; L_AMT BINARY_INTEGER := 672 * 3; /* ensures proper format; 2016 */ L_FILEPOS PLS_INTEGER := 1; /* pointer for the file */ L_CHUNKS NUMBER; L_BUF RAW(2100); L_DATA RAW(2100); L_MAX_LINE_WIDTH NUMBER := 54; L_DIRECTORY_BASE_NAME VARCHAR2(100) := 'DIR_FOR_SEND_MAIL'; L_LINE VARCHAR2(1000); L_MESG VARCHAR2(32767); /* 以上部分是發送大二進制附件時用到的變量 */ TYPE ADDRESS_LIST IS TABLE OF VARCHAR2(100) INDEX BY BINARY_INTEGER; MY_ADDRESS_LIST ADDRESS_LIST; TYPE ACCT_LIST IS TABLE OF VARCHAR2(100) INDEX BY BINARY_INTEGER; MY_ACCT_LIST ACCT_LIST; -------------------------------------返回附件源文件所在目錄或者名稱-------------------------------------- FUNCTION GET_FILE(P_FILE VARCHAR2, P_GET INT) RETURN VARCHAR2 IS --p_get=1 表示返回目錄 --p_get=2 表示返回文件名 L_FILE VARCHAR2(1000); BEGIN IF INSTR(P_FILE, '\') > 0 THEN --windows IF P_GET = 1 THEN L_FILE := SUBSTR(P_FILE, 1, INSTR(P_FILE, '\', -1) - 1); ELSIF P_GET = 2 THEN L_FILE := SUBSTR(P_FILE, - (LENGTH(P_FILE) - INSTR(P_FILE, '\', -1))); END IF; ELSIF INSTR(P_FILE, '/') > 0 THEN --linux/unix IF P_GET = 1 THEN L_FILE := SUBSTR(P_FILE, 1, INSTR(P_FILE, '/', -1) - 1); ELSIF P_GET = 2 THEN L_FILE := SUBSTR(P_FILE, - (LENGTH(P_FILE) - INSTR(P_FILE, '/', -1))); END IF; END IF; RETURN L_FILE; END; ---------------------------------------------刪除directory------------------------------------ PROCEDURE DROP_DIRECTORY(P_DIRECTORY_NAME VARCHAR2) IS BEGIN EXECUTE IMMEDIATE 'drop directory ' || P_DIRECTORY_NAME; EXCEPTION WHEN OTHERS THEN NULL; END; --------------------------------------------------建立directory----------------------------------------- PROCEDURE CREATE_DIRECTORY(P_DIRECTORY_NAME VARCHAR2, P_DIR VARCHAR2) IS BEGIN EXECUTE IMMEDIATE 'create directory ' || P_DIRECTORY_NAME || ' as ''' || P_DIR || ''''; EXECUTE IMMEDIATE 'grant read,write on directory ' || P_DIRECTORY_NAME || ' to public'; EXCEPTION WHEN OTHERS THEN RAISE; END; --------------------------------------------分割郵件地址或者附件地址----------------------------------- PROCEDURE P_SPLITE_STR(P_STR VARCHAR2, P_SPLITE_FLAG INT DEFAULT 1) IS L_ADDR VARCHAR2(254) := ''; L_LEN INT; L_STR VARCHAR2(4000); J INT := 0; --表示郵件地址或者附件的個數 BEGIN /*處理接收郵件地址列表,包括去空格、將;轉換爲,等*/ L_STR := TRIM(RTRIM(REPLACE(REPLACE(P_STR, ';', ','), ' ', ''), ',')); L_LEN := LENGTH(L_STR); FOR I IN 1 .. L_LEN LOOP IF SUBSTR(L_STR, I, 1) <> ',' THEN L_ADDR := L_ADDR || SUBSTR(L_STR, I, 1); ELSE J := J + 1; IF P_SPLITE_FLAG = 1 THEN --表示處理郵件地址 --先後須要加上'<>',不然不少郵箱將不能發送郵件 L_ADDR := '<' || L_ADDR || '>'; --調用郵件發送過程 MY_ADDRESS_LIST(J) := L_ADDR; ELSIF P_SPLITE_FLAG = 2 THEN --表示處理附件名稱 MY_ACCT_LIST(J) := L_ADDR; END IF; L_ADDR := ''; END IF; IF I = L_LEN THEN J := J + 1; IF P_SPLITE_FLAG = 1 THEN --調用郵件發送過程 L_ADDR := '<' || L_ADDR || '>'; MY_ADDRESS_LIST(J) := L_ADDR; ELSIF P_SPLITE_FLAG = 2 THEN MY_ACCT_LIST(J) := L_ADDR; END IF; END IF; END LOOP; END; ------------------------------------------------寫郵件頭和郵件內容------------------------------------------ PROCEDURE WRITE_DATA(P_CONN IN OUT NOCOPY UTL_SMTP.CONNECTION, P_NAME IN VARCHAR2, P_VALUE IN VARCHAR2, P_SPLITE VARCHAR2 DEFAULT ':', P_CRLF VARCHAR2 DEFAULT L_CRLF) IS BEGIN /* utl_raw.cast_to_raw 對解決中文亂碼問題很重要*/ UTL_SMTP.WRITE_RAW_DATA(P_CONN, UTL_RAW.CAST_TO_RAW(CONVERT(P_NAME || P_SPLITE || P_VALUE || P_CRLF, 'ZHS16GBK'))); END; ----------------------------------------寫MIME郵件尾部----------------------------------------------------- PROCEDURE END_BOUNDARY(CONN IN OUT NOCOPY UTL_SMTP.CONNECTION, LAST IN BOOLEAN DEFAULT FALSE) IS BEGIN UTL_SMTP.WRITE_DATA(CONN, UTL_TCP.CRLF); IF (LAST) THEN UTL_SMTP.WRITE_DATA(CONN, LAST_BOUNDARY); END IF; END; ----------------------------------------------發送附件---------------------------------------------------- PROCEDURE ATTACHMENT(CONN IN OUT NOCOPY UTL_SMTP.CONNECTION, MIME_TYPE IN VARCHAR2 DEFAULT 'text/plain', INLINE IN BOOLEAN DEFAULT TRUE, FILENAME IN VARCHAR2 DEFAULT 't.txt', TRANSFER_ENC IN VARCHAR2 DEFAULT '7 bit', DT_NAME IN VARCHAR2 DEFAULT '0') IS L_FILENAME VARCHAR2(1000); BEGIN --寫附件頭 UTL_SMTP.WRITE_DATA(CONN, FIRST_BOUNDARY); --設置附件格式 WRITE_DATA(CONN, 'Content-Type', MIME_TYPE); --若是文件名稱非空,表示有附件 DROP_DIRECTORY(DT_NAME); --建立directory CREATE_DIRECTORY(DT_NAME, GET_FILE(FILENAME, 1)); --獲得附件文件名稱 L_FILENAME := GET_FILE(FILENAME, 2); IF (INLINE) THEN WRITE_DATA(CONN, 'Content-Disposition', 'inline; filename="' || L_FILENAME || '"'); ELSE WRITE_DATA(CONN, 'Content-Disposition', 'attachment; filename="' || L_FILENAME || '"'); END IF; --設置附件的轉換格式 IF (TRANSFER_ENC IS NOT NULL) THEN WRITE_DATA(CONN, 'Content-Transfer-Encoding', TRANSFER_ENC); END IF; UTL_SMTP.WRITE_DATA(CONN, UTL_TCP.CRLF); --begin 貼附件內容 IF TRANSFER_ENC = 'bit 7' THEN --若是是文本類型的附件 BEGIN L_FILE_HANDLE := UTL_FILE.FOPEN(DT_NAME, L_FILENAME, 'r'); --打開文件 --把附件分紅多份,這樣能夠發送超過32K的附件 LOOP UTL_FILE.GET_LINE(L_FILE_HANDLE, L_LINE); L_MESG := L_LINE || L_CRLF; WRITE_DATA(CONN, '', L_MESG, '', ''); END LOOP; UTL_FILE.FCLOSE(L_FILE_HANDLE); END_BOUNDARY(CONN); EXCEPTION WHEN OTHERS THEN UTL_FILE.FCLOSE(L_FILE_HANDLE); END_BOUNDARY(CONN); NULL; END; --結束文本類型附件的處理 ELSIF TRANSFER_ENC = 'base64' THEN --若是是二進制類型的附件 BEGIN --把附件分紅多份,這樣能夠發送超過32K的附件 L_FILEPOS := 1; --重置offset,在發送多個附件時,必須重置 L_FIL := BFILENAME(DT_NAME, L_FILENAME); L_FILE_LEN := DBMS_LOB.GETLENGTH(L_FIL); L_MODULO := MOD(L_FILE_LEN, L_AMT); L_PIECES := TRUNC(L_FILE_LEN / L_AMT); IF (L_MODULO <> 0) THEN L_PIECES := L_PIECES + 1; END IF; DBMS_LOB.FILEOPEN(L_FIL, DBMS_LOB.FILE_READONLY); DBMS_LOB.READ(L_FIL, L_AMT, L_FILEPOS, L_BUF); L_DATA := NULL; FOR I IN 1 .. L_PIECES LOOP L_FILEPOS := I * L_AMT + 1; L_FILE_LEN := L_FILE_LEN - L_AMT; L_DATA := UTL_RAW.CONCAT(L_DATA, L_BUF); L_CHUNKS := TRUNC(UTL_RAW.LENGTH(L_DATA) / L_MAX_LINE_WIDTH); IF (I <> L_PIECES) THEN L_CHUNKS := L_CHUNKS - 1; END IF; UTL_SMTP.WRITE_RAW_DATA(CONN, UTL_ENCODE.BASE64_ENCODE(L_DATA)); L_DATA := NULL; IF (L_FILE_LEN < L_AMT AND L_FILE_LEN > 0) THEN L_AMT := L_FILE_LEN; END IF; DBMS_LOB.READ(L_FIL, L_AMT, L_FILEPOS, L_BUF); END LOOP; DBMS_LOB.FILECLOSE(L_FIL); END_BOUNDARY(CONN); EXCEPTION WHEN OTHERS THEN DBMS_LOB.FILECLOSE(L_FIL); END_BOUNDARY(CONN); RAISE; END; --結束處理二進制附件 END IF; --結束處理附件內容 DROP_DIRECTORY(DT_NAME); END; --結束過程ATTACHMENT ---------------------------------------------真正發送郵件的過程-------------------------------------------- PROCEDURE P_EMAIL(P_SENDORADDRESS2 VARCHAR2, --發送地址 P_RECEIVERADDRESS2 VARCHAR2) --接受地址 IS L_CONN UTL_SMTP.CONNECTION; --定義鏈接 BEGIN /*初始化郵件服務器信息,鏈接郵件服務器*/ L_CONN := UTL_SMTP.OPEN_CONNECTION(P_SERVER, P_PORT); --使用UTL_SMTP.HELO有可能會提示「ORA-29279: SMTP 永久性錯誤: 503 5.5.2 Send hello first.」,改爲使用UTL_SMTP.EHLO就行了 --UTL_SMTP.HELO(L_CONN, P_SERVER); UTL_SMTP.EHLO(L_CONN, P_SERVER); /* smtp服務器登陸校驗 */ IF P_NEED_SMTP = 1 THEN UTL_SMTP.COMMAND(L_CONN, 'AUTH LOGIN', ''); UTL_SMTP.COMMAND(L_CONN, UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(UTL_RAW.CAST_TO_RAW(P_USER)))); UTL_SMTP.COMMAND(L_CONN, UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(UTL_RAW.CAST_TO_RAW(P_PASS)))); END IF; /*設置發送地址和接收地址*/ UTL_SMTP.MAIL(L_CONN, P_SENDORADDRESS2); UTL_SMTP.RCPT(L_CONN, P_RECEIVERADDRESS2); /*設置郵件頭*/ UTL_SMTP.OPEN_DATA(L_CONN); WRITE_DATA(L_CONN, 'Date', TO_CHAR(SYSDATE, 'yyyy-mm-dd hh24:mi:ss')); /*設置發送人*/ WRITE_DATA(L_CONN, 'From', P_SENDOR); /*設置接收人*/ WRITE_DATA(L_CONN, 'To', P_RECEIVER); /*設置郵件主題*/ WRITE_DATA(L_CONN, 'Subject', P_SUB); WRITE_DATA(L_CONN, 'Content-Type', MULTIPART_MIME_TYPE); UTL_SMTP.WRITE_DATA(L_CONN, UTL_TCP.CRLF); UTL_SMTP.WRITE_DATA(L_CONN, FIRST_BOUNDARY); SELECT DECODE(lower(p_CONTENTTYPE),'1','plain','txt','plain','2','html','html','html','plain') INTO L_CONTYPE FROM DUAL; WRITE_DATA(L_CONN, 'Content-Type', 'text/'||L_CONTYPE||';charset=gb2312'); --單獨空一行,不然,正文內容不顯示 UTL_SMTP.WRITE_DATA(L_CONN, UTL_TCP.CRLF); /* 設置郵件正文 把分隔符還原成chr(10)。這主要是爲了shell中調用該過程,若是有多行,則先把多行的內容合併成一行,並用 l_splite分隔 而後用 l_crlf替換chr(10)。這一步是必須的,不然將不能發送郵件正文有多行的郵件 */ WRITE_DATA(L_CONN, '', REPLACE(REPLACE(P_CONTENT, L_SPLITE, CHR(10)), CHR(10), L_CRLF), '', ''); END_BOUNDARY(L_CONN); --若是文件名稱不爲空,則發送附件 IF (P_FILENAME IS NOT NULL) THEN --根據逗號或者分號拆分附件地址 P_SPLITE_STR(P_FILENAME, 2); --循環發送附件(在同一個郵件中) FOR K IN 1 .. MY_ACCT_LIST.COUNT LOOP ATTACHMENT(CONN => L_CONN, FILENAME => MY_ACCT_LIST(K), TRANSFER_ENC => P_ENCODE, DT_NAME => L_DIRECTORY_BASE_NAME || TO_CHAR(K)); END LOOP; END IF; /*關閉數據寫入*/ UTL_SMTP.CLOSE_DATA(L_CONN); /*關閉鏈接*/ UTL_SMTP.QUIT(L_CONN); /*異常處理*/ EXCEPTION WHEN OTHERS THEN NULL; RAISE; END; ---------------------------------------------------主過程----------------------------------------------------- BEGIN L_SENDORADDRESS := '<' || P_SENDOR || '>'; P_SPLITE_STR(P_RECEIVER); --處理郵件地址 FOR K IN 1 .. MY_ADDRESS_LIST.COUNT LOOP P_EMAIL(L_SENDORADDRESS, MY_ADDRESS_LIST(K)); END LOOP; /*處理郵件地址,根據逗號分割郵件*/ EXCEPTION WHEN OTHERS THEN RAISE; END; END; /