该系列脚本结合日常工作,方便DBA做数据管理、迁移、同步等功能,以下为该系列的脚本,按照功能划分不同的包。功能有如下:
1)数据库对象管理(添加、修改、删除、禁用/启用、编译、去重复、闪回、文件读写、会话管理、表空用、用户/权限管理);
2)数据库分析;
3)数据库备份;
4)数据库同步;
5)数据库数据导出;
6)获取数据库对象源码;
7)数据库对比智能升级;
......
更多功能请自行体验。
本系列包依赖于Oracle DBA管理包脚本系列系列(一)的脚本。
EXEC PKG_DBMANAGE.DROP_OBJECT(USER,'CHECKTABLELIST');
EXEC PKG_DBMANAGE.DROP_OBJECT(USER,'CHECKTABLE'); CREATE OR REPLACE TYPE CHECKTABLE IS OBJECT
(
TABLENAME VARCHAR2(40),
WHERESTR VARCHAR2(2000)
);
/
CREATE OR REPLACE TYPE CHECKTABLELIST IS TABLE OF CHECKTABLE;
/ EXEC PKG_DBMANAGE.DROP_OBJECT(USER,'TEMP_TAB_COLUMNS');
EXEC PKG_DBMANAGE.DROP_OBJECT(USER,'TEMP_COLUMN_EXPRESSION'); CREATE GLOBAL TEMPORARY TABLE "TEMP_TAB_COLUMNS"
( "OWNER" VARCHAR2(64 BYTE),
"TABLE_NAME" VARCHAR2(64 BYTE),
"COLUMN_NAME" VARCHAR2(64 BYTE),
"DATA_TYPE" VARCHAR2(64 BYTE),
"ORACLETYPE" VARCHAR2(64 BYTE),
"NULLABLE" CHAR(10 BYTE),
"DATA_DEFAULT" CLOB,
"COLUMN_ID" NUMBER
) ON COMMIT PRESERVE ROWS ; CREATE GLOBAL TEMPORARY TABLE "TEMP_COLUMN_EXPRESSION"
( "INDEX_OWNER" VARCHAR2(64 BYTE),
"INDEX_NAME" VARCHAR2(200 BYTE),
"INDEX_TYPE" VARCHAR2(64 BYTE),
"UNIQUENESS" VARCHAR2(64 BYTE),
"COMPRESSION" VARCHAR2(64 BYTE),
"TABLE_NAME" VARCHAR2(64 BYTE),
"TABLE_TYPE" VARCHAR2(64 BYTE),
"COLUMN_NAME" VARCHAR2(64 BYTE),
"COLUMN_EXPRESSION" CLOB,
"COLUMN_POSITION" NUMBER,
"DESCEND" VARCHAR2(64 BYTE)
) ON COMMIT PRESERVE ROWS ; COMMENT ON TABLE "TEMP_COLUMN_EXPRESSION" IS '保存索引列的详细信息'; EXEC PKG_DBMANAGE.DROP_OBJECT(USER,'TEMP_DIRLIST'); CREATE GLOBAL TEMPORARY TABLE "TEMP_DIRLIST"
( "DIR" VARCHAR2(255 BYTE),
"FILENAME" VARCHAR2(255 BYTE),
"FILESIZE" NUMBER,
"FILEDATE" DATE
) ON COMMIT PRESERVE ROWS ; COMMENT ON COLUMN "TEMP_DIRLIST"."DIR" IS '文件目录';
COMMENT ON COLUMN "TEMP_DIRLIST"."FILENAME" IS '文件名称';
COMMENT ON COLUMN "TEMP_DIRLIST"."FILESIZE" IS '文件大小';
COMMENT ON COLUMN "TEMP_DIRLIST"."FILEDATE" IS '创建文件日期';
COMMENT ON TABLE "TEMP_DIRLIST" IS '文件列表'; CREATE OR REPLACE JAVA SOURCE NAMED "JAVA_DEL_FILE"
AS
import java.io.*;
import java.sql.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.io.File;
import java.lang.String;
public class JAVA_DEL_FILE
{
/**
* 删除目录下所有文件(按时间排序)
*
* @param path
* @return
*/
public static String delAllFile(String Directory,String Filter) throws SQLException
{
List<File> list1 = getFileSort(Directory,Filter);
for (int i = 1;i< list1.size();i++)
{
list1.get(i).delete();
}
return "0";
} /**
* 获取目录下所有文件(按时间排序)
*
* @param path
* @return
*/
public static List<File> getFileSort(String path,String filter)
{
List<File> list1 = getFiles(path, new ArrayList<File>(),filter);
if (list1 != null)
{
if(list1.size() > 0)
{
Collections.sort(list1, new Comparator<File>()
{
public int compare(File file, File newFile)
{
if (file.lastModified() < newFile.lastModified())
{
return 1;
}
else if (file.lastModified() == newFile.lastModified())
{
return 0;
}
else
{
return -1;
}
}
});
}
}
return list1;
} /**
* 获取目录下所有文件
*
* @param realpath
* @param files
* @return
*/
public static List<File> getFiles(String realpath, List<File> files,String filter)
{
File realFile = new File(realpath);
if (realFile.isDirectory())
{
File[] subfiles = realFile.listFiles();
for (File file : subfiles)
{
if (file.isDirectory())
{
getFiles(file.getAbsolutePath(),files,filter);
}
else
{
if(file.getName().toUpperCase().indexOf(filter)!=-1)
{
files.add(file);
}
}
}
}
return files;
}
}
/
CREATE OR REPLACE JAVA SOURCE NAMED "JAVA_DIRLIST"
AS
import java.io.*;
import java.sql.*;
public class JAVA_DIRLIST
{
public static void getList(String directory) throws SQLException
{
File path=new File(directory);
String[] fileList=path.list();
String fileName;
long fileSize;
long fileDate;
for (int i=0;i<fileList.length; i++)
{
fileName=fileList[i];
File fpath=new File(directory+'/'+fileName);
fileSize=fpath.length();
fileDate=fpath.lastModified();
#sql{insert into TEMP_DIRLIST(DIR,filename,filesize,filedate) values(:directory,:fileName,:fileSize,to_date('1970-01-01 08:00:00','YYYY-MM-DD HH24:MI:SS')+:fileDate/(24*60*60*1000))};
}
}
}
/
CREATE OR REPLACE PROCEDURE "EXEC_JAVA_DIRLIST"
--功能:执行Java程序获取文件列表
--参数:见下方说明
--调用:
/*
DELETE FROM TEMP_DIRLIST;
EXEC EXEC_JAVA_DIRLIST('E:\');
select * from TEMP_DIRLIST;
*/
--日期:2014-09-16
(
p_directory in varchar2
)
as language java name 'JAVA_DIRLIST.getList( java.lang.String )';
/
create or replace package PKG_GetHZPY is -- Author : ADMINISTRATOR
-- Created : 2006-10-8 上午 11:51:16
-- Purpose : 获得汉字拼音编码 -- Public type declarations
TYPE THZPY_LIST is VARRAY (526) OF VARCHAR2(6);
TYPE TROMA_NUM_LIST is VARRAY (94) OF VARCHAR2(2);
TYPE TGREECE_ALPHABET_LIST is VARRAY (24) OF VARCHAR2(2);
TYPE TPYIndex_191_list IS VARRAY(191) OF NUMBER;
TYPE TPYIndex_list IS VARRAY(10) OF TPYIndex_191_list; -- Public constant declarations
--<ConstantName> constant <Datatype> := <Value>; -- Public variable declarations
--<VariableName> <Datatype>; -- Public function and procedure declarations
function GetHzPY_by_index(p_PY_Index number) RETURN VARCHAR2;
FUNCTION get_greece_alphabet_py(p_Index NUMBER) RETURN NUMBER;
FUNCTION get_roma_num_py(p_Index NUMBER) RETURN NUMBER;
FUNCTION get_py_index_01(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER;
FUNCTION get_py_index_02(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER;
FUNCTION get_py_index_03(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER;
FUNCTION get_py_index_04(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER;
FUNCTION get_py_index_05(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER;
FUNCTION get_py_index_06(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER;
FUNCTION get_py_index_07(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER;
FUNCTION get_py_index_08(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER;
FUNCTION get_py_index_09(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER;
FUNCTION get_py_index_10(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER;
FUNCTION get_py_index_11(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER;
FUNCTION get_py_index_12(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER;
FUNCTION get_py_index_13(p_Index1 NUMBER, p_Index NUMBER) RETURN NUMBER;
FUNCTION GetHzFullPY(p_String varchar2) RETURN VARCHAR2;
FUNCTION GetHzFullPYLower(p_String varchar2) RETURN VARCHAR2;
FUNCTION GetHzFullPYUpper(p_String varchar2) RETURN VARCHAR2;
FUNCTION GetHzFullPYsubstr(p_String varchar2,s float, e float) RETURN VARCHAR2;
FUNCTION GetHzPYCAP(p_String varchar2) RETURN VARCHAR2;
FUNCTION GetHzPYCAPLower(p_String varchar2) RETURN VARCHAR2;
FUNCTION GetHzPYCAPsubstr(p_String varchar2,s float, e float) RETURN VARCHAR2;
FUNCTION F_TRANS_PINYIN_CAPITAL(P_NAME IN VARCHAR2) RETURN VARCHAR2;
end;
/
create or replace package body PKG_GetHZPY is -- Private type declarations
--type <TypeName> is <Datatype>; -- Private constant declarations
--<ConstantName> constant <Datatype> := <Value>; -- Private variable declarations
--<VariableName> <Datatype>; -- Function and procedure implementations
FUNCTION GetHzPY_by_index(p_PY_Index number) RETURN VARCHAR2 IS
v_PY_List THZPY_LIST := THZPY_LIST(
'a', 'aes', 'ai', 'an', 'ang', 'ao', 'ba', 'bai', 'baike', 'baiwa',
'ban', 'bang', 'bao', 'be', 'bei', 'ben', 'beng', 'bi', 'bia', 'bian',
'biao', 'bie', 'bin', 'bing', 'bo', 'bu', 'ca', 'cai', 'cal', 'can',
'cang', 'cao', 'ce', 'cen', 'ceng', 'ceok', 'ceom', 'ceon', 'ceor', 'cha',
'chai', 'chan', 'chang', 'chao', 'che', 'chen', 'cheng', 'chi', 'chong', 'chou',
'chu', 'chua', 'chuai', 'chuan', 'chuang', 'chui', 'chun', 'chuo', 'ci', 'cis',
'cong', 'cou', 'cu', 'cuan', 'cui', 'cun', 'cuo', 'da', 'dai', 'dan',
'dang', 'dao', 'de', 'defa', 'dei', 'deli', 'dem', 'den', 'deng', 'deo',
'di', 'dia', 'dian', 'diao', 'die', 'dim', 'ding', 'diu', 'dong', 'dou',
'du', 'duan', 'dug', 'dui', 'dul', 'dun', 'duo', 'e', 'ei', 'en',
'eng', 'eo', 'eol', 'eom', 'eos', 'er', 'fa', 'fan', 'fang', 'fei',
'fen', 'feng', 'fenwa', 'fiao', 'fo', 'fou', 'fu', 'fui', 'ga', 'gad',
'gai', 'gan', 'gang', 'gao', 'ge', 'gei', 'gen', 'geng', 'geo', 'geu',
'gib', 'go', 'gong', 'gongli', 'gou', 'gu', 'gua', 'guai', 'guan', 'guang',
'gui', 'gun', 'guo', 'ha', 'hai', 'hal', 'han', 'hang', 'hao', 'haoke',
'he', 'hei', 'hem', 'hen', 'heng', 'heui', 'ho', 'hol', 'hong', 'hou',
'hu', 'hua', 'huai', 'huan', 'huang', 'hui', 'hun', 'huo', 'hwa', 'hweong',
'i', 'ji', 'jia', 'jialun', 'jian', 'jiang', 'jiao', 'jie', 'jin', 'jing',
'jiong', 'jiu', 'jou', 'ju', 'juan', 'jue', 'jun', 'ka', 'kai', 'kal',
'kan', 'kang', 'kao', 'ke', 'keg', 'kei', 'kem', 'ken', 'keng', 'keo',
'keol', 'keop', 'keos', 'keum', 'ki', 'kong', 'kos', 'kou', 'ku', 'kua',
'kuai', 'kuan', 'kuang', 'kui', 'kun', 'kuo', 'kweok', 'kwi', 'la', 'lai',
'lan', 'lang', 'lao', 'le', 'lei', 'lem', 'len', 'leng', 'li', 'lia',
'lian', 'liang', 'liao', 'lie', 'lin', 'ling', 'liu', 'liwa', 'lo', 'long',
'lou', 'lu', 'luan', 'lue', 'lun', 'luo', 'lv', 'm', 'ma', 'mai',
'man', 'mang', 'mangmi', 'mao', 'mas', 'me', 'mei', 'men', 'meng', 'meo',
'mi', 'mian', 'miao', 'mie', 'min', 'ming', 'miu', 'mo', 'mol', 'mou',
'mu', 'myeo', 'myeon', 'myeong', 'n', 'na', 'nai', 'nan', 'nang', 'nao',
'ne', 'nei', 'nem', 'nen', 'neng', 'neus', 'ng', 'ngag', 'ngai', 'ngam',
'ni', 'nian', 'niang', 'niao', 'nie', 'nin', 'ning', 'niu', 'nong', 'nou',
'nu', 'nuan', 'nue', 'nun', 'nung', 'nuo', 'nv', 'nve', 'o', 'oes',
'ol', 'on', 'ou', 'pa', 'pai', 'pak', 'pan', 'pang', 'pao', 'pei',
'pen', 'peng', 'peol', 'phas', 'phdeng', 'phoi', 'phos', 'pi', 'pian', 'piao',
'pie', 'pin', 'ping', 'po', 'pou', 'ppun', 'pu', 'q', 'qi', 'qia',
'qian', 'qiang', 'qianke', 'qianwa', 'qiao', 'qie', 'qin', 'qing', 'qiong', 'qiu',
'qu', 'quan', 'que', 'qun', 'ra', 'ram', 'ran', 'rang', 'rao', 're',
'ren', 'reng', 'ri', 'rong', 'rou', 'ru', 'rua', 'ruan', 'rui', 'run',
'ruo', 'sa', 'saeng', 'sai', 'sal', 'san', 'sang', 'sao', 'se', 'sed',
'sei', 'sen', 'seng', 'seo', 'seon', 'sha', 'shai', 'shan', 'shang', 'shao',
'she', 'shei', 'shen', 'sheng', 'shi', 'shike', 'shiwa', 'shou', 'shu', 'shua',
'shuai', 'shuan', 'shuang', 'shui', 'shun', 'shuo', 'shw', 'si', 'so', 'sol',
'song', 'sou', 'su', 'suan', 'sui', 'sun', 'suo', 'ta', 'tae', 'tai',
'tan', 'tang', 'tao', 'tap', 'te', 'tei', 'teng', 'teo', 'teul', 'teun',
'ti', 'tian', 'tiao', 'tie', 'ting', 'tiu', 'tol', 'ton', 'tong', 'tou',
'tu', 'tuan', 'tui', 'tun', 'tuo', 'uu', 'wa', 'wai', 'wan', 'wang',
'wei', 'wen', 'weng', 'wie', 'wo', 'wu', 'xi', 'xia', 'xian', 'xiang',
'xiao', 'xie', 'xin', 'xing', 'xiong', 'xiu', 'xu', 'xuan', 'xue', 'xun',
'ya', 'yan', 'yang', 'yao', 'ye', 'yen', 'yi', 'yin', 'ying', 'yo',
'yong', 'you', 'yu', 'yuan', 'yue', 'yug', 'yun', 'za', 'zad', 'zai',
'zan', 'zang', 'zao', 'ze', 'zei', 'zen', 'zeng', 'zha', 'zhai', 'zhan',
'zhang', 'zhao', 'zhe', 'zhei', 'zhen', 'zheng', 'zhi', 'zhong', 'zhou', 'zhu',
'zhua', 'zhuai', 'zhuan', 'zhuang', 'zhui', 'zhun', 'zhuo', 'zi', 'zo', 'zong',
'zou', 'zu', 'zuan', 'zui', 'zun', 'zuo'
);
BEGIN
IF (p_PY_Index>0) AND (p_PY_Index<527) THEN
RETURN INITCAP(v_PY_List(p_PY_Index));
ELSE
RETURN '';
END IF;
END GetHzPY_by_index; FUNCTION get_greece_alphabet_py(p_Index NUMBER)
RETURN NUMBER IS
v_greece_alphabet_list TGREECE_ALPHABET_LIST := TGREECE_ALPHABET_LIST(
'a','b','g','d','e','z','e','th','i','k','l','m','n','x','o','p','r',
's','t','u','ph','kh','ps','o'
);
BEGIN
IF (p_Index>0) AND (p_Index<95) THEN
RETURN v_greece_alphabet_list(p_Index);
ELSE
RETURN '';
END IF;
end get_greece_alphabet_py; FUNCTION get_roma_num_py(p_Index NUMBER)
RETURN NUMBER IS
v_rom_num_list TROMA_NUM_LIST := TROMA_NUM_LIST(
'1','2','3','4','5','6','7','8','9','10','','','','','','',
'1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20',
'1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20',
'1','2','3','4','5','6','7','8','9','10','','',
'1','2','3','4','5','6','7','8','9','10','','',
'1','2','3','4','5','6','7','8','9','10','11','12','',''
);
BEGIN
IF (p_Index>0) AND (p_Index<95) THEN
RETURN v_rom_num_list(p_Index);
ELSE
RETURN '';
END IF;
end get_roma_num_py; FUNCTION get_py_index_01(p_Index1 NUMBER, p_Index NUMBER)
RETURN NUMBER IS
v_list01 TPYIndex_list := TPYIndex_list(
TPYIndex_191_list(483,389,458,273,262, 50,395, 88,350,232,482, 24,182,172,178,213, 42,517,144,180,
117,477,477,456,182,157,508,161,394,478,471,121,182,146,158, 90,395,279,190,201,
437,269,311, 29,469,472,326,386,276,341,410,103, 65, 39,507,141,122,243,235,477,
186,249,507, 0,483,408,415,128,471,499,471, 68,475,460,180,475,482,500,231, 97,
451,172,355,456, 7, 24,115,423,102,459,503,159,147, 25, 44,501,389,361,108,263,
341,455,474,112, 55,450, 81,508,320,483, 84, 96,456,477,463,172, 3,478,328,393,
117,422,522,487,184,459,470,463,494,459,301,291,462,467,509,522, 17,328,477,408,
477,506,147,250,510, 26,351, 18,502, 59,473,500, 18,459,351,395, 13,166,151,460,
125,107,266, 24,155,168,141,352, 59,464,393,445,145,220,477,140,478,261,467, 4,
242,106,245, 40, 48,470,509,366,175,408, 69),
TPYIndex_191_list(418,297,179,181,435,505,526, 50,247,184,399,435,393,445, 25,278,461,443,483,457,
467,140,209,456,477,117,232,167,479,459,376,320,457,262,458,466, 81,184,507,220,
408,168,461,175, 21,431,110,471, 15,483,463,161,506,507, 24,182,474,522,232,449,
234, 55,520, 0,125,432,399,258,421,515,464,333,339,122,232,415,346,109,507,520,
245,411,236,167, 89,518, 16,456,184,277, 28,175,475,386,346,479, 47,341,368,508,
57,451,483, 24,431,472,112,422,455, 98, 45,394,191, 81, 40, 15,498,165,474,500,
521,472,482,467,498, 59,117,117,507,262,172,477,462,470,408, 92,499,505,440, 15,
491,346,451,412,507,413,458,484,364,301,487,176,249, 83,422,149,178,457,388,341,
353, 46, 51,376, 15,461,481,474,421,417,473,107, 24,460,490,136,376,225,481,493,
520,322,411,513,483,499,522,389, 55,180,147),
TPYIndex_191_list(501,348,478, 81,462,241, 15,330,179,231,242,251,341,459,421,479, 89,525,388,345,
181,443,525,337,223, 43,140,339,427,513,451,172, 25,166, 57,434,388,474,111,459,
483, 98,235, 25,136,459,459,265,475,179,340,345,112,509, 3,374,477,187,299,421,
477, 71,211, 0,175, 51,177,386,490, 30, 23, 4,420, 72, 41,221,477,179,341,259,
456,297,349,291, 43,234,247,213, 13,483, 21,491,507,408,482,149,348,347,229,427,
451,240, 51, 42,460,433,462,229,246,491,306,422,472,246,279,491,465,369,369,441,
43,291,291,179,472,395,396,343, 0,150,393, 90, 9,134,165,456,369,232,483,147,
432,336,172,477,254,357,472,254,498,181,137,181,254,509,135,467,482,191,477,261,
395,259,184,208,265,117,462,261,420,123,161,317,117,265,340,175,412,257,441,136,
180,348, 89,122,478, 3,229, 31,266,516, 65),
TPYIndex_191_list(408, 97,179,235,457, 91,108,108,184, 51,506,112,271,507,112,112,189,122,333,211,
147,361, 55,172,341, 66,172, 70,449,186,229,117,351, 84,265,236,508, 22,178,178,
388, 42,128, 55,214, 97,106,178, 59,180, 90,246,494,484, 67,194,386, 55, 67,229,
110, 42,339, 0, 55,518,123,337, 97,348,517,175,172,472,168, 97,507,456,137,394,
175,498,189,342, 54, 42,513,242,229,322,388,208,137,162,498,517,231,184,237,141,
177,141,175,175,439,172,175,175,507, 42,523,268,229,510,471,180,199,462,507,477,
510,268,223,185,208,473,447,461,270,213,178,234,194,180,124,265, 48,222,481,194,
185,348,242, 26,220,189,262, 89,467,456,477,470,473,394,233,242,330,395,172,342,
177,352,460,477,469,108,185,439,184, 70,250,470,470,247,229, 45,460,352,487,182,
13,253, 18,121,121,477,322,184,474,125, 98),
TPYIndex_191_list(133, 68,182,133,280,182,477,176,192,161,351,108,346,492,213,161,483,141,166, 70,
214,231,231,414, 91,182,351,457,194,472,351,470,292,522,395,457,449,449,462,388,
172,401,213,457,462,357,473,349,390, 48,467,457,214,172, 98,457,376,472,503,147,
471, 81,499, 0,318, 2,346,471,507,252,431,391,435,524,110,494,484,229, 83,347,
6,141,472,229, 43,341,229,472,472,484,159,262,365,351,204,225, 91,513,393,393,
393,477, 69,398,186, 7,371,395,517,458,461,172,487,369, 61,137,350, 48, 93,159,
264,252,468,518, 97,475,313,168,477, 50,347,462,335,162,159,483,306,469,366,313,
124,187,247,125,452,339,456,177,487, 48,394,444,452, 98,395,185,321,452,270,357,
81,395,509,434,457,477,339,333,518,467,477,461,471,351,459,445,335, 22,117,473,
168,420, 68,447,526, 26,418,459,168,339,106),
TPYIndex_191_list( 98,507,510,470,461,210,395,433,275,468,448,223,439,465,482,261,292,464,336,149,
487,240,335,252,522,151,459,223,334,232, 7,264,247,415,117,147,485,482,136,136,
15,147,477,341,441,472,449,229,350, 45,493,471, 90,339, 81,347,255,159,428,203,
232,222,386, 0,519,455,478,339,447,342, 4,494,292,483,432,220,457, 3,300,517,
499,488,461,460,516,456,452,431,136,339,339, 70,475,518,441, 65,151,471,339,503,
232,459,479,137,494,143,246,290, 81,352,445,130,422, 4, 70,483,503,509, 41,448,
483,491,474,262,161,487,164,484,172,508,451,386,467,165,498,472,232,483,377,189,
345,472,388,321,416,480,451,479,327, 15,131,493,168,431,474,461,342,379,481,159,
462,249, 40,145,366,447,172,318,456,459,518,242,447,174,417, 60,374,132,276,342,
18, 6,231,524,510,268,421,177, 49,177,189),
TPYIndex_191_list(421,393, 3,461,241,461,161,166,143,467,459,494, 43,334, 73,249,161,119,422,475,
374,177,461,162,250,357,461,461,172,214,461,149,248,345,467,445,421,470,456,525,
108,189,166, 30, 55,488, 70,483,444,457,339,149,231,467,166,478,470,474,408,472,
479, 68,500, 0,517,299,485,462,345,484, 3,481,451,483,321, 72,463, 96, 71,463,
328,478,524,297, 81,221,418,455,458,475, 97,466,509,499,179, 43,470,256,507,242,
166,319,482,474,478,480,257,159,503,229,237,145,279,268,472,229,242,240,268, 70,
46,332,328,460,256,457, 97,209,472, 42,479, 86,219,418,461, 58,164,168,513,503,
461,498,229, 42, 41,229,477,246,491,413,156,496,175,488,510,221,295,356,239,166,
478,296,442,192,484,181,329,487, 61,166, 98,143,439,441,143,354,363,143,420,143,
478,167,147,245,143, 56,451,484,352,209,337),
TPYIndex_191_list(484,484,471,442,441,441,442,244,166,477,243,243,471,441,435,337,242,211,471,516,
413,413,517, 71,340,458,388,295,268,173,507,470,477,347,257,364,444,111, 18,464,
221,180,172, 81,464,317,422,351,517,137,420,181,473,115,242,350,135,469, 7,236,
510,117,161, 0,507, 6, 69,319,265,172,151,247, 59, 48,478,160, 94,502,117,140,
474, 97,141, 40,473,462,398, 24,159, 68,188, 71,148, 4,464,459, 12,335, 15,477,
478,147,467,515,347,112,109,353,481,187,458, 81,222,185,347,503,234,162, 26,181,
475, 81,471,352,415,506,449,184,245,506,206,389, 89,421, 28,440, 17,459, 97,477,
507,516,339,184,291,194,215,291,175,123,483,471,136,228,109,471,215, 4,393,280,
441, 47,164, 18,231,455,513, 13,483,456,178,368,475,128,520,483,165, 98,474,117,
172,257,389,445,478,112,508,178,179,155,123),
TPYIndex_191_list( 57,459,333,225,464,165, 92,449,468,457,172,211,479,481,189,413,395,261,453, 47,
441,353,508,229,322, 12,492, 94,505,456,506,470,505, 3,133,472,191,452,462,237,
145,222,389,322, 17, 46,242,242,313,341,257,268,513,403,241, 21, 33,507,501,191,
83, 46,517, 0,172,143,342,347, 81, 65,472,418,497,341,451,515,345,388,388,110,
337,443,442,108,353, 96,525, 81,394,166, 97,421, 79,456,111,165,421, 68,475,510,
175,483,342,345,198,477,328, 83,176,475,469,421,221,184,163, 71,358,341,470,459,
457, 3,471, 72,368,179,247,213,242,472,421,451,166,240,240,369,229,235, 42,470,
472,225, 7,449,376,514,477,250,510,514,161,215,161,467,215,398,252, 96,398,477,
479,176,318,499, 20,415,354,236, 67,468,462,280,458,484,449,507,348,310,135,339,
259,259, 46,494,186,124,423,420,472, 18,169),
TPYIndex_191_list(487,462, 7,100,431,319,185,462, 83,473,164,189,498, 16,165,110, 84,470,199, 6,
453,420,456, 6,176,231, 97,487,176,395,111,168, 18,243, 97,435,341,182,302, 40,
459,108,172,159, 70,482,180,178,452,508,314,199,508,487,328, 48,485,514,472,278,
463,111,112, 0,484, 91, 25,517,502,291,484,440,468,507, 98,268, 18,393, 98,151,
467,107,506,265, 11,117,236,518,357,459,473,251,518,184,361, 89,172,121,460,168,
185,135,175,175,292,507,505,459,155,140,470,210,472,266,234,320,471,482,472,459,
431,447,352,411,159,459,390,394,462,252,117,456,194,220, 63,435,464,278,483,334,
415,507,147,514,333,443,459,483,472,456,457,472,483,408,229,184,515,339,459,517,
89,242, 98, 98,247,262, 61,335,184, 28,236,461,399,339,166,117,455,455,421,110,
110,432,291,352,180,180,341, 83,464,161,449)
);
BEGIN
IF (p_Index>0) AND (p_Index<192) THEN
RETURN v_list01(p_Index1)(p_Index);
ELSE
RETURN 0;
END IF;
end get_py_index_01; FUNCTION get_py_index_02(p_Index1 NUMBER, p_Index NUMBER)
RETURN NUMBER IS
v_list02 TPYIndex_list := TPYIndex_list(
TPYIndex_191_list(220,478,509,280,117,245, 4,215,478,471,184,229, 83,459,162,162,473,474,278,371,
173,483,483,451,431,365,257, 70,368,348,166,455,341, 57,263,117,178, 92,477,508,
165,262,472,479,468,178,451,506,350,507,462,445,231,254,357,408,329,451,447, 63,
161,346, 13, 0,467,483,141,521,474,484,364,366,237,257,317,487,249,214,393,505,
484,417,364,266,479,413,294,423,318,222,280, 13,328,477,483,468,484,477,192,481,
291,524,179,513,494,278,223,503,161,161, 6,368,249,331,136,456,345,445,500,263,
459,459,268,233,231,162,141, 79,507,467,477,162,457,214,474,472, 42,177,257,117,
108,472,477,152,177,117,395,415,342,231,468,463,294, 89,477, 30, 3,293,297,249,
433, 50,179, 59,483,332,364,366,291,472,420,479,341,485,262, 18,393,464,291, 91,
237,484,221,472,236,177,358,221,459,479,403),
TPYIndex_191_list(462,352,261,229,243,472,510,221,186,518,463,408,420,482,513,470,264, 61,449,471,
477,518,229,469, 25,277,295,479,243,364,349,441,365,474,477,180,516,510,159,395,
477,433,457, 47,354,133,461,498,395,393,165,261,208, 28,491,484,350,151,505,175,
297, 24,164, 0,347,395,297,179,297,507,483, 13,212,297,247,347,161,507,297,393,
451,462,212,166,187,477,477, 13,347,240, 13,112,247, 94,334,513,334,194,473,513,
470,510, 94, 72,178,261,261,399,389,268,233,459,459,215,482,294,318,450,450,450,
474, 97,214,508,122,136,512,122,122,457, 18,178,432, 84,395,505,462,291,457,446,
251,241,333,462,110,462,247, 35,462,184,186,233,186,510,462,334,447,459,229,472,
72,166,240,361,456,147,393, 51,476,485, 11,474, 5,456,178,172,111,449,341,339,
178,526,526,473,184,123,469,334,229,433,522),
TPYIndex_191_list(117,445,328, 6,213,351,334,433,236, 48,333, 37, 12,439,469, 20,151,194,246, 98,
295, 85,242,100,106,121,352,477,271,395, 4,451,164,261,229,172,439,451,482,136,
234,474,177, 98,475, 26,354,112,280,229,482,459,364, 72,393, 47,441,128,124,458,
478,483,279, 0,191,472,353, 49,418,235,162,184,220,265,215,215,522,136,471,123,
245,245,236, 97,506,478, 89,147,506,451,328,178,522,209, 89,478,518,494,165,483,
473,112,350,473,431,477,507,395, 98,510,500,247,472,257,147,172,164,435,456,483,
520,221,194,472,472,451,520, 40,417,194,347,431,441, 94,457,453, 31,422,479,178,
189,237,456,345, 17, 83,341,481,295, 67,395,371,411,520,176,233,192, 42, 85, 34,
87,441,241,500,500, 6, 32,351,342,524,524, 72, 72,457,483,328,240,460,506, 25,
347,177,472,223,500,233,233,347, 97,525,345),
TPYIndex_191_list(186,474,177,474,186,500,477,469,280,475,475,477,295,472,172,462,194,457, 81, 6,
524,451,364, 72,236,178,483,485,478,366,178,234,457,240,240,479,457,184, 42,479,
451,472,280,352, 44, 64,243, 83, 83,295,472,472,472,280,472,211,165,464, 44,234,
200,337,337, 0,350,507,502,477,179,416,352,324,334,488, 87,295,111,314,507,161,
70, 69,447,117,268,477,477,333,340,185,366,401,404,345,505,395,354, 69,141,333,
501,376,449, 69,386,339, 91,160,506,467,451,477, 12,333, 85,133,317,423,261,173,
427,166,508,393, 21,143,494,271, 12,180, 42,507,456, 18, 18,501,261,345, 42,111,
259, 12, 72,264, 51,178,459,221,175, 24,122,172,435,494,140,256,347,444,471,463,
178,514,471, 59,439,477,507,433,507,461,441,141,209,259,482, 26, 24, 47,220,172,
411,399,348,483,263,412,494,460,110,182, 98),
TPYIndex_191_list(451,237,458,412,507, 26,348,182,182,241,478,457,242,477, 51,441,408,463,263, 43,
456,110,213,207,211, 18,379,235,233,247,172,479,459,435,481,229,435,472, 81,334,
166,277,166,111,351,472,492,477,106,376,106,395, 84,161,456,443,176, 7,393,501,
423,117, 81, 0, 44,505,477,352,390,484,180, 84,501,176,342,322, 18,391,421,175,
125,107, 18,208,175, 22,461,421,143,342,159,291,143,449,186,172,242,166,166,477,
477,477,485,485,452,472,483, 48, 84,481,330, 48,517,477,172,508,450, 81,236,117,
450,457,450,506,507,180, 61,507, 61,446,172,507,520,509,220,462,178,175,431,458,
329,117,451,318,457,506,330,431, 73,507, 22,508, 45,474,166,257,240,460, 13,351,
224,361,435,121,361,147,477,420,457,108,479,452,452,456,172,457,178,449, 61,483,
395, 65,420,516,347,167,465,450,459,192,184),
TPYIndex_191_list(477, 13,265,320,208, 11,298,500,161,522,482, 81,443,482,117,457, 18,482,468, 61,
24,165,469,328,399,457,421,481,268,205,395,457,223,155,213,270,507,462,474, 85,
149,451,467,461,408,210,350,166, 48,477,465,138,235, 48,389,513,485,322, 73,166,
461,252,481, 0,484,328,485,483,483,194,503,235,177,346,431, 26,341,457,258,477,
155, 47,456,229,232, 61,477,229,280, 98,456, 61, 73, 43,258,229,139,139,339,206,
432,245,457,191,142,291, 96,143,500,484,179,172,235,483,151,352,421,431,295, 58,
258,463,456,417,520,175,481, 73,280,487,434, 57,349, 33, 20,167,520,431, 15,468,
451,125,451, 18,468,164,262,481,339,422,478,463,254,340,194, 3,346,472,368,520,
408,479,353,159,487,413,339,474,411,165,172,136,184, 55,291,462,189,506,481, 32,
470,393, 25,457,462,167,481,473,229,378,423),
TPYIndex_191_list(478,467,420,487,266,133, 61,330,271,143, 48, 30, 30, 30, 65,265,501,439, 6,403,
139,353,493,182,231,313,411,347,478,247,389,442,251,459,391,348, 81,507,247,185,
339,339,483,333,233,411,482, 49,507,439, 47,339,351,322, 15,349,177, 48,231,333,
214,166,506, 0,478,478,457,457, 70,421, 97,444,413,186, 33,461,108,111,223,223,
459,265,233,456, 30,186, 63,459,421,394,328,477,459,299, 70,421,180,411,177,451,
468,347,347,184,378,198,479,477,235,379,187,163, 3,475,216,458, 48,483,478, 69,
259,291,259, 94,339,268,459,258, 50,507,306, 51,473, 25,507,213,213,482,117,237,
264, 47,166, 42,221,163,468,358, 42,172,184,164,391,231,278,268,422,186,514,514,
485,125,175, 89, 85, 28,173,507,214,500,342,125,175,483,482,457,500,457,457,351,
161,161, 98,477,431,254, 83,389,477,477,472),
TPYIndex_191_list(350,229,108,366,490,501,485,483,456,147,393,498,477,339,456, 78,361,457,347,173,
483, 6,503,507,507, 78,472,450, 20,184,452,161,485,347,393,506,487,449,369,335,
335, 7,298,494,487, 24,507,278,337,474,505,498,473,340,291,475, 48,328,173,257,
351, 51,471, 0,500,319,276,341,445, 8,507,184,216,340,341,154,296,133,525,477,
462,379,166, 8,507,216, 97, 97,299,505,151,177, 89,366,234,498,242,391,186,234,
184,471,459,483,472, 25,128,431, 47,417,341,257,299,184,322,175,472,415,462,498,
112,209,350,168,441,335,494,412,483,517,449,507,525,512,499,242,412,472, 12,451,
449,347,391,265,258,117, 72,455,352,485,520,432,441, 16,455,526,458,339, 47,378,
245,348,123, 81,167,339,399,449,236,471,506,232,137,477,467,472,506, 28, 24,431,
521,198,398,178,266,128,259,378,322,306,175),
TPYIndex_191_list(506,482,341,472,278,468,328,451,374,295,395,520,505,470,481, 20,473,164,472,523,
467,340,172,431,219,219, 46,182,441,167,127, 89,461,462,341,498, 15,474,451, 77,
456,520,127,135,347,364,353,521,416,416,364,322,194,474, 72,507,306,462,350,459,
179,264,477, 0, 94,388,418,498,334,229,423,209,507,447,458,452,342,432,505, 98,
306,352,498,456,503,192,364,387,416,417,233, 49, 55,143,322,507,339,412,231, 47,
48,139,242,241,520,457,161,511,342,422,162,507,342,141,479,345,507,295,251, 42,
313, 51,413,513,177,388,341,330,176,474,135,341,172,331,223, 96,459,371,141,496,
477,470, 47,461,159,140,418,292,235,506,451,193,172, 32,463,421,107, 45,186,461,
16,268,517,451,337,347, 96,162,177,418,474,511,231,481,279,242,517,499,337, 58,
457, 71,379,348,178,211,388,462,498, 6,184),
TPYIndex_191_list(475, 98,259,261,172,420, 72,221,184,475,366,475,475,291,455,178, 23,297,125,507,
507,422,268,175,462,234,421, 8,412,242,485,359,507,473,225,372,399, 64,292,459,
320,229,220,164,479,246,240,341,341,341,221,459,479,257,388,479, 64,462,503,246,
257,268, 48, 0,523,243,421,387, 83,447,422,177,221,246,141,141,339,470,193,477,
147, 11,334, 83,208,265,456,151, 33,398,143,467,177, 46,505, 97,483, 8,467, 97,
295, 83,353,477,194,472,339,440,461, 97,473,458,265,510, 3, 81,505,399,233,351,
465,477,177,388,177,517,477,231, 18,420,461,461,469,339,339,186,499,446, 11,483,
221,451,394,173,173,483,177,440, 90,507,342,351,500,517,517,517,347,235,517, 51,
92,510,178,148,320,482,272,339,328,237,117,109,180,502,477,390,175,105,507,108,
330,108,500,211,415,483,172,172,168,462,433)
);
BEGIN
IF (p_Index>0) AND (p_Index<192) THEN
RETURN v_list02(p_Index1)(p_Index);
ELSE
RETURN 0;
END IF;
end get_py_index_02; FUNCTION get_py_index_03(p_Index1 NUMBER, p_Index NUMBER)
RETURN NUMBER IS
v_list03 TPYIndex_list := TPYIndex_list(
TPYIndex_191_list(479, 81,467, 42,473,395,265,265,516, 57,456, 15, 11,178,394,161,109,181,468,111,
347,161,472,494,109,393,184,473,109,468,334,505,236,149,268, 20,467,167,520,458,
110,477,452, 89, 3, 24, 5,240,213,433,395,165,468,214,467,177,179,507,439,159,
121,460,147, 0,187,459,215,509,457,394,503,503,147,149,449,432,517,524,509,388,
291,457,339,506,477,472,449,235, 43,450,461,110,468,477,487,166,467,265,475,479,
399,451,348,254,278,221,473, 57,474,417,337,177,189,149,453, 43,339,149,472,229,
172,258,491,462,149,268, 61,291,501,166,147,468, 54,233,421,180,331,235,457,477,
178,165, 69,475,475,229,421,439,461,110,393,502,149,477,460,464,388,177, 13,180,
472, 3,475,366,259,229, 46,213, 85,446,474,168,247,364,240,246,243,387,422,472,
510,485,477,161,399, 32,394,497,341,467,216),
TPYIndex_191_list(478,346,111,328,111,236,209,446,307,433,222,524,266,450,444,339,479,520,450,439,
222,223,240,332,399,429,361, 7, 97,433,229,350,182, 18,505, 59,366,341,483,456,
470,108,518,361,503, 97,252, 48,477,125,133,507,176,388,449,182,252,507,484,110,
89,459, 57, 0,399,162,463,298, 50,411,485,179,172,254,328, 5,111,477,117,278,
161,475,510,463,474, 98,502,487,524,394, 97,242,411,278,505,420,457,138,117,268,
477,475,475,395,295, 18,477,291,219,151,317,108,508, 69, 59,479,117,399,390,411,
393,357,481,507,522, 70,136,337, 6,117,117,526, 22,498,408,510,320,395,138, 40,
474,182,237,257,229,364,493,373,481,470,339,505,477,460,505,229,379,191, 24,361,
8,361, 24,518, 50,477, 59,525,524,106,106,483,107,133,500,229,478,507,395,117,
366,477,209,349,377,469, 97, 56,483,491,446),
TPYIndex_191_list(479,178,237,500,470,372,505, 15,479,216,180,334, 16,369,457,222,237,112,339,452,
187,147,478,350,482,240,322,514, 81,469,441,493,482, 18, 81,147,507,361, 15,459,
164,449,306,173,433,172,461,247,212, 34,111,411,408, 90,347,479,184,215,517, 42,
451,180,229, 0, 24,458,115,423,507,220,231,517,229,339, 24,245,411,341,339, 28,
42,503,110,320,335,167, 47,493,234,483,483,136,142, 89,123,450, 67,108, 47,500,
339,484,472,483,352,477,393,457,517,413,220,521,521,111, 46,348,295,449,242,149,
346,509,184,184, 47,526,342,471,328,517,518, 23,322, 87, 51, 43,258,162,175,141,
457, 72,141, 83,507,352,274,117,128,322,388,477,393, 97,117,451,451,173,520,175,
477,457,472,472,500,483,151,455,329, 18,474,210,467,371,473,219,472, 16,166,214,
178,214,408,112,445,507,271,254,209,161,435),
TPYIndex_191_list(483,482,411,484,473,505,329,475,340,475,405,483,451,257,431,172,178,365,165,224,
352,460,395,421,487,393, 51,328,173,477,505,117,306,261,136,179,418,474,462,484,
518,266,413,173,474,178,165,147,341,249,484,364,395,507,452,435,364,422,499,408,
394,194,457, 0,136,339,193,416,317,423,125, 57,505,300,172,178,342,459,257,467,
123,517,445,345,473, 83,173,507, 72,240,377,457,172,231,166,481,341,143,121,121,
442,162,393,524,322,482,176,161,164,141,477,477,124,192,141,141,449,507,514,487,
222, 46,520,229,466,348,403,439,139,494,413,225,242,232,261,247,177,413,194, 21,
242,233,503,498,399,251,294,473,433,322,510,386,352,175, 61,172,472,469,507,470,
507,524, 61,337,399,162,214,505,388,457, 57, 83,110,268,456,359,235,237,345,459,
370,108,500,223,487,405,443, 47,422,259,461),
TPYIndex_191_list(186,463,166,172,306,445,297,369,439,497,111,349,472,155,347,136,237,223,124,457,
394,518,376,172, 90,180,175, 51, 68,399,176,235,280,478,166,388,524,468, 47,122,
184,524,477,337,112,166, 71,172,415,333, 47, 51,511,166,172,178,173,499,175,342,
72,477, 21, 0,411,391,229,478,423,420,262,339,442, 24,168,172,341,291,297,477,
124,191,478,368,348,472,339,261,502,141, 57,172,214,334, 79, 51,125,262,482,507,
165,341,225,234,372,242,229, 64,247,264,166,313,247,507,124, 91,484,485,110,517,
412,231,176, 51,348,510,247,472,229,510,347,178, 98,413,163,295,483,240,220,177,
459,141,184,466,236,479,388,478,482,479,460,299, 25,500,231,184,403,391,524, 61,
352,351, 31,183,483,246,229,523,243,422,186,472,221,221,510,246,229, 7,279,483,
236,140,477,459,467, 44,457,339,194,478,186),
TPYIndex_191_list(457,467,458,214,222,463,412,462,467, 53,478,341,463,341, 54,137,478,483,461,475,
473,421,354,313,161,461,164,467,321,477,461,467,446,231, 51,477, 98,483, 58,164,
26, 26,184,341,507,379, 48,379,508,417,415,229,494,483,229,214, 98,503,452,268,
474,394,467, 0,186,340,350,413,348,477,475,475, 30,258, 85,505,487,452, 50,431,
179,389,478, 84,182,214, 64, 70, 91,176,231, 23, 91,175,175,510,394,477,462,353,
345,474,470,166,353,339,351,166, 92,477,461,139,257, 3,178,328, 42,446,446,328,
234,173,374,271,445,470,106,364,459,184,350,306,446,320,184, 97, 18,376,254,415,
399,445,194,418,376,399,271,254,439,364,500,378,500,259,242, 85,186,339,473,282,
23,393,457,457,348,471, 89,473,487,506, 24, 71,404,224,291,108,350,314,494,262,
84,517, 54,449,108, 69,445,252,482,332,341),
TPYIndex_191_list(483,483,441,182,507,507,341,180,180,444,187,159,352, 20,147,508,318,469,165,482,
467,467,487,472, 70,482,161,168,307,268,456, 49,318, 18,507,317,518,488,237,494,
112,257,488,445,505,505,477,107,432,408,213,479,184,477,173,508,166, 16,494,510,
482,136,161, 0,333,518,507,413, 47,408,184,469,394,469,117,172,139, 70,478,509,
475,166,490, 47,451,160,175,408,106,464,117,518,507,478,456,193,446,472,431,270,
225,477,261,352,334,461,477,413,213,346,184,333,465,507,165,266,456,351,477,180,
395,323, 42,179,234,350,451,147,252,482, 25, 90,159,477,506,221,147,229,128,231,
57,159,477,439,223,458, 49,181,415, 47,320,459,393,215,333,147,348,361,441,461,
435, 98,487,229,404,408,225,404, 91,487,155,464,423, 58,501,279,484,445, 89,455,
184,391,232,167,418,346, 73,185,161,143,472),
TPYIndex_191_list(509,322,149, 43,341,109, 48,242,184,229,503,333,432,483,291,242,261,180,236,245,
351,483,393,161,161,484,220,348,341,507,478,334, 16,484,452,371,110,484,194,339,
391,379,339,328,457,484,365,164,175,302,456,435,112,455,431,451,368, 33,151,472,
159,261,254, 0,479,472,348,394,257,490,167,277,141, 48, 98,231,339,339,257,432,
62,451, 30,265,334,467,172,175,112,477,478,395,462,506,421,483, 18,265,395,441,
394,481,184,439,442,350,350,473,240,168,484,278,317,482,352,514,232, 42,472,516,
151,518,258,479,219,112,241,451,458,479,334,179,472,417,484,459,474,259,517, 47,
420,418,447,208,378,498,395,245,249,451,490,456,452,342,494,395, 3,487,478,413,
417,395, 3,317,467,453, 31,264,125,469,165,462, 81,507,479,178,125,415,177,166,
478,494,403, 57,461,483,466,161, 18, 21,507),
TPYIndex_191_list(176,208,393,389,261, 6,242,467,482, 42,108,481,142,258,348,483,172,471, 44,457,
172,242,240,179,143,411,507,121,342,177, 61, 57,513,313,427,475,457,261,422,422,
421,231,447,420,122,322,518,192,322,501,514,467,216,341,472,403,461, 65,431,176,
520,479,159, 0,463,399,164,520,215,467,507,331,399,345,334,473,166,178,456,314,
172,451,461,341,471,457,416, 96,265,370,413,505,520,477,507,449,421,478,462,475,
498,376,152, 18, 42,399,337,235,451,379,379, 47,181,162,280,223, 66,159,147,487,
237,159,117,149,151,459,175,388,457,483,242,297,483,235,394, 71,164,494,462,483,
395,469,236,449,518,481,211, 30,231, 83,475,468,505,251, 70,477,415,328,184,418,
347,517,299,455,347,321,379,386,451, 51,418,411,435,379,510,231,291,457,399,261,
297,479,479,259,179,339,339,524,455,423,478),
TPYIndex_191_list(478, 94, 59,168,348,221,470,194,451, 23,136,341,479, 23,216,110, 31,256,491,451,
334,491,242,229,482,473,242,408,507,479, 91,450,166,462,317,393, 21, 42,268,237,
175,379, 47,136, 23,168,459,242,347,364,229,180,461,479,415,451,448,469,510,403,
220, 94,108, 0,161,220,399,236,479,291,172,231,525,479,235,477,175, 42, 69,358,
175,221,108,403,484,517,112,391,225,221, 61,351,481,341,107,186,472,479,459,491,
243,472,229,261,388,421, 71,177, 42,479,149,510,221,221,279,449,243,470,459,472,
122,472,483,140,461,461,166,159,513,498,462, 48,490,339,508,111,298,452,337,477,
328,189,317,472,318,271,233,140,463,140,140, 20, 68,458,506,510,194,502,117, 7,
462,462,236,517,319,420,473,439,388,451,165,509,474,467,155,352,164,466,466,459,
478,471,509,474,395,451,439,469,490,189,458)
);
BEGIN
IF (p_Index>0) AND (p_Index<192) THEN
RETURN v_list03(p_Index1)(p_Index);
ELSE
RETURN 0;
END IF;
end get_py_index_03; FUNCTION get_py_index_04(p_Index1 NUMBER, p_Index NUMBER)
RETURN NUMBER IS
v_list04 TPYIndex_list := TPYIndex_list(
TPYIndex_191_list(468,506,334,166,140, 45,166, 46,446,234,117,181,462,337,435,517,435,145,222,472,
467, 48,364,161,457,399,168,470,209,485,461,457,514,351, 81,462,339,446,247,472,
184,235,215,167,444,457, 65,456,159,184,117,455, 61,112,333,349,371,477,349,463,
477,345,483, 0,123,328,479,450,394,137,390,446,283,128,451, 46,151,214,508,458,
487,112,231,464,177, 18,479,510,451,442,388,457,468,302, 42,472,181,181,257,451,
498,179,349,365,164,108,350,415,473,234,178,493,137,487,278,395,232,135,422, 44,
487, 25,475,462,457,456,487,151,461,477,487,277,388,349,474,261,341,479,456,133,
472,342, 18, 21,520,242,175,241,322,415,477,439,186,520,161,477,507,451,237,357,
313,360,181,215, 64,497,175,457,457,477,461, 48,165, 70,475,470,472,470,461,187,
79,444,393,345,111,457,483,235,439,390,111),
TPYIndex_191_list(470,221,257,422,477,181,258,180,446,479,477,469,221,420, 30,457,353,520,341,166,
510,236,483,477,462,502,166, 68,305, 24,368,461,470,179, 50,423,474,151,221, 21,
364,234,268,371,247,234, 6,470,213,485,233,229,242,186,233,472,457,462,240,475,
30,358,485, 0,221, 61,439,139,184, 45,261,422,221,510,221,236,483,502,506,319,
47,451,147,186,475,522,261, 55,194,492, 85,342,481,342,317, 44,175, 55,483,498,
262,317, 25, 55,482, 91, 47,298,224,445,361,252,109,123,472,492, 15,408,482,125,
271,499,352,352,518,252,199,341,229,335,123,507, 16,352, 57,173,112,194,184, 51,
457, 15,246,178,249,376,451,254, 96,439,345,457,229, 91,234,315,330, 25,457, 50,
451,359, 50, 7,172, 41,517,151,192,320,160,471,478,164,514,213,508,271,328,184,
477,464,477,236,328,291,474,482,469, 70, 25),
TPYIndex_191_list( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
TPYIndex_191_list( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
TPYIndex_191_list( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 98, 0, 0, 0,171, 0, 0,
0,248,275,309, 0,338, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 0, 0, 0, 98, 0, 0, 0,171, 0, 0, 0,248,275,309, 0,338, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
TPYIndex_191_list( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
TPYIndex_191_list( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
TPYIndex_191_list( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
0, 98, 0, 98, 0,171, 0, 0,248,275, 0,309, 0, 0, 0, 0, 0, 0, 0, 0,
309, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 98, 0, 98, 0,171, 0, 0,
248,275, 0,309, 0, 0, 0, 0, 0, 0, 0, 0,309, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
TPYIndex_191_list( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
TPYIndex_191_list( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
);
BEGIN
IF (p_Index>0) AND (p_Index<192) THEN
RETURN v_list04(p_Index1)(p_Index);
ELSE
RETURN 0;
END IF;
end get_py_index_04; FUNCTION get_py_index_05(p_Index1 NUMBER, p_Index NUMBER)
RETURN NUMBER IS
v_list05 TPYIndex_list := TPYIndex_list(
TPYIndex_191_list( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
TPYIndex_191_list(209,459,468,268,502,178,470,388,418,439,223,517,457,458, 15,507,472,386,147,180,
315,110,461,328,339, 21,478,220,175,342,215,472,520,507,506,471,234, 38,520,118,
112,455,484,388,442,471,462,173,329,482,474,416,334,266,412,249,484, 69,483,395,
149,342,477, 0,505, 31,149,251,176,271, 42, 6,124, 65,111, 18, 18,165,337,235,
483,514,474,457,461,398, 96,177,125,468, 91,166,211,459,459,297, 20, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
TPYIndex_191_list(168,366,259,234,482,180,398,242,418,459,261,358,280,246,459,339,186,474,518,242,
413,350,119,224, 7,159, 81, 54,122,483,339,483, 43,159,456,117,178,471,258, 12,
485,186,487,186,478, 70,332,342,477,122,333,117,468, 62,135,173,390, 59,357,394,
393,477,522, 0,237, 18,505,179,177,175,229,140,459,509,472,466,473,467,413,347,
478,470, 13,460,458,141, 49,467,320,223, 71,479,452, 98,435,431,456, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
TPYIndex_191_list(456, 47,187,257, 15,435,459, 51,147,468,472,468,466,117,457,236,229,179,417,112,
449, 83,332,500,379,265,483,220,265,450,483,432, 51,320, 47, 98, 43, 17,242,352,
84,320,342,517,347,107,179, 91,178,167,483,257, 57,468,431,464, 69,365,265,175,
451,368,164, 0,462, 54,175,513,473,231,352, 92,471,165,237,395,364,417,474,452,
456,505,179,479,249,423,237,229,222,432,342, 67,186,502, 23,441, 43, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
TPYIndex_191_list(215,513, 61,477,339,180,493,350, 6,231,258,478,162,451,456, 79,466,497,470,351,
71,235,233,349,413,141,180,108,179,237,172,166,180, 3,493, 71,177,142,421,211,
164,379,415,432, 51,483,179,242,329,399,524,221,457,518,468,368,455,121,225, 91,
229,507,365, 0,229,491,468,431,141,415,219,240,242,229,221,479,457,460,451,139,
72,491,475, 25,319,507,229,397,460,344, 11,321,109, 70,113, 0,447, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
TPYIndex_191_list(161,477, 10,185, 43, 48,238, 71,259,515,333, 20,509,238, 59,479,339,459,241, 81,
313,513,235,456, 70,453,479,472,432,147, 43,348,393, 42, 42,369,413,393,242,112,
498,117,333, 87,516,259, 18,237,416,237,271,487,117,128,178,117,432,271,424,176,
447,117,278, 0,271,271,172,432,121, 18, 68,507,244,317,477,162,483,483,271,187,
477,237, 85,162, 71,515,176, 47, 43,444,225, 40,237, 85,235,176, 50, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
TPYIndex_191_list(328, 85, 85,346, 70,399,507,277, 18,123,509,458,467, 46,469,339,471, 65, 18,520,
469,507,107,507,110,184,388,295,427,439,178,483,166,421, 48,257,180,461,441,252,
461,414,337, 97,398,477,322,501,139,249,235,172,432,475, 48,328,265, 94,194,471,
63,393,508, 0,507,483,112,473, 46,441,143,452,164,209,478,186,457,139,477, 55,
225,308, 83,501,393, 63,477,520,412,379, 84,241,247,347,117,406,345, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
TPYIndex_191_list(237,223,459,110,421,478,151,459,139,451,299,483,451,481,225,229,399, 70,235,235,
22,172, 48,473,178,506,256,229,168,220,172,468,479,478,481,421, 83,246,243,243,
25,446, 7,107,107,346,172,493,254,314, 59,236,268,172,322,124, 98,147, 18, 50,
341, 3,461, 0,149,165,149,494, 65,149,461,475,149,177, 3,464,165,246,330,151,
177,122,319,350,353,498,136,187,187,509,498,446,502, 91,339,479, 15, 1, 1, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
4, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7,314, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 11,
11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13),
TPYIndex_191_list(502,151,151, 25,449,483,108,117,350, 72,242,500,229,179,467,191,468, 4,247,467,
509, 71, 4,136,229,122,450,339,484,459,463,457,112,265,266,395,487,317,109,257,
459,395,479,506,474,393,168, 68,505,213,467,393,257,268,510,505,395, 85,291,518,
44,109,317, 0,240,439,507, 81,281,266,470,505,473,268,508,268,257,461,147,164,
47,512,185, 98,251,459,457,215,388,432,245,449,228,395,349,234,506, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18,
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,328, 18, 18, 18, 18, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 23, 23,
23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24),
TPYIndex_191_list(229,220,524,185,328,167,242,494,509,483,167,249,458,464,166,142,490, 57,175,257,
160,468,432,467,107,455,141,261,453,208, 71,432,349,268,111,494,501,477, 90,208,
268,405, 61,247, 48,258,141,164,405,457,337,393,233, 45,459,475,469,456,451,175,
475, 3,166, 0,175,502,257, 50,378,297,470,474,485,259,262,332,262,225,213,468,
262,168,242,259,240,352,251,457,422,191,510,347,483,406,517,186,393, 24, 24, 25,
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 25,
26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
28, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 33, 33,
33, 33, 33, 35, 35, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 42,
42, 42, 42, 42, 42, 42, 42, 42, 42, 43, 43)
);
BEGIN
IF (p_Index>0) AND (p_Index<192) THEN
RETURN v_list05(p_Index1)(p_Index);
ELSE
RETURN 0;
END IF;
end get_py_index_05; FUNCTION get_py_index_06(p_Index1 NUMBER, p_Index NUMBER)
RETURN NUMBER IS
v_list06 TPYIndex_list := TPYIndex_list(
TPYIndex_191_list(160,479,509,177,497,485, 7, 87,339,518,456,503,340,342, 70,186,229,117,452, 98,
192,507,178,332, 98,503,415,447,179,268,522,483,246,445, 98,271,510,301,333,236,
337,224, 98,334,481,213,199,352,510,213, 98,340,242,451, 3,478,472,333,223,159,
348,451,345, 0, 36,348,353, 42,222,159,483,461,458,252,246,481, 45, 45,472,386,
215,136, 36,162,242, 46,303,411,517,199,472,515,206, 47,339,520,348, 43, 43, 43,
501, 43, 43, 43, 43, 43, 43, 43, 44, 44, 44, 44, 44, 44, 44, 44, 44, 45, 45, 45,
45, 45, 45, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 47,
47, 47, 47, 47, 47, 47, 47, 47, 48, 48, 48,395, 48, 48, 48, 48, 48, 48, 48, 48,
48, 48, 48, 48, 49, 49, 49, 49, 49, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
50, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51),
TPYIndex_191_list(235,187,317,265,500,151,457,228,478,456,339,245,280,368,472, 87,445,479,194,451,
406,505, 92,458, 71,431,280,432,339, 96,112,353,353,249,133,462, 98,237,431,422,
194,328,451,432,471,339,231,451,487,515,219,316,474,513, 42,339,345,322,237,242,
191, 55, 46, 0,478,225,330,339,510, 65,520, 58,245,172,388,223,497,175,457, 87,
83,317,488,345, 81,229,175,457,501,345,459,483,515,345,194,494,225, 51, 51, 51,
51, 51, 51, 53, 54, 54, 54, 54, 54, 54, 54, 55, 55,514, 55, 55, 55, 56, 56, 56,
56, 56, 57, 57, 57, 57, 57, 57, 57, 58, 44, 59, 59, 59, 59, 59, 59, 59, 59, 59,
59, 59, 59, 61, 61, 61, 61, 61, 61, 62, 63, 63, 63, 63, 64, 64, 64, 65, 65, 65,
65, 65, 65, 65, 65, 66, 66, 66, 67, 67, 67, 67, 67, 67, 68, 68, 68, 68, 68, 68,
69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69),
TPYIndex_191_list(178, 51,475,353, 71,477,328,328,483,332,339,477,194,175,483,368,319, 59, 25,473,
249,463,213,225,225,507,229,246,108,353,319,479,229,240,240,268,403,139,221, 27,
472,362,485,418,249,462,474,507,109, 94,508,446,477,395,482,507,433,117,261,414,
257, 41,247, 0,483,456,510,141,458,507,124,124,404,179,393,121,215, 81,423,136,
139,524,236,242, 72,507, 18, 51,166,482,478,518,168,505,484,456,459, 69, 70, 70,
70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 71, 71, 71, 71, 71, 72, 72,
72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 73, 73, 73, 79, 79, 79, 79, 79, 79, 79,
81, 81, 81, 81, 81, 81, 81, 81,499, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 83,
83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 84, 84, 84, 84, 84,
84, 84, 84,433, 85, 85, 85, 85, 85, 85, 85),
TPYIndex_191_list(473,507,477,257,408, 81, 15,505,481,172,124,422,408,249,418,117,468,339,483,339,
408,421, 70,141,415,229,299,459, 72,229,485,507,491,225,365,462,441,361,518,276,
507,459,292,350,111,254,487,507,180,507,483,209, 11,328,291,229,482,328, 25,236,
292,526,507, 0,184,168,439,507,216,151,478,518,507,361, 91,510,299,337,124,494,
445,215,122,180,431,441,471,245,242,136,526,516, 12,339,507,215,228, 87, 87, 87,
87, 87, 87, 87, 87, 87, 88, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 90, 90, 90,
90, 90, 90, 90, 90, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 92,
92, 92, 92, 92, 92, 94, 94, 94, 94, 96, 96, 96, 96, 96,444, 96, 96, 96, 97, 97,
97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
98, 98, 98,100,106,106,106,106,106,106,106),
TPYIndex_191_list(322,235,524,483,413,446,477,457, 20,172,117,328,306,178,508,520,467, 47, 72,459,
518,483,467,507,193,136,364,415,364,172,192,388,261,507,172,242,413,172,479,452,
350,217,477,165,346,172,461,337,177,517,508,524,247,415,299,379,166,358,306,483,
332,518,443, 0,452, 47,168,213,247,319,379,517,229,491,471,483,393,180,474,223,
474, 13, 24,447,510,319, 84,456,447, 55,474,461, 47,208, 70,517,467,106,107,107,
107,107,107,107,107,107,108,108,108,108,108,108,108,108,108,108,108,108,108,108,
108,108,108,109,109,109,109,109,109,109,109,109,109,109,110,110,110,110,110,110,
110,110,110,110,110,110,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
111,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,115,116,117,117,
117,117,117,117,117,117,117,117,117,117,117),
TPYIndex_191_list(413,139,517,455,447,475,349,474,474,433, 44,432, 84,241,233,457,456,214, 55,502,
212,212, 47, 65,233,493, 64,345,349, 91,493,240,346, 51,395,117,341, 51,159,339,
149,394,111,263,351,510,236,285, 24, 8,408,159,505, 84,477,399,180,351,333,229,
513, 35, 79, 0, 66,448,180,191,180,224,322, 48,252,510,449,177,414,347,471,515,
484,148,179,328,477, 89,388,458,510,276,136,346,265, 13,388,320,236,117,117,117,
117,117,117,117,117,117,117,117,337,117,117,117,117,117,117,117,117,117,117,117,
117,117,117,117,117,117,117,117,117,119,119,121,121,121,121,121,121,122,122,122,
122,122,122,122,122,122,122,122,123,123,123,123,123,123,123,123,123,124,124,124,
124,124,124,124,124,124,124,125,125,125,125,125,125,125,125,125,125,125,144,125,
125,125,125,125,126,127,127,128,128,128,128),
TPYIndex_191_list(301,117,108,122,108,395,254,461,349,265,246,141,351, 48,478,474, 18,216,177,487,
366,172,148,508,220, 71, 33,117,441,229,222,184,139,459,147,481,458,507, 47,414,
510,526,435,173,124,122,213,487,309,461,337,220,521,315,328,125,420,138,483,175,
502,161,506, 0,498,509,242,235,354,117,498,136,341,187,515, 33,522, 25,468, 20,
416,459,333,464,161,477,485, 57,247,456, 89,461,172,178,464,257,108,128,128,128,
133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,135,135,135,135,135,
135,135,135,135,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
136,136,137,137,137,137,137,137,138,138,138,139,139,139,139,139,139,139,139,139,
139,139,140,140,140,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
141,142,142,142,143,143,143,143,143,143,144),
TPYIndex_191_list( 92,112,510,159,346,350,263,341,136,395,487,151,422,485, 50,371,506,295,341,461,
240,322, 91,517, 51,395,510,342,240,175, 26,166, 18,510, 61,472,491,523,328,330,
483,513,499,387,143,477,161, 42,208,333,493,172,247,172,292,417, 64, 84,417,224,
232,461, 25, 0,261,408,422,233, 70,117,175,265,214, 69,177,513,223,461,242,395,
491,339,315,339,328,122,184,242,242,472, 71,374,511,135,341,231,395,145,145,145,
145,145,145,145,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
147,147,147, 16,148,148,149,149,149,149,149,149,149,149,149,151,151,151,151,151,
151,151,151,151,151,268,151,151,151,151,151,151,151,152,152,154,154,154,154,155,
155,155,155,155,159,159,159,159,159,159,159,159,159,160,160,160,160,160,160,160,
161,161,161,161,161,161,161,161,161,161,161),
TPYIndex_191_list(221,214,483,485,149,505,420,431,295,423,477,339,427,513,509,317,412,509,341,517,
427,242,242,175,445,479,483,220,240,346,231,221,341,485,508,351,231, 20, 92,523,
229,395,246,479,485,517,483,108,393,503,393,307,151,291, 66,501,341,499,328, 11,
456,386,192, 0,365, 18,415,478,503,261,420,161,122,184,268,509,229,413,159,439,
379,235,514, 8,223,106,351,151,459,117,229,485,242,184,339, 8,501,161,161,161,
161,161,161,161,162,162,162,162,162,162,162,162,162,163,163,163,163,163,164,164,
164,145,164,164,164,164,164,164,164,164,164,164,165,165,165,165,165,165,165,165,
165,165,165,165,165,165,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
166,166,166,166,166,166,166,167,167,167,167,167,167,168,168,168,168,168,168,168,
168,168,168,172,172,172,172,172,172,172,172),
TPYIndex_191_list(162,162,376,422, 20,262,520,175,229,462,117,306, 15,136,466,173,514,422,376,111,
176,268,376,376,306,457,232,211, 25,164,399,172,459,442,295,229,526, 81,295,433,
221,408,182,133,506,182,482,172, 40,509,470,485,176,483,178,449,361,452,350,276,
518,440,298, 0,116,178,399,516,328,505,386,159,507,172,111,487,361, 70,179,109,
522,182,498, 7,117,507,339,509,159,498,457,117,477,393, 25,510,351,172,172,172,
172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
172,172,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,175,
175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
175,175,175,191,175,175,175,175,175,175,175)
);
BEGIN
IF (p_Index>0) AND (p_Index<192) THEN
RETURN v_list06(p_Index1)(p_Index);
ELSE
RETURN 0;
END IF;
end get_py_index_06; FUNCTION get_py_index_07(p_Index1 NUMBER, p_Index NUMBER)
RETURN NUMBER IS
v_list07 TPYIndex_list := TPYIndex_list(
TPYIndex_191_list(236,510,390,122,473,117,445,505, 69, 51,395,508,468,522,181, 11,351,268,399,524,
213,180,361,148,477,178,510, 50,210,268,186,213,161, 59,164,128,423,462,209,461,
352,121,246,470,322,459,117,458,439,364,433,478,225,462,185,145, 85,439,408,176,
460,166,186, 0,175,468,507,452,505,247, 47,350,399, 12,439,461,449,459,128,466,
431,466,462,159,457,117,435,415, 94,215,117,180,161,507,472,181,112,175,175,175,
175,175,175,175,175,176,176,176,176,176,176,176,176,176,176,176,176,176,177,177,
177,177,177,177,177,177,177,177,177,177,177,177,474,177,177,177,177,177,177,177,
177,177,177,177,177,177,178,178,178,178,178,178,178,178,178,184,178,178,178,178,
178,178,178,178,178,172,178,178,178,178,178,178,178,179,179,179,179,179,179,179,
179,179,179,179,179,179,179,179,179,179,179),
TPYIndex_191_list(172,467,361,520,393, 97,234,247,232,423,352,390,339,516,339,449,506,459,398,477,
423,449,123,450, 17,515, 28,143,522,245,237,477,500, 18, 58,236,262,339,346,432,
520,167,521,457,518,464,232,179,110,369,265,483,520,108,247,467,479,389,339,467,
460,175,194, 0,459,368,262,339, 92,508, 81,265,263,484,475, 13,408,350, 20,164,
128,520,262,451,117,451,467,135,263,462,231,520,329,487,478,431,137,179,179,180,
180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
180,180,180,180,181,181,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
182,182,182,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
184,184,184,184,184,184,184,184,185,185,185,185,185,185,185,186,186,186,186,186,
186,177,186,186,186,187,187,187,187,187,187),
TPYIndex_191_list(507,487, 47, 42, 69,458,484,520,467,479,451,128,385,479,179,477,515,291, 12,161,
317,509,175,417,352,403,487,458,415,457,364,423,117,487,505,124,366,161,497,427,
468,413,505,520,423,165, 28, 18,112, 63,229,417,478,457,520,225,513,341,251,507,
247,271,330, 0,231,468,520,172,461,415,247, 17,477,493,271,342,167,459,172,386,
466,357,468,415,345,497,526,507,388,376,235,483,108,359, 58,525,175,187,187,187,
187,187,188,188,188,125,189,189,189,189,189,191,191,191,191,191,191,192,192,192,
192,192,192,192,193,193,193,193,194,194,194,194,194,194,194,194,194,194,194,194,
194,194,194,198,198,198,198,199,199,206,206,206,206,208,208,208,208,209,209,209,
209,209,209,209,210,210,210,210,210,211,211,211,211,212,212,213,213,213,213,213,
213,213,213,214,214,214,214,214,214,214,214),
TPYIndex_191_list(359, 42,369,466,166,162,523,457,342,487, 68,479,166,457,379,175,176,164,493, 61,
462,517, 18,421,477,299,415,477,387,467,172, 23,341,221,337,470,339,322,474,268,
225,462,523,213,482,467,225,459, 42,177,242, 42,479,388,460,459,524,523,246,457,
221,225,231, 0,159,361,510,505, 85,457,479,423,487,459,415,462,116,116,339, 25,
333,460,502,123,479,139,525,421, 31,339,453,479,225,421,242,408,123,214,214,214,
215,215,215,215,216,216,216,216,219,219,219,219,219,219,219,220,220,220,221,221,
221,221,221,221,221,221,221,221,221,221,221,221,221,222,222,222,222,222,222,222,
223,223,223,223,223,223,223,223,223,224,224,225,225,225,225,225,225,225,225,225,
225,225,228,228,228,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
229,229,229,229,229,229,229,229,229,229,229),
TPYIndex_191_list(355,393,136,510,184,259,265,137,431,185,117,393,138,517,483, 4,107,408,249,237,
328,107, 44,451, 18,172, 49,237,185,261,502,246,328,172,172,243,261, 68,473,482,
482,111, 7,473,136,482,492,257,477,510,477,364,354,342,164,477,477,473,342,459,
483,222,484, 0,108,388,111,388,231,300,342,159, 49,111,159, 48, 65,117,458,321,
219,334,242,507,483,457,462,457,194,166,166,461,386,159,176,509,386,229,229,229,
229,229,229,229,229,232,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
232,232,232,232,232,232,232,232,232,232,232,233,233,233,233,233,233,233,233,224,
233,233,233,233,234,234,234,234,234,235,235,235,235,235,235,235,235,235,235,235,
235,236,236,236,236,236,236,236,236,236,236,236,236,236,236,237,237,237,237,237,
237,237,237,237,237,237,240,240,240,240,240),
TPYIndex_191_list( 48,468, 48,520,449,166,160,151,330,231,351, 6,235,321,345, 6,166,468, 72,446,
135,135,135, 85,368,277,513,435,328,477,351,173,184, 51,245,178,498,241,172,223,
168,482,163,477,347,487, 70,159,507,446,505, 45,506,482,517,433,307,471,503,381,
149,394,234, 0,180, 18, 81,143,452,467,333, 61, 87,446,435,184, 61,214,231,231,
453,214,231,231, 61,394,411,435,214,503,507, 70,297,346,291,435,435,240,240,240,
240,241,241,241,241,241,241,242,242,242,242,242,242,242,242,242,242,242,242,242,
242,242,242,242,242,242,242,247,247,247,247,247,247,247,247,247,247,247,247,247,
247,243,243,243,243,243,243,244,244,245,245,245,245,245,245,245,246,246,246,246,
246,246,246,246,246,246,246,246,249,249,249,249,249,249,249,249,249,250,250,250,
250,250,250,251,251,251,251,251,251,251,251),
TPYIndex_191_list(240,502,408,413,502,477,350,198, 32,339, 81,164, 48,361,366,484, 40,347,111,320,
318,482,357,452,339,328,457,457,198, 85,110, 7, 25,467,432,518,209,507,291,333,
518,509,459,271,351,194, 48,473,318,507,465,106,155,518,214,506,433, 65,257,462,
462,250,462, 0,296,452,452,466,199,482,155,319,388,435,257, 57,393,351,425,524,
172,482,463,445, 47,443, 90,280,328,136,229,501,415,178,232,404, 21,251,252,252,
252,252,252,252,254,254,254,254,254,254,254,254,254,254,254,254,256,257,257,257,
257,257,257,257,257,257,257,257,257,257,257,257,257,258,258,258,259,259,259,259,
259,259,259,259,261,261,261,261,261,261,261,261,261,261,261,261,261,261,262,262,
262,262,262,262,262,262,262,263,263,263,263,263,263,263,263,264,264,265,265,265,
265,265,265,266,266,266,266,266,266,267,268),
TPYIndex_191_list(245,329,225,352,160, 70,282,277,361,393,515,184, 89,328,168,455,257,368,513, 48,
246,313, 81, 4,280,402,487,508,365,441,451,186,173, 92, 18, 43,472,447,398,422,
413,515,477,233,172,328,462,247,313, 43,242,168,318, 53,176,242,513,242,177,479,
247,469, 34, 0,439,291,233, 65,214,461,444,317,507,177,456, 65,476,460,415,111,
511, 70,211,299,186, 51,185,219,231,444,339, 65, 23,470,366,485,492,268,268,268,
268,268,268,268,268,268,268,268,268,268,268,268,268,270,270,270,271,271,271,271,
271,271,271,271,271,271,271,271,271,271,271,276,276,276,276,276,276,276,277,277,
277,277,277,278,278,278,279,280,280,280,280,280,281,282,282,284,285,291,291,291,
291,291,291,291,291,291,291,291,292,292,292,292,292,292,292,293,293,294,294,295,
295,295,295,295,295,295,296,297,297,297,297),
TPYIndex_191_list(459, 21,464,215,234,472,242,168,488,246,351,492,243,291,491,459,455,181,235,181,
177,172,149,466,262,295,125,175,507,507,466,420,459, 40,457,483,464,184,182,463,
391,182,432,395,421,337,337,139,339,432,458, 72,108,314,420,108,108,242,236,458,
349,318,210, 0,117,493,112,229,483,222,446, 25,341,184,165,520, 20,271, 85, 90,
12, 40,477, 31,241, 69,469,474, 79, 71,342,242,477,172,175,455,339,297,297,298,
298,298,298,299,299,299,299,301,301,301,307,302,303,303,306,306,306,306,309,313,
313,313,313,313,313,313,314,314,314,314,314,314,315,315,315,315,315,315,317,317,
317,317,317,317,317,317,318,318,318,318,318,319,319,319,319,319,319,319,320,320,
320,320,320,320,320,320,320,321,321,322,322,322,322,322,322,322,322,322,322,322,
322,322,322,328,328,328,328,328,328,328,328),
TPYIndex_191_list(242,242, 42,403,175,333,472,472, 32,224,435,433,177,322,477, 40,262,122,483,458,
518,166,415,507,444,451,339,452,361,117,510,162,186,172, 6,521,254,362,148,478,
482,477,346,328,431, 81,229,481, 15,477,510,291,314, 24,466,474,459,159,526, 89,
85,295,161, 0,257,394,137,261,451,117,518,507,172, 61,446,469,246,229,364,507,
46,483,466,518,234,456,172,141, 59,135,140,294,483,518,320,271,508,328,328,328,
328,328,328,328,328,328,329,329,329,329,330,330,330,330,331,331,332,332,332,332,
332,333,333,333,333,333,333,333,333,333,334,334,334,334,334,334,334,334,335,337,
337,337,337,337,337,337,337,337,337,337,337,337,337, 13,339,339,339,339,339,339,
339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,
339,339,339,339,339,339,339,339,339,339,340)
);
BEGIN
IF (p_Index>0) AND (p_Index<192) THEN
RETURN v_list07(p_Index1)(p_Index);
ELSE
RETURN 0;
END IF;
end get_py_index_07; FUNCTION get_py_index_08(p_Index1 NUMBER, p_Index NUMBER)
RETURN NUMBER IS
v_list08 TPYIndex_list := TPYIndex_list(
TPYIndex_191_list(341,510,164,117,121,418, 54,180,106, 4,345, 48,333,341,223,399,514, 68, 33,483,
91,451,229, 90,117,361,478,337,487,415, 47,299,456, 22,457,128,510,268,514,526,
445,350,417, 46,322,457,464,479, 45,187,472, 67,147, 67,173,450,482,365,461,459,
452,178,278, 0,271,441,286,252, 59, 81,351, 89,521,219,242,451,361,215,337,518,
124,143,245, 50, 56,500,258,229, 13,347,185,347, 81,386,179,502,507,340,340,341,
341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,341,
341,342,342,342,342,342,342,342,342,345,345,345,345,345,345,345,345,345,345,345,
345,345,345,345,346,346,346,346,346,347,347,347,347,347,347,347,347,347,347,347,
348,348,348,348,348,348,348,348,348,348,348,348,348,349,349,350,350,350,350,350,
350,350,350,351,351,351,351,351,351,351,351),
TPYIndex_191_list(128,210,347,472,450, 17,509,175,235,421,432, 72,161,151, 57, 43,164,117,220,386,
472,477,433,339,449, 33,505,494,182, 18,477,259, 14,319, 87,350,194,460,449,483,
483,117,231,468,278, 33,455, 57,461,329,271, 4,479,216,216,176,262,526,526,522,
365,457,475, 0,472,351,175,117,247,175,321,159,159,160,472,441,518,348,261,165,
393,121,509,341,451, 25,451,172, 92,474,417,352,505,470,395,221,520,351,351,351,
351,351,352,352,352,352,352,352,352,352,352,352,352,353,353,353,353,353,353,353,
353,354,354,357,357,357,357,358,358,358,358,358,359,359,359,360,360,361,361,361,
361,361,361,361,361,361,361,362,362,363,364,364,364,364,364,364,364,364,364,364,
365,365,365,366,366,366,366,366,366,366,366,366,366,368,368,369,369,369,370,370,
371,371,372,372,372,374,374,374,374,376,376),
TPYIndex_191_list(474,484,257,487,399,513,139,357,469,446,451,482,412,478,395, 57,395,487,505,366,
229,353,484,229,184,457, 51,467,441,237,455, 83,341,522,334, 67,484, 51,483,317,
337,276,457,111,487,371, 31,261,416,266,412,237,457,136,222,125, 67,422,246,468,
517,141,520, 0,142,526,433, 33,320,446,393,222,236,433,466,254,439,510, 4,231,
520,333,467,179,442,178,451,443, 32,483,477,518, 18,242, 26,501,225,376,376,377,
377,377,378,378,378,378,379,379,379,382,383,386,386,386, 40,386,386,386,386,386,
387,387,388,388,388,388,388,388,388,388,388,388,388,388,388,388,388,388,389,389,
389,389,389,389,389,389,390,390,390,390,390,390,390,390,390,390,390,391,391,391,
391,391,391,391,391,391,391,391,391,393,393,393,393,393,393,393,393,393,393,393,
393,393,393,393,393,394,394,394,394,394,394),
TPYIndex_191_list(342,251,472,236,457,330,142,147, 81,242,391,389, 81,470, 25, 81,498,393,468,161,
6,261,247,508,334,176,261, 61,294,166,187,478,388,478,143, 46,161,386,208,341,
249,492,494,229,451,172,470,394,259,313, 42, 83,369,225,483,345,510,210,175,250,
487, 13,482, 0,242,474, 98,431,110,186,110,366,111,214,405,471,467,117,422,456,
89,408,461,457,372,487,390,175,416,236,483,458,408,299,468,487,483,394,394,394,
394,394,395,395,395,395,395,395,395,395,395,395,395,395,393,395,395,395,395,395,
395,395,395,395,395,395,395,395,395,395,395,395,395,395,395,395,395,395,395,395,
395,395,395,395,395,395,395,395,395,398,398,398,398,398,398,398,398,398,398,399,
399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,
399,399,399,399,399,399,399,399,399,399,399),
TPYIndex_191_list(461,149, 3,166,166,172,518,460,449,264,228,176, 30,393,379,231,194,484, 68,507,
422,500,416,472,108, 87,462,136,510,175,193,372,470,474, 8, 94,332,484,297,509,
455,330,339,493, 46,505,106,291,479, 61,461,339,107,175,483,214, 20,517,261,221,
179,349,346, 0,446,459,413,247,477,467,462,477,219,225,177, 81,507, 15,474,268,
164,319,412,421,443,349,345,451,237,166,313,193,487, 13,229,510,510,399,400,400,
401,401,401,401,402,402,403,403,403,404,404,404,404,405,405,405,405,406,406,406,
406,408,408,408,408,408,408,408,408,408,408,408,408,408,395,408,408,411,411,411,
411,411,411,411,411,412,412,412,412,413,413,413,413,413,413,413,413,413,466,413,
413,414,414,414,415,415,415,415,415,415,415,415,415,415,415,416,416,416,417,417,
417,417,417,417,417,417,418,418,418,418,418),
TPYIndex_191_list( 3,235,468,347,220,494,456,369,369,347,242,413,443,252,487,333,483,470,172,181,
468,350,413,181,112, 25,460,477,459,483,184,459,459,478,342,479,240,440,162,485,
236,474,257,221,214,221,172,422,251,225,225,166,411,507,451,214,163,229,172,225,
163,246,172, 0,214,242,175,375,427,225,352,461,477,243,258, 22,507,461,184,161,
467, 67,117,467,242,161,149,177,184, 13,472,500,500,214, 23,457,399,418,418,418,
418,420,420,420,420,420,420,420,420,420,421,421,421,421,421,421,421,421,421,421,
421,421,421,421,421,421,421,421,422,422,422,422,422,422,422,422,422,422,422,422,
422,423,423,423,423,423,423,423,423,423,423,423,425,427,427,427,427,431,431,431,
431,431,431,431,431,431,431,431,431,431,431,431,432,432,432,432,432,432,432,432,
433,433,433,433,433,434,434,434,435,435,435),
TPYIndex_191_list( 84,350, 87,446,186,503,475,483,147,518,460,109, 98, 7, 48,341,452,485,485,187,
339,439,507,484,353,482,347,339,508,271,450,111,111,148,117,357,319,291,425,333,
81,184,229,117,498,467,328,328,459, 84, 22, 24,500,434,136,479,246, 59,166,252,
117,234,477, 0,459,229,477,333,346,391,477,450,268,346,141,349,223,464,178,350,
173,485, 45, 15,147,468,505,337,459,232, 18,484,482,178, 70, 83,166,435,435,435,
435,435,435,435,439,439,439,439,439,439,439,439,439,439,439,439,439,440,440,440,
440,441,441,441,441,441,441,441,441,441,441,441,442,442,443,443,443,443,443,443,
444,444,444,445,445,445,445,445,445,445,445,445,445,445,447,447,447,447,447,447,
447,448,448,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,449,
450,450,450,450,450,450,450,450,450,450,451),
TPYIndex_191_list(411,184,339,483,187,457,245,229, 85,423,215,147,147, 12,110,451,444,487,417,341,
451,291,451,232, 89, 98, 11,517,450, 30,261,446,219,178,435,254,467,262,178,395,
468,472,365,451,117,484,257,451,368,462,458,479,395,508,422,510,520,431,484,259,
219, 91,350, 0,457,455,487,483,479,176, 11,408, 59,457,453,231,317,364,172,456,
466,147,477,328,162,477, 91,285,458,161,166,249,477,452,479,427,508,451,451,451,
451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,
451,451,451,451,451,451,451,451,451,452,452,452,452,452,452,452,452,452,452,453,
453,453,455,455,455,455,455,455,455,455,455,456,456,456,456,456,456,456,456,456,
456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,
457,457,457,457,457,457,457,457,457,457,457),
TPYIndex_191_list( 31,409,339,433,389, 81,242,451,507, 46,351,328,483,175,241,347,478,176,452,461,
251,503,503,249,483,237, 61,229,251,461, 43,268,524,408,350,425,507,322,345,351,
22,233,141,457,339,513,110,233,186,186,478,431,177,359,461,456,508,470,408, 51,
47, 71,229, 0,445,477,180, 68,339,172,460,391,347,479, 41,229,495,468,510,494,
462,252,462,339,364,175,149,517,178, 23,151,108,225,178,219,265,229,457,457,457,
457,457,457,457,457,457,457,457,457,457,457,457,457,457,457,459,457,457,457,457,
457,458,458,458,458,458,458,458,458,458,458,386,458,458,459,459,459,459,459,459,
459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,
460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
461,461,461,469,461,461,461,461,461,461,461),
TPYIndex_191_list(350,295,242, 91,461,510,240,229,240,318,475,328,389,475,479,399,457, 30,351,352,
30,251,178,510,517,165,307,320,508,250,106,194,264,457,191,484,351,236,468,399,
439,460,483,161,451, 72, 49,451, 72,516,122,483,477,117,321,178,508, 70,477,508,
178,507,462, 0,357,507,187, 41,477,357,445,236,319,474,526, 18,390,184,210,469,
505,477,314,117, 81,117,142,507,507,357,477,445,276,135,468,503,351,461,461,461,
461,461,461,461,462,462,462,462,462,462,173,462,462,462,462,462,462,462,462,462,
462,462,462,462,462,463,463,463,463,463,463,463,463,463,463,464,464,464,464,464,
464,464,464,464,148,464,464,464,464,464,465,465,465,465,465,465,465,466,466,466,
466,466,466,466,466,466,467,467,467,467,467,467,467,467,467,467,467,467,467, 51,
467,467,467,467,467,468,468,468,468,468,468)
);
BEGIN
IF (p_Index>0) AND (p_Index<192) THEN
RETURN v_list08(p_Index1)(p_Index);
ELSE
RETURN 0;
END IF;
end get_py_index_08; FUNCTION get_py_index_09(p_Index1 NUMBER, p_Index NUMBER)
RETURN NUMBER IS
v_list09 TPYIndex_list := TPYIndex_list(
TPYIndex_191_list(483,291, 25,446,306,339,209,361,176,525,268,178,106,366,510,141,478,188,464,380,
215,294,399,462,215,229,185,393,178,505,237,172,477, 26,514,404,354,229,466,421,
215,423,484,236, 48, 43, 72,232,320,110,484,472, 91,507,477,339,143,198,339,431,
431,117,508, 0,462, 85,215,442,482,482,484,117,483,442,472,477,319, 70,487,418,
135,163,364,484,277,181,417,317,377,294,479,178,163,209,231,229,395,468,468,468,
468,469,469,469,469,469,469,470,470,470,470,470,470,470,470,470,470,470,470,470,
470,471,471,471,471,471,471,471,471,471,471,471,471,471,471,471,471,472,472,472,
472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,
472,472,472,472,472,472,472,472,472,472,473,473,473,473,473,473,473,473,473,473,
473,473,473,473,473,473,473,474,474,474,474),
TPYIndex_191_list(247,477, 85,462,459,451, 21, 32,172,388,335, 18,337,175,513,175, 67,172, 70,488,
108,110,460,470, 22,359,251,221, 6,494,166, 32,415,299, 70,231, 71,399,500, 18,
221,337,507,419,399,447,395, 15,462, 25, 46,220,240,457,459,221,503, 69,184,491,
395,175,477, 0,221,471,457,112,117,114, 7,151,172,172,459,139, 20,472,467,186,
329,254,261,261,331,395,408,172,505,186,261,433,231,474,507,187,457,474,474,474,
474,474,474,474,474,474,474,474,475,475,475,475,475,475,475,475,475,475,475,475,
475,475,475,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,
477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,
477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,477,478,478,478,478,
478,478,478,478,478,478,478,478,478,478,478),
TPYIndex_191_list(388,451,457,432,483,221, 98, 91,347,318,172,266,479,135,351,500,179,139, 79,175,
246,351,175,451,186,351,246,221,393,172,139,472,432,350,179, 63,507, 44,172, 70,
507,462,352,125,395,141,462,167,350,464,291,339,242,498, 18,464,389,133,507,469,
51,457,477, 0,242,186,457,472,457,472, 87,117,350,350,177,172,108,470, 84,159,
41,423,467,178,477,361,470,478,388,339,445,172,470,478, 98,111,471,478,479,479,
479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,480,481,481,481,
481,481,481,481,481,481,481,481,481,481,481,481,482,482,482,482,482,482,482,482,
482,482,482,482,482,482,482,482,482,482,482,482,483,483,483,483,483,483,483,483,
483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,
483,467,483,483,483,483,483,483,483,483,483),
TPYIndex_191_list(474,411,393,478,478,186,461,281, 46,482,507,465,109,463,263,391,472,372,516,467,
477,477,413, 48,151,393,151,467,505,510,506,135,518,500,136,117,175, 85,236,431,
473,301,317,509,122,477,184,474,498,477,477,351,502,333, 18,465,351, 25, 68,522,
423,510, 59, 0,503,481,467,470,477,165,151,395,346,461,395,154, 91,160,141,352,
166,178,162,121,473,451,393,509,439,261,266,246,166,472,465,137,106,483,483,483,
483,483,483,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,
484,484,484,485,485,485,485,474,485,485,485,485,485,487,487,487,487,487,487,487,
487,487,487,487,487,488,488,488,490,490,490,490,490,490,490,491,491,491,491,492,
492,492,493,493,493,493,493,493,493,493,493,493,493,493,493,493,494,494,494,494,
495,496,497,497, 35,497,498,498,498,498,498),
TPYIndex_191_list( 24,433,477,225,510,213,351,456,172,507,361, 63,222, 98,213,477,435, 70, 15, 42,
482,199,345,347,400, 4,483,461, 47,178,459,456,456,124,411, 26,166,180,485,505,
485, 91,162, 43,404,178,194,351, 61,461,415,450,459,110,220,418,477,291,478,509,
328,517, 42, 0, 46,516,172,339,421,515,451,184,348, 89,506,526,521,341,517,232,
175,172,458,245,393, 21,162,329,483,462,467,329,395,468,395,167,162,498,498,498,
388,498,488,498,498,498,499,499,499,499,499,499,500,500,500,500,500,500,500,500,
500,500,500,500,500,500,500,500,500,501,501,501,501,501,501,501,501,501,501,501,
501,501,501,501,502,502,502,502,502,502,502,502,502,502,503,503,503,503,503,503,
503,503,503,503,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,
506,506,506,506,506,506,506,506,506,506,506),
TPYIndex_191_list( 98,508,431,462,117,337,435,221,339,483,518,513,457,166,478,440,459,278, 46,112,
510,473,472,165,468,125,306,467,270,475,451,464,427,509,388,334,443,165,168,125,
479,261,461,261,458,342,505,469,431,413, 12, 48,500,477,176,484,462,461,423,474,
474,507,483, 0,330, 61,229,268,268,389,503,267,175,494,522,231,247,493,467,142,
457,517, 6, 6,179,503,477,461,176,251,502,459,447, 70,467,497,379,505,506,506,
506,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,
507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,
507,507,507,507,508,508,508,508,508,508,508,508,508,508,508,509,509,509,509,509,
509,509,509,509,509,509,509,509,509,510,510,510,510,510,510,510,510,510,510,510,
510,510,510,510,510,510,510,510,510,510,510),
TPYIndex_191_list(457,498, 94,506,461,221, 98,479,186,172,525,345, 25,166,513,456,496,498,507,345,
421,496,337,394,468,493,421, 71,415,459,172,177,500,300,477, 3,500,166,462,477,
477,388,358,300,341, 94,418,161,509,149,477,479,191,483,175,166, 91,503,468,491,
225,393,451, 0, 42,229,477, 20,503,472, 98, 50,451, 50,474, 42,358,478,221, 46,
462,295,164,491,477, 71,500,472, 91,445,361,465,465, 18,509,393,467,510,510,510,
510,511,502,512,513,513,513,513,523,513,514,514,514,514,514,514,514,515,515,515,
515,515,515,516,516,517,517,517,517,517,517,517,517,503,517,517,518,518,518,518,
518,518,518,518,490,518,518,518,518,518,518,520,520,520,520,520,520,520,521,521,
521,521,522,522,522,522,522,522,522,522,523,523,524,524,524,524,525,525,526,526,
526,498,526,526,526,526, 0, 0, 0, 0, 0),
TPYIndex_191_list(341,159,458,172,159,147,240,457,457,233,147, 91,240,339,229, 79, 20,399,459,112,
507,507,472,472, 51,166,444,477,477,472, 7,160, 98, 51,472,215,121,184,337,457,
164,510,173,111,457,168,452,164, 81,520,111,477, 4,328,276,328,135,276,482,268,
408,164,254, 0,268, 4,483,291, 18,483,173,442,254,457,477,483, 51,421,164,186,
15,505,487,117, 28,133,425,477,148,449,332,168,108,421,449,499,507, 51,172,456,
121,292,372,328,127, 47,125,280, 98,399,483,331, 18,445,474,474,507, 81,463,478,
214,483,124,423, 83,172,277,295,172,339,261, 15,379,136,494,391, 67,472,186,408,
475,472,351,334,141,214, 20,494,137,482, 33,477,452,180,209,141,189,219,172,472,
449,211,330,186,345,168,477,439,450, 70, 87,501,224,372,477,271,361,483,328,471,
447,456, 43, 31,192,510,297,188,482,477,135),
TPYIndex_191_list(106,510,395, 18,518,106,141,329,107,250,425,394,213,117,434,477, 48,254,151,111,
242,235,166,121,329,518,173,467,495,177,121,492,175,479,470,505,391, 23, 23,350,
391, 54,492,509,220,491, 59, 46,389,432,320,128,459,250,175,415,117,421, 61, 61,
507,172,501, 0, 91,179,465, 57,487, 13,490,220,112, 31,172,394,477,523,117,135,
374,494,233,477, 8, 46,449,507,515, 21,487,497, 70,491,472,337,388,439,445,291,
119,172,106,482,210,191,510,477,433, 41,177,299,270, 50,472,229,350,229,483,333,
481,408,112,341,371,315,517,399,246,455, 18,431,139,206,184,111,472,462,172,451,
520,247,422, 23,306, 48,457,180,175,177,182,439,468, 70,439,444,391,341,522,485,
64, 81,457,470,159,143, 42,214, 13,337,159,117,117,413,408,452,472, 25,142,254,
462,243,335, 24,479,246,225,232,161,234,459),
TPYIndex_191_list(449,479,179,514,459,492, 18, 91,399,472,446,468,240,514,492,487, 18,509,112,487,
457,465,457, 47, 47,458,422,521,229,388,349,478,459,518,186,347, 81, 59,505,441,
81,457,500,186,178,351, 51,168,469,433, 97,122,417, 63,457,502,413,478,351,175,
353,517,451, 0,242, 71,350,518,431,351, 48,165,345,345,177,493,485,106,522,456,
194,186, 46,318,485,314,339,445,477,292,236,257,209,518,340,510,351,411,333,508,
266,472,178,159,388,313,184,281,136,151, 81,502,351,477,213,225,137,178,166,393,
135,352,506,167,467,345,124,213, 99,521,517,451,483,393, 42,415, 46,175,469,475,
98,483,468, 4, 81,518,329,268, 71,413,395,261,503,175,496,345,186,472,500, 46,
70,179,526,456,341,180, 11, 83,526, 15,464,121,507,295,521, 56,328,451,165,451,
457,147,349,213,252,456,109, 24,328, 15,475)
);
BEGIN
IF (p_Index>0) AND (p_Index<192) THEN
RETURN v_list09(p_Index1)(p_Index);
ELSE
RETURN 0;
END IF;
end get_py_index_09; FUNCTION get_py_index_10(p_Index1 NUMBER, p_Index NUMBER)
RETURN NUMBER IS
v_list10 TPYIndex_list := TPYIndex_list(
TPYIndex_191_list(500,317,510,291,477,172, 97, 97,510,525,512,460, 85,329,507,178, 28, 68,351,399,
441, 63,199,295,461, 26,525,271,399,177,345,260,175,339,455,451,178,353,295,184,
295,245,242,228,455,352,522,346,477, 81,520,322,506,483, 96, 57,481,507,498, 46,
445,422,117, 0,522,360,498,443,342,500, 83,431,172,237,491, 18, 49,242,233,422,
507,413,457,214,172,517,342,507,317,520,231,493,357,443,184,459,508, 81,420,173,
507,510,211,346,470,487,229,479,124,457,117,328,421,472,185,472,478,501,334,388,
521,236,112, 51,164,250,351,390,151,125,259,467,462,412,462,186,175,388, 71, 43,
408, 20, 16,350, 16, 98,107,399,172,481,151,467,456,125,505,213,328,477,229,339,
11,122,240, 83,242, 45, 81,445,291,271, 6,471, 85, 89,189,388,389,280,121,478,
47,395,143,470,234,484,507, 4,477,328,292),
TPYIndex_191_list( 25, 63,186,235,418,345,345,233, 96,139, 68, 18, 18,184,345, 96, 50,172,456,485,
292,507,485,507, 51, 92,451,240,235,459,451,221,358,462,295,418,351,353, 64,523,
457,214,339,235, 70,111,431, 97,133,222,361,246, 3,172,184,206,446,472,257,192,
351,247,223, 0,445,507,472,431, 72,479,483, 45,498,141,187,485,463, 69,468,108,
361,388,213,399,444,339,420, 98,276,339,254,368,213,341,513,159,161,322,441,378,
69,209, 85,478,228,160,125,484,251,481,232, 48,463,328,477, 32,177,277, 91,341,
172,449,465,339,460,117,484,487,110,172,229, 98,184,328,507,369,459, 43, 61,347,
456,341,339,388, 20,510,208,477,268,122,331,240, 7,271,184,357,348, 48,117,236,
294,478,254,479,349,265,433,341,477,359, 18, 59,184,439,166,510,435,345,117,361,
464,352,166,470,266,339,177, 49,176,246,479),
TPYIndex_191_list(351,213, 81,236, 69, 6,505,108,213,473,322, 15,136,136,319,510,364, 98, 7,509,
507,474,194,503,507,395,333,106,133,184,461,140,471,189,352,509,518,507,391,232,
483,390,482,484,478,503,449,117,348,509,477,236,503,500,232,518,166,450, 58,166,
191,477,322, 0,341,142,292,333,139, 15,245,315,232,368,365,172,473,459, 54, 62,
405,471,482,159,399,117,518,117,487, 16,500,483,487,423,136,505,458,470,127,179,
250,416,159,509,191, 18,395,455,482, 98,257,482,229,441,459,117,415,482, 81,393,
139,232,479, 57,180,339,457,411,179,277,339, 7,399, 43,434,483,164, 18,117,441,
70, 65,472,522, 71,175,449,479,136,147,340,112,393,460,451, 42,189,339,214,457,
98, 13,314,435,241,315,468,173,505,395,366,268,100, 15,453,149,172,229, 12,175,
406,222,479,483,413,259, 90,457,231, 63,235),
TPYIndex_191_list(484,242,461, 44,513,451,468,469,503,177,500, 26,233,111,108,235,125,379,191,164,
477,172,515,106,483,175,159,225,320,229,229,242,235, 69,509,232,487, 59,524, 20,
219, 59,477, 20, 20,446, 11, 59, 20,329,299,299,505, 58,477,362,108,395,366, 42,
122,483,477, 0,339,498,450,441,516,431,460,431, 98,508, 45,291,507,505,510,423,
477,351,166, 89,482,277,477,178,234,470, 96,181,482,350, 81,180,477,351,208,467,
233,166,470,186,369,524,172,259,108,339,159,462,159,451,477,453,412, 18,149,420,
366,470,459,124,229,168,351,155,108,295,261,299,477,213,231, 68,477,457,492,319,
482,233,119,122,431,258,442, 46,117,332,298,178,177,488,477,247,187,432,475, 3,
276,172,143, 8,184,335,234,341,139, 85,498,471,347,483, 4,468, 24,214,484,399,
100, 53,175,406,500,306,377,246,479,507,147),
TPYIndex_191_list(472,456,231,417,166,136,220, 16, 67,510,322,482,509,179,483, 58,431,418,484,306,
422,415,472, 48,431,395,505,482,487, 98,168,418,451,278,474, 50,470,418,395,507,
484,413,249,139,501,503, 27, 48,413, 96,395,241,507, 67,359,341,468,483,477, 98,
233,395,250, 0,468,500,427,106, 20, 20,229,484,482,246,229,435,339,388,483,366,
449,117,192, 23,463,393,484, 66,168, 12,184, 20,447,213,141,395,209,503,462,242,
525, 64,122,164,328,464,517,168,523,279,477,443, 69,395, 26, 48,172,208, 72,224,
498, 1,474,117,271,477,420,229, 98, 18, 15,143,347,478,488,188,119,137,236, 89,
297, 97,280,482,408,213,172,393,166, 68,234,477,461, 18, 59,140,166,466,477,315,
211, 97,172,264,261,498,299,127,270,250, 48,223,128,100,498,417,493,457,526,172,
112,494,306,263,235,513,509,423,161, 65,386),
TPYIndex_191_list(145,458,172,160,464,457,141,306,222,472, 47, 90,247,117,483,222,173,128, 25,457,
351,461,339,348,509,521,333,225,291,482,335,460,184,481,345,477,257,371, 15,399,
483,487,160,214,460,460,412,422,266,457,366, 51,518,521,475,456,460,487,345,481,
254, 44,242, 0,233,513,161,345,449,345,467, 79, 18,470, 18,497,451,506,254,235,
97,259,475,378,211,112,259,216,231,491, 42,482,339,472, 42,491,352,480, 70, 25,
87,222,229,400, 58,498, 68,278,229,214,178,481,214,182,412,478, 48,178,241,209,
455,166,347, 6,413, 91,194,295,151, 46,417,125, 1,100,149, 82, 3, 3,417,152,
439, 48,320,225, 32,330,339,479, 17,412, 81,261,322,186,233,337, 53,177,309,347,
242, 35, 79,149,179,469,477,374,328,366, 40,168,279,451,175,278,245,161,236,482,
483,348,483,164,451,507,320,422, 50,494,143),
TPYIndex_191_list(457,491,507,483,478,524,254,505, 90,505,484,117,432,340,334, 50,524, 58,482,478,
337,524,145,515,242,221,472,423,500,421,515,459, 91,421,350, 57,487,107,194,412,
50, 67,487,481, 5,498,176,330, 46,483,229,493,477,176,421,334,299,477,472,477,
293,366,398, 0,472,236,261,261,293,463,177,395,261,472, 20,395,477,457,179,350,
477,233, 72,502,236,334,350, 7,505,507, 7,243,117,277, 84,459,345,451,455,251,
501,117,108,172,339,341,339,351,471,459, 6, 34,221, 7,161,194, 89,173,466, 69,
135,254,265,477, 89,345,470,506,223,220,411,472,136,461,143,206,186,364,474,448,
490,451,483, 67,241,518,257,394,411,172,501,235, 79, 23,477, 83, 48,318, 63,470,
473,160,220,457, 43,165,474,507,177,351,376,108,350, 4,140,249,298,487,458,319,
110,364,211,398,416, 18,185,229,483,459,478),
TPYIndex_191_list(208, 54,518,108,483,456,147,123,339,252,363, 81,408,457,477, 41,477,441,457,307,
341,350,175,502,475,478,314,109,505,464, 90,485,508,117,328,369,463, 98,186, 96,
135,478,341, 11,457,361, 44,298,111,487,477,347,328,143,159,478,187, 84,477,508,
457,121,363, 0,168,420,192,484,242,288,452, 97,518,291,441,395,265,328,194,236,
24,420,161, 25,328,483,408,526, 26,509,432,173,505,395,522,507,184,414,477,143,
246,291,391, 63,261,161, 40,451,451,257,280,501,180,186,233,462,470,164, 54,168,
416,478, 89,395,422,444,457,361,483, 48,477,460, 25,483,167, 40,412,268,466,179,
376,513,279,328,456,141,319,466,460,445, 4,483, 18,128, 6,179, 42,462,235,479,
399, 72, 66, 42,456,507,313, 49,456,189, 43, 55,411, 20,298,161, 51,322, 68,473,
526,291,117, 44,477,477,439,472, 33,189,470),
TPYIndex_191_list(434,477,477,468,502,319,151,379,394,522,522, 25,510, 48,488,334,439,341,117,499,
254,472,117,229,485,328,473, 11, 25,178,351,467,506,271,457,457, 81,173,271,421,
393,477,408,213,188, 15,517,464,159,177, 48,199,246,333,395,270,194,478,187,509,
49,460,439, 0,268,225,172,483,467,361,525,507,406,229,459,464,352,328,477,510,
460,266,210,474,459,459,466,187, 40,223,172,328,366,261,477,478,140,194,487, 15,
411,341,214,215,477,431,352,346,464,110, 43,450, 50,161, 65,487,214, 98,228,515,
345, 18,413,341,481,180,345, 49, 51,235,259,432,166,402,472,451,159,265,192,418,
247,215,182,222,483, 43,457,452,167, 98,351,353,151,432,353,191,514,317,342,376,
339,408, 40,112,484,271,262, 96,261,136, 20,452,148,451,224,122,399,240,242,473,
408, 97,236,254,246,468,317,445,159,265,180),
TPYIndex_191_list( 4, 88,482,379,193,341,408,289, 84,147,485,507,199,350,461,503,482,492,431, 67,
137,159,508,441,247,259,222,449,518,487, 15,413,483, 42,435, 25,147,173,159,185,
112, 42,449,507,445,468,456,483,433,213,517,244,464,347,393,147,244,475,184,497,
184,459,434, 0,252,337,229,317,485, 47,124,229,425, 24,510,505,441,237,524,184,
43,484,175,123, 84,423, 43,245,210,236,328,242,229,342,335,185,265,164,451,234,
173,505,478,166,510,172,467,166,423,470,176,237,161,470,366,413,456,220,451,517,
185, 34, 12,457,257,164,510,339,457,411, 91,517,328,262,122,110, 61,393,139,242,
402,462,472,262,350,412,165,467,321,175,468,455,257,472,347,194,391,252,479,337,
229,366,418,167, 18,466,117,422,318,266,165,479,461,221, 32,161,246,164,231,510,
477,242,468,122,399,408,388,390,439, 42,220)
);
BEGIN
IF (p_Index>0) AND (p_Index<192) THEN
RETURN v_list10(p_Index1)(p_Index);
ELSE
RETURN 0;
END IF;
end get_py_index_10; FUNCTION get_py_index_11(p_Index1 NUMBER, p_Index NUMBER)
RETURN NUMBER IS
v_list11 TPYIndex_list := TPYIndex_list(
TPYIndex_191_list(524,322, 4,328,459,471,515,229,194,206,418,215, 91,515, 56,518,506, 16,295,520,
97,472, 87,477,341,515,172,483,179,139,254, 43,444,457,231,423,136,457,399,505,
247,259,242,162, 21,119,220,198,109,456,277,449,161, 73,459,446,168,232,107,258,
189,473,395, 0,231,143,459, 91,441,451,449,117,365,172, 98,187,505,431,498,161,
473, 92,458,483,199,394,165,451,117,502, 40,346,395,159,214,432,345,415,229, 70,
42,231,366,337, 18,149,517,147,462,479,485,111,149, 7, 13,141, 71,261,482, 46,
297,341,341,456,233,341,164,175,175,521,471,456,181,494,477,106,173,180, 69,160,
318, 26,229,350,461,431,354,214,451,164,242, 54,165,350,458, 6,135,418,237,459,
235,184,462,263,415,219,470,166,442,507,193,507,172, 98, 42,457,184, 42,180,301,
261,117, 18,483, 51,406,110,472,456,483, 18),
TPYIndex_191_list(345,160,440,520,164,475,265,175, 92,175,411,214,161,468,503,178,505, 20,508,518,
466,475,257,315, 3,121,341,257,417,418,318,458,231,417,189,522,475,300,453,364,
422,417,342,229,406,515, 25,317,372,328,377,123,518,456,479,165,433,237,189,416,
395,412,449, 0,149,505,505,246,477,484,422,295,457,173,125,249,185,411,522,417,
446,112,452,276,242,417,313,522,442,466,139,468,231,412,251,268,246,179,518,141,
298,483,408, 68,509,388,346,471,359,399,243,177,332, 40,229,333,447,459,417, 81,
451, 98,180, 21,178, 43, 18, 42,301, 6,484,435,456,135,268,328, 3,332, 48,229,
472,342,330, 43,225,501,457,388, 18,294,268,403,119,119,117,301,518,178,186, 13,
492,408,117,521,477,301,420,461,162,329,229,339,194,515, 30,507,456, 6,237,388,
21, 61, 42,172,460,177,483,509,125,449,213),
TPYIndex_191_list( 18,451,237, 81,376,520,477,242,199,342, 65,339, 43,422,251,481, 42,112,180, 21,
399,247,466, 61,240,491,491, 32,229,458,457,192,403, 17,501,341, 47,242,162,172,
337,415,342,334,235,379,466,459, 47,214,408,237,280,165,331,415,108,345,352,473,
422,460,483, 0,177,525,233,346,223, 96,463,491,339,175,508, 79,471,479, 96,186,
300,491,337,434,446,501, 87,388,189,175,110,415,242,185,166,483,231,487,328,399,
122,462,117,509,117, 51, 69,209,148,176,128,461,431,236,339,110,389,142, 97,398,
237,352,449,518,194,460,431,263,166,408, 20,135,515,265,179,505,366,124,229,477,
175, 23,330,251,225,267,378,462,233,497,176,341,345,164,523,474,172, 54,490,481,
87,172,451, 23,265,186,194,240, 83, 69,334,265,173,106,133,467,471,155,474,246,
457,166,231,339,479,339,161,215,472, 61,449),
TPYIndex_191_list(517,378,341,517,225, 18,434,468,475, 97,143,422,351,111, 68,477, 3,520,470, 84,
510,155,515,172,295,151,168,348, 23,479,214,297,467,175,175,341, 40,507,264,229,
225,172,523,213,389,322,219, 91,485, 58,247, 21, 13,242,459,212,240, 98,242,175,
221, 25,341, 0,474, 42,460,175,457,139, 31,295,225, 64,351,317,246,523,243,526,
477,186,422,510,221,457,473,464,319,464,252,471,507,459,483,477, 43, 46,184,254,
483,484,458,280, 3,422,179,165,479, 65, 61,468,501,337, 30,351,242, 18,491,452,
451,487,423,456,390,339, 40,249,229,328,263,474,369,175, 51, 47, 61,461,109,314,
510,277,507,503,240,182,333,242,458,461,482,507,445,507,236,135, 81,229,445, 47,
193,223,471,359,507,505,140,339,435,216,182,162,155,141,178,243,185, 4,467,108,
136,117,186,518,417,236, 51,111, 91,341,502),
TPYIndex_191_list(507,479,165,518, 25,422,364, 17,237,468,219, 42,501,501,182, 6, 85,186,233,291,
258,249,402,388,388,258,472, 18,147, 18,388,341,192, 17,159,370,376,459,459,175,
265,458,404, 90,498,280,500,322,458,236,139, 18,370,151,449,125,125,107, 51,460,
141,265,384, 0,215,232,247,435,386,184,485,485, 42,351,235,422,387,215,472,452,
472,483,167,483,452,460, 13,460,351,474,452,317,478,451,478,216,353,246, 56,232,
143,175, 81,184, 62,393,278,498,231,221,172,332,184,350, 92, 56, 46,247, 40,184,
468,257,479,505,110,418,416,462,124, 65,124,406, 23,364,510,462,179,342,339, 51,
422,510,161,122,485,348,445,186,345,347,242,525,457,184,484,225,472,235, 25, 40,
482, 6,268, 63,389,432,487,231,330, 70,172, 23,477,361, 98,136,194,242,507,477,
505,161,229,474,395,507,352,242,503,292,450),
TPYIndex_191_list(221,391,352,325,432,295,418,189,151,353, 55,449, 90,339,214,422,449,330,459,457,
166, 42,328,422,164,418,452,446,147,189,391,166,418,164,224,463,477,507,478,473,
90, 98,394,320,199,487,507,328, 47, 98,351, 81,236,507, 24, 97,399,415,106,141,
483,187,345, 0,464, 57,456,458,388,394,337,505,459, 72,320,477, 94,245,478,184,
505,242,394,459,478,510,473,362,458, 49,472,478,483, 81,451,295,515, 58,518, 62,
242,235,451,175,342,173,172,172,191, 79,121,175,492,313,236, 26, 17,497,328,334,
119,219,122,149,421,124,494,463,487,141,151,491,254,483, 43,291,339,394,475, 44,
472,166, 26,147,141,468,214, 3,266,444,470,474,457,279, 16,395,213,477,507,518,
121,179,505,220,350,172, 70,117, 42,172,457, 81,483,135,179,351,175,176,332,254,
136,456,136,172,184,175,329,193,346,417, 8),
TPYIndex_191_list( 4,178,339,472,166,487,456,422,172, 72, 6,457,478,372,359,235,443, 79,328,415,
483,472,111,291,106,172, 72,478,507,240,457,229,229,353,507,477,347,341,164,135,
524,161,488,483, 50,415,147,455,403,164,184,488,481,172,457,237,229,306,469,488,
172,172,276, 0,116,457,271,111,318,487, 48,473, 4,456, 83, 71,161, 84,271, 46,
498,236,339,509,159,500,478,510,444,236, 89,479,456,236,236,159,478,125, 25,254,
271, 65,175,376,399, 43,242,337,351,331, 72,459, 54, 89,471,478,194,487,108, 48,
177, 91, 85,482,484,143,485,455,364,165,180,368,420,133,516,276,474,341,240, 89,
188,242,173,393,509,526,137,505,351,507,180,140, 89,472,211,372,145,329,505,261,
444,246, 67,319,449,294,180,472,110,483,520, 87,175, 62,278,262,447, 98,399, 47,
479,125,247, 23,427,507, 53,136,259,378,388),
TPYIndex_191_list(250,250,487,237,259, 23,456,451,216,457,477, 70,427,483,240, 69,172,318,473,451,
446,457,172,456,259,225,229,417, 3,110, 69,240,236,477,112,229, 13,151,151,151,
24,348,432,505, 47,348,232,180,432,110,262, 13,432,166,475, 87, 40,341,361, 81,
91,456,361, 0,347,298,478,372,276,447,522, 11,477,474,423, 18,178,159,319, 24,
478,418,423,178, 4,154,133,340,435,479,415,433,468,206, 17,418,501,231,235,483,
457,477,386,463,457, 21,372,184,412, 21, 21,399,135,136,161,110,172,221,483,320,
254,500,180,291,237,477,473,451, 96,342,395,161,510,468,420,475,473,456,147,258,
44,472,161,483,451, 92, 13,468, 20,443,237,251,389,487,477,483,108,415,459,186,
64,408,423,467,457,229,161,181,161,110,395,408,459,507,351,161,117,526,261,507,
59,505,433,339, 42,457,517,457,358,425,421),
TPYIndex_191_list(328,216,219,498, 12,101,350,350,391,390,271,175, 81,312,423,418,462,317,125, 24,
216,422,241,166,345,469,172,175,176, 42,418,161,459,341, 91,447,175,221,451,361,
117,447,352,125,451,390,147, 43,216,365,487,391,451,125,117,423,135,487,124, 18,
469,415, 91, 0,447, 91,117,182,459,462,459,172,488,224,322,479,479,487,322, 4,
478,460,161,475, 87,348,214,460,405,147,467,477,467,136,411,214,339, 94,173,166,
307,296,473,518,353,341,265,425,339, 94,254,258,123,483,483,418,469,263,172,122,
71,162, 45, 96,471,517, 20,112,107, 3,229,240,498,439, 81,219,445,117,464,252,
458,345,499, 89,280,125,455,339, 94, 15, 87, 46,509,178, 81,468, 20,503,142,377,
348,351, 96, 79,176, 27,259, 25,191,507,117,117,467,262,208, 96,263, 70,394,484,
477,415,518, 48,270,220,175, 81,417,471,291),
TPYIndex_191_list(148,483,449,111, 96, 81, 83,317,334,236, 45,180,225,347,345, 98, 98,451,462,216,
393,477,477,194, 94,483,333,225,433,173,440,166,214,173,246,435, 47,479,487,161,
147,180,443,443,332,220,443,518,518, 56, 87,220,421,147,341,212,522,459,347,477,
374,431, 98, 0, 98,472,452,472,483,513,472,459,463,477,484,377,432,432,176,214,
225,223,330,512,251, 63,474,149,345,136,470,472,166,388,366,259, 23,415,328,369,
412,214,254,194,266,330, 47,191,235,136, 87, 18,352,432,108,505,391,449,442,117,
123,136,229,472,328,221,229,172,497,151,139,185,179,119,477,334,502,233,441, 54,
388,258, 41,307, 26,420,184, 11,341,109,192,440,168,314,483,506,136,194,334, 26,
25,485,271,421, 83,406,395,468,418, 18,291,328, 97,193,223,106,482, 47,173,280,
475, 47, 84,478,189,510, 87, 88,162,352,144)
);
BEGIN
IF (p_Index>0) AND (p_Index<192) THEN
RETURN v_list11(p_Index1)(p_Index);
ELSE
RETURN 0;
END IF;
end get_py_index_11; FUNCTION get_py_index_12(p_Index1 NUMBER, p_Index NUMBER)
RETURN NUMBER IS
v_list12 TPYIndex_list := TPYIndex_list(
TPYIndex_191_list(459,332,242,235,295,352,435,181,335,479,483,225,112, 88,137,117,458,500,319,372,
117,420,234,172,468,461,184, 21,408,451,473,474,412,189,412,108,237,457,237,330,
330,237, 21, 21, 21,233, 21,379,112,466,473,500,408,474,237,110,108,110,395, 30,
172, 87,408, 0,445,500,516,361,483,473,395,478,108,108,416,478,510,477,526, 18,
178,423, 13, 59,434,408, 13,395, 97,145,361,432,177,173, 24,474,439,386, 84,506,
379, 49,422, 4,366,223,220,425,199,497,229,124, 98, 67,244,237,189,175,222,347,
184, 1,342,306, 16, 73,194,215,136,168,320,185,421,518,346,189,408, 98, 40,412,
164, 3,241,342,110,257,268,125,185,276,237,477,173, 23, 21,422,251,246,481,522,
468, 81, 42,186,337,242, 96,221,337, 64,342, 79,168,517,477, 40, 21,508,393, 67,
507, 18,518,268,399,247,172,117,222,194,361),
TPYIndex_191_list( 59,460,473,185,106,224,457, 25,282, 98, 26,187, 90,413,483,457,474,215,143,395,
175,515, 24,459, 26,475,421,110,501,451,139, 98,302,487,161,165,166,500,160,151,
464,111,451,136, 40,411,422, 25,124,457,214,237,412,459,475,452,268,422,251, 18,
483,466,179, 0,376,443,513,388, 48, 70,477,339,359, 47,451,460,500,111,145,259,
472,268, 42,460,246,491,279, 87,445, 97,173,224,457, 90,187,143,136,505,172,379,
292,117,358,141,177,149,457,334, 85,161,481,182,484, 13,505,136, 89,242,351, 48,
408,106,507,137,466,243, 25,229,161,483,459,431,456,263, 4, 15, 57,161, 98, 59,
257,456,474,175,479,503,237,233,177,182,483,161,242,139, 24, 87,178,229,388,229,
482,122,194, 70,498,319,510,468,173,471,477,507,223,456, 67,459,386,510,110,136,
451,483,483, 70,219,477,160, 67,241,173,378),
TPYIndex_191_list(475, 25,111, 25,291, 18,334,441,147,110,175, 4, 3,459,487,111,332,463,249,483,
333,341, 81,445,503, 48,470,510,507,320,463,363,372,487,452,507, 70,247,482, 25,
13,211,445,477,351,337,351,181,334,502,484,322,509,184,510,301,184,328,522,173,
236,505,499, 0,117,473,395, 18,445,445,408,237,249,329,423,507,364,427, 89,470,
352,393,181,106,145, 25,510,478,246,509, 70,145,237,184,411,347,252, 48,268, 11,
172,165, 21,246,479,499,240,478, 50, 11,220,477, 83,328, 83,351,477,411,457,349,
516, 20,474,433, 90,194,483,470,184,483,477, 40,276,361,179,257,317, 71,340,125,
198,231, 47,231,175, 21, 51,431, 18,184, 97, 68, 15, 13,247, 20,221, 48,503,342,
366,317,399,467,187, 66,179,225,518, 44,408,168,223,422,313,241,176,300,268, 85,
87, 70,236,297,143,214, 6,421,147,339,148),
TPYIndex_191_list(232,147,441,468,443,187, 98, 47,464,408,242,515,509,391,329,215,423,220,520,194,
339,339,472,110,378,472,125,474,456,329, 61,329,341,110,165,341,168,483,431,352,
458,520,214,365,408,137,445,443,412,341, 47,507,237,322,427,457, 32, 91,472,484,
521,461,388, 0,339,507,403,242,457,246,501,268,474, 30,330, 61,351, 18,507,483,
467,162, 25,413,461,235,500, 96,237,445, 35, 83,461,434,472,246,500,178,151,479,
194,147, 98,513,295,251,377,149,366,332,161,341,350,172, 41,166,125,259,117,328,
369,459,149,178,133, 90,478, 48,147,136,194,229,482,357,498,350,236, 47,482,349,
173,280,507,408,351,435,216,339,177,473,270,393,503,390,456,229, 51,117,342,348,
339,457,483,110,143,143,477,328,433,352,449,222,259, 57,364,278,117,214,194,117,
412,483,482,241,350, 20,270,347, 6,251,252),
TPYIndex_191_list(180,477,475,503,332,509,472,492,247,427,460,172,403,184,457,164,229,330,363,478,
330,464,347,520,413,214,403,451,451,451,483,122,477,192, 13, 15,499,431,461,210,
443,128,329,483,415,334,461,318,186, 67,268,233,241,461,492,431, 23,212,242,124,
345,193,345, 0,223,378,215,431,109,466,357, 70,215, 23,107,328,107,431, 13, 18,
365,117,106,364,351,133,485,322,511,390,417,431,229, 23,431,322,411,249,484,457,
48,422,318,395,165, 32,330,422,457,460,508,501,401,254,322,166,317,388,168,259,
42,231,264,229, 91,351,116,479,348,458,395,510,483,172, 91,172,175,502,518,161,
349,334, 68,394,494,135,229,408,433,173, 20, 48,208, 18,459,472,352,506,187,395,
123,314,390,461,348,494,346,510,371,341,445, 18, 70,206,484,461,505,214,165,160,
135,110,229, 18, 48,413,264, 90,242, 92,141),
TPYIndex_191_list(506,520,405,175, 97,161,219,339,231,505,322,249,376,251,251,383,467,234,341,341,
279,216,297, 23,358, 90, 90,280,460,457, 90,147, 90, 90,182,483,483,472,229,463,
141,520,237,462,389,257,339,339,119,467,483,443,339,232,122,330, 18,339,467, 50,
472,500,483, 0, 72,361,178, 7,159,445, 84,172,483,162,346,417,148,444,268,178,
393, 11,484,328,247,452,161,242,488,109,111,276,482,329,268,151,458, 83,491, 79,
25,220,509,483,483, 49,457,295,307, 54,388,477, 18,508, 11,109,125,242,510,494,
457,390,451,259,398, 32, 49,259,347,294,173,350,386, 18, 81,342,417,178,422,457,
459,261, 7,229,433,457, 59, 30,235,520,376,160,491, 59,467,365,350,176,127,172,
477,236,457,510,110,175,329,151,477,261,507,339,339,474, 72,117,351,182,346,234,
518,491,278,503,176, 48, 87,122,509,477,136),
TPYIndex_191_list(462,147,328,236,445, 25,350,333,117, 18,172,451,351, 84, 25,482,142,328,292,506,
420,319,117,498,184,136,395, 89, 69,418,340,399,160,505,106, 4,451,502,510,478,
234,246,439,477,477, 24,451,177,209,462,459,125,166,223,117,193,466, 97,187,431,
262,390,498, 0,417,347,483,282,503,142,128,413,456,350,393,337,164,433,229,386,
386,193,259, 47,229,521,457,481,393,518,339,506,460,282, 57,172, 84,526,445,459,
266,507,472,387, 47,441,225,215,320,161,431,467,145,422,223, 26,177,457,184,229,
470,395, 67, 96,349,469, 63, 22, 13,418,175,117,342,507,117,388,229,445,173, 25,
420,214,345, 18,459,459,172,177,232,172, 58,163, 48,507, 83, 25,507,175, 85, 53,
508,184, 97, 67,329,365,295,317,339, 51,186,337,108, 63,510,235, 42,234,523,462,
507, 84,268,466,268,328,161,186,389,136,524),
TPYIndex_191_list(346,136,509, 89,220,110,291,477,215,242,182, 43,180,245,236,521,229,259,520,507,
292,161,483, 81,395,393,164,431,160,506,510,219,520,495, 20, 20,164,352,495,451,
451,483, 57,365,498,165,231,472,350,350,175, 18, 98,473,117,457,459,458,451,161,
395,371,468, 0,452,341,149,456,318,378,237,249,395,395,215,518,427,418,474,125,
481,341,339,452,371,393,231, 6,224,166,265,172,433,351,175,393,251,133,413,507,
518,348,232,483,229,452,435,172,320,110,386,478, 3,459,250, 46,184, 13,433,518,
478,483, 58,455,265,484,445,515,416,187,184,246,351, 50,349,243,456,491,270, 6,
237, 15,463,482,109, 7,333,292,242,413,117,160,420,141,178,451,106,172,177,460,
470,128,229,231,175,395,433,142,386,164,172,348,236,521,110,215, 43,136,291,292,
84,395,518,111, 85, 98,350,117,165, 20,378),
TPYIndex_191_list(457,350, 21,172,172,510,176,466,513,481,501,192,469, 22,483,351,460, 25,177,470,
413,165,525,445,388,108,186,235,470,263,457,497,460,111,139,160,211,495,378,500,
122,141,479,229, 43,225,399, 3,366,172,483,161,399,229,234,246,264,505,460, 98,
242,139,229, 0,459, 72,172,444, 7,151,482,498, 25,328,193,439,495,160,211,498,
187,481,339,393, 18, 43,431,452,451,352,176,318,341,451,457,161,122, 6,339,418,
139,474,224, 21,469,251,265,481,141,388,525,229, 68,473, 68,345,251,175,184,365,
135, 15,178,440,209,136, 81,160,125,194, 18,241,340,212, 23, 91,257, 7,472,232,
461,450, 48,460,472,434,423,481, 19,215,254,357,433,172,518,466,352,182, 23,164,
234,256,166,261,172,187,510,261,339, 6,391,235, 69, 51,482,458,477,351, 91,229,
348, 30, 4,111,482,456,472,457,350,147,498),
TPYIndex_191_list(500,139,353,477,117,229,507, 26,472,117,502,172,112,366,472,395,112,266, 13,484,
507,161,347,141,111,452,500,395,483,116,474,186,186,328,164,505, 13,472,471,506,
109,112,452,313, 69,125,366,236,264,117,445,452,229, 20,507,125,484, 59,351,461,
48, 70,184, 0,474,136,508,483,473,483,471,434,483,432,479, 94,456,106,137, 3,
507,472,155,461,173,234,510,473,477,159,242,366,270,125,361,461,466, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
);
BEGIN
IF (p_Index>0) AND (p_Index<192) THEN
RETURN v_list12(p_Index1)(p_Index);
ELSE
RETURN 0;
END IF;
end get_py_index_12; FUNCTION get_py_index_13(p_Index1 NUMBER, p_Index NUMBER)
RETURN NUMBER IS
v_list13 TPYIndex_list := TPYIndex_list(
TPYIndex_191_list(509, 48,246,155,292, 98,243,173,172,441,185,445,337,456,185,483, 25,187,187, 18,
457,187,184,441,180,431, 98, 98,213,161,456,393,220,177,317,242,328,399,117,471,
517,322,350,341, 15, 84,242,353,175,184,441,471,484,339,229,475,515,206, 97,215,
394,339,180, 0,477,477,348,518,220, 89,339,442,128,184,351,477,525,172,399,446,
48,263,365,471,350,431,161,431, 98,178,254,117, 57,441,472,151,484, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
TPYIndex_191_list(329,215,257,161,479,507,456,184, 89,342,109,161,479,484,459,453,395,151, 51,422,
458,371,237,172,161,341,470,147, 59, 59,477,474,472,172,229,432,208,431,431,477,
441,249,461,124,432, 46,172,442,503, 6,474,477,313, 48,507,237,481,247, 18,403,
517,483,456, 0,186,478,431,408,177,477,162, 18,479,413,165,108,177,233,472,124,
182,459,459,441,250,525,483,479,242,442,459,469,477,328,510,246,457, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
TPYIndex_191_list(477,172,494,483,500,475,473,328,297,161,261,479,259, 81,485,483,225, 26,242,151,
240,403,485,479,352,351,229,243,395,342,461,236,469,155,509,456,215,341,128,484,
413,151,350,477,453,237,172,477,477,164,500,259,403,242,179,236,175,459, 67,175,
175,472,482, 0, 63,319, 63,319,510,175,261,483,237, 46,354,235,291,182,354,180,
408,460,472,173,261,229,501,180,339,236,472, 63,250,151, 44,117,262, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
TPYIndex_191_list(262,117,319,351,351,270,117,472,220,262, 48,112,351,262,268,268,521,304,111,165,
179,140,432,440,162,213,159, 48,152,477, 70,457,444,268,341,500,472,257,472,485,
422,472,472,472,505,505,516, 30,477,257,500,472, 91,242,111,265,484, 63,351,502,
447,510,507, 0,259, 6, 22,445, 18,502,261,505,518,136, 89,111,484, 43,124,339,
484,422,427,399,110,452,110, 84,445,508,351,394,395,395,435,457,180, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
TPYIndex_191_list(167,457,472,441,408,459,225,474,456,456,209,462,151,466,453,498,299,279,518,499,
172,518,172,172, 48, 46, 46,151,471,478,462, 13,494,462,518, 48,472,498,433,236,
236, 51,352,462,478,295,182,474, 58,487,483, 51,477,291,498,521,351,487,472,483,
98,455,477, 0, 67,521, 83, 51,179,471,151,478,252,318,455,318,472,252,240,133,
194, 68,236, 68,350,350, 22, 56,151,186,462,485, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
TPYIndex_191_list( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
);
BEGIN
IF (p_Index>0) AND (p_Index<192) THEN
RETURN v_list13(p_Index1)(p_Index);
ELSE
RETURN 0;
END IF;
end get_py_index_13; FUNCTION GetHzFullPY(p_String varchar2)
RETURN VARCHAR2 IS
--declare
--p_String varchar2(200) := '???????';
v_char varchar2(2); --????
n_loop number; --??
n_len number; --????
n_ascii number; --??ASCII?
n_ord_high number; --n_ascii/156
n_ord_low number; --n mod 256
n_temp number;
n_temp1 number;
v_PY varchar2(32767); BEGIN
v_PY := '';
n_len := length(p_String);
FOR n_loop IN 1..n_len LOOP
v_char := substr(p_string,n_loop,1);
IF upper(v_char) IN (
'A','B','C','D','E','F','G',
'H','I','J','K','L','M','N',
'O','P','Q','R','S','T',
'U','V','W','X','Y','Z',
'0','1','2','3','4','5','6','7','8','9',
'(', ')', '[', ']','.', '!', '@', '#', '$',
'%', '^', '&', '*', '-', '+','<', '>', '?', ':', '"') THEN
v_PY := v_PY||v_char;
ELSE
n_ascii := ascii(v_char);
n_ord_high := trunc(n_ascii/256,0);
n_ord_low := n_ascii-(n_ord_high*256);
--DBMS_OUTPUT.PUT_LINE('n_ascii = '||to_char(n_ascii,'9999999'));
--DBMS_OUTPUT.PUT_LINE('n_ord_high = '||to_char(n_ord_high,'9999999'));
--DBMS_OUTPUT.PUT_LINE('n_ord_low = '||to_char(n_ord_low,'9999999'));
IF (n_ord_high>128) and (n_ord_low>63) THEN
CASE n_ord_high
WHEN 162 THEN --????
IF n_ord_low>160 THEN
v_PY := v_PY||get_roma_num_py(n_ord_low-160);
END IF;
WHEN 163 THEN --??ASCII
IF n_ord_low>128 THEN
v_char := chr(n_ord_low-128);
IF upper(v_char) IN (
'A','B','C','D','E','F','G',
'H','I','J','K','L','M','N',
'O','P','Q','R','S','T',
'U','V','W','X','Y','Z',
'0','1','2','3','4','5','6','7','8','9',
'(', ')', '[', ']') THEN
v_PY := v_PY||v_char;
END IF;
END IF;
WHEN 166 THEN --????
IF (n_ord_low>160) AND (n_ord_low<185) THEN --A1--B8
v_PY := v_PY||get_greece_alphabet_py(n_ord_low-160);
ELSE
IF (n_ord_low>192) AND (n_ord_low<217) THEN --C1--D8
v_PY := v_PY||get_greece_alphabet_py(n_ord_low-192);
END IF;
END IF;
ELSE
BEGIN
n_temp := n_ord_high-128;
n_ord_low := n_ord_low-63;
n_temp1 := trunc(n_temp/10,0);
n_temp1 := n_temp-n_temp1*10;
IF n_temp1=0 THEN
n_temp1 := 10;
END IF;
--DBMS_OUTPUT.PUT_LINE('n_temp = '||to_char(n_temp,'9999999'));
--DBMS_OUTPUT.PUT_LINE('n_temp1 = '||to_char(n_temp1,'9999999'));
CASE
WHEN n_temp<11 THEN
n_temp1 := get_py_index_01(n_temp1,n_ord_low);
WHEN n_temp<21 THEN
n_temp1 := get_py_index_02(n_temp1,n_ord_low);
WHEN n_temp<31 THEN
n_temp1 := get_py_index_03(n_temp1,n_ord_low);
WHEN n_temp<41 THEN
n_temp1 := get_py_index_04(n_temp1,n_ord_low);
WHEN n_temp<51 THEN
n_temp1 := get_py_index_05(n_temp1,n_ord_low);
WHEN n_temp<61 THEN
n_temp1 := get_py_index_06(n_temp1,n_ord_low);
WHEN n_temp<71 THEN
n_temp1 := get_py_index_07(n_temp1,n_ord_low);
WHEN n_temp<81 THEN
n_temp1 := get_py_index_08(n_temp1,n_ord_low);
WHEN n_temp<91 THEN
n_temp1 := get_py_index_09(n_temp1,n_ord_low);
WHEN n_temp<101 THEN
n_temp1 := get_py_index_10(n_temp1,n_ord_low);
WHEN n_temp<111 THEN
n_temp1 := get_py_index_11(n_temp1,n_ord_low);
WHEN n_temp<121 THEN
n_temp1 := get_py_index_12(n_temp1,n_ord_low);
WHEN n_temp<121 THEN
n_temp1 := get_py_index_13(n_temp1,n_ord_low);
ELSE
n_temp1 := 0;
END CASE;
v_PY := v_PY||GetHzPY_by_index(n_temp1);
END;
END CASE;
END IF;
END IF;
END LOOP;
RETURN v_PY;
--DBMS_OUTPUT.PUT_LINE(v_PY);
END; FUNCTION GetHzFullPYLower(p_String varchar2)
RETURN VARCHAR2 IS
--declare
--p_String varchar2(200) := '???????';
v_char varchar2(2); --????
n_loop number; --??
n_len number; --????
n_ascii number; --??ASCII?
n_ord_high number; --n_ascii/156
n_ord_low number; --n mod 256
n_temp number;
n_temp1 number;
v_PY varchar2(32767); BEGIN
v_PY := '';
n_len := length(p_String);
FOR n_loop IN 1..n_len LOOP
v_char := substr(p_string,n_loop,1);
IF upper(v_char) IN (
'A','B','C','D','E','F','G',
'H','I','J','K','L','M','N',
'O','P','Q','R','S','T',
'U','V','W','X','Y','Z',
'0','1','2','3','4','5','6','7','8','9',
'(', ')', '[', ']','.', '!', '@', '#', '$',
'%', '^', '&', '*', '-', '+','<', '>', '?', ':', '"') THEN
v_PY := v_PY||v_char;
ELSE
n_ascii := ascii(v_char);
n_ord_high := trunc(n_ascii/256,0);
n_ord_low := n_ascii-(n_ord_high*256);
--DBMS_OUTPUT.PUT_LINE('n_ascii = '||to_char(n_ascii,'9999999'));
--DBMS_OUTPUT.PUT_LINE('n_ord_high = '||to_char(n_ord_high,'9999999'));
--DBMS_OUTPUT.PUT_LINE('n_ord_low = '||to_char(n_ord_low,'9999999'));
IF (n_ord_high>128) and (n_ord_low>63) THEN
CASE n_ord_high
WHEN 162 THEN --????
IF n_ord_low>160 THEN
v_PY := v_PY||get_roma_num_py(n_ord_low-160);
END IF;
WHEN 163 THEN --??ASCII
IF n_ord_low>128 THEN
v_char := chr(n_ord_low-128);
IF upper(v_char) IN (
'A','B','C','D','E','F','G',
'H','I','J','K','L','M','N',
'O','P','Q','R','S','T',
'U','V','W','X','Y','Z',
'0','1','2','3','4','5','6','7','8','9',
'(', ')', '[', ']') THEN
v_PY := v_PY||v_char;
END IF;
END IF;
WHEN 166 THEN --????
IF (n_ord_low>160) AND (n_ord_low<185) THEN --A1--B8
v_PY := v_PY||get_greece_alphabet_py(n_ord_low-160);
ELSE
IF (n_ord_low>192) AND (n_ord_low<217) THEN --C1--D8
v_PY := v_PY||get_greece_alphabet_py(n_ord_low-192);
END IF;
END IF;
ELSE
BEGIN
n_temp := n_ord_high-128;
n_ord_low := n_ord_low-63;
n_temp1 := trunc(n_temp/10,0);
n_temp1 := n_temp-n_temp1*10;
IF n_temp1=0 THEN
n_temp1 := 10;
END IF;
--DBMS_OUTPUT.PUT_LINE('n_temp = '||to_char(n_temp,'9999999'));
--DBMS_OUTPUT.PUT_LINE('n_temp1 = '||to_char(n_temp1,'9999999'));
CASE
WHEN n_temp<11 THEN
n_temp1 := get_py_index_01(n_temp1,n_ord_low);
WHEN n_temp<21 THEN
n_temp1 := get_py_index_02(n_temp1,n_ord_low);
WHEN n_temp<31 THEN
n_temp1 := get_py_index_03(n_temp1,n_ord_low);
WHEN n_temp<41 THEN
n_temp1 := get_py_index_04(n_temp1,n_ord_low);
WHEN n_temp<51 THEN
n_temp1 := get_py_index_05(n_temp1,n_ord_low);
WHEN n_temp<61 THEN
n_temp1 := get_py_index_06(n_temp1,n_ord_low);
WHEN n_temp<71 THEN
n_temp1 := get_py_index_07(n_temp1,n_ord_low);
WHEN n_temp<81 THEN
n_temp1 := get_py_index_08(n_temp1,n_ord_low);
WHEN n_temp<91 THEN
n_temp1 := get_py_index_09(n_temp1,n_ord_low);
WHEN n_temp<101 THEN
n_temp1 := get_py_index_10(n_temp1,n_ord_low);
WHEN n_temp<111 THEN
n_temp1 := get_py_index_11(n_temp1,n_ord_low);
WHEN n_temp<121 THEN
n_temp1 := get_py_index_12(n_temp1,n_ord_low);
WHEN n_temp<121 THEN
n_temp1 := get_py_index_13(n_temp1,n_ord_low);
ELSE
n_temp1 := 0;
END CASE;
v_PY := v_PY||GetHzPY_by_index(n_temp1);
END;
END CASE;
END IF;
END IF;
END LOOP;
RETURN Lower(v_PY);
--DBMS_OUTPUT.PUT_LINE(v_PY);
END; FUNCTION GetHzFullPYUpper(p_String varchar2)
RETURN VARCHAR2 IS
--declare
--p_String varchar2(200) := '???????';
v_char varchar2(2); --????
n_loop number; --??
n_len number; --????
n_ascii number; --??ASCII?
n_ord_high number; --n_ascii/156
n_ord_low number; --n mod 256
n_temp number;
n_temp1 number;
v_PY varchar2(32767); BEGIN
v_PY := '';
n_len := length(p_String);
FOR n_loop IN 1..n_len LOOP
v_char := substr(p_string,n_loop,1);
IF upper(v_char) IN (
'A','B','C','D','E','F','G',
'H','I','J','K','L','M','N',
'O','P','Q','R','S','T',
'U','V','W','X','Y','Z',
'0','1','2','3','4','5','6','7','8','9',
'(', ')', '[', ']','.', '!', '@', '#', '$',
'%', '^', '&', '*', '-', '+','<', '>', '?', ':', '"') THEN
v_PY := v_PY||v_char;
ELSE
n_ascii := ascii(v_char);
n_ord_high := trunc(n_ascii/256,0);
n_ord_low := n_ascii-(n_ord_high*256);
--DBMS_OUTPUT.PUT_LINE('n_ascii = '||to_char(n_ascii,'9999999'));
--DBMS_OUTPUT.PUT_LINE('n_ord_high = '||to_char(n_ord_high,'9999999'));
--DBMS_OUTPUT.PUT_LINE('n_ord_low = '||to_char(n_ord_low,'9999999'));
IF (n_ord_high>128) and (n_ord_low>63) THEN
CASE n_ord_high
WHEN 162 THEN --????
IF n_ord_low>160 THEN
v_PY := v_PY||get_roma_num_py(n_ord_low-160);
END IF;
WHEN 163 THEN --??ASCII
IF n_ord_low>128 THEN
v_char := chr(n_ord_low-128);
IF upper(v_char) IN (
'A','B','C','D','E','F','G',
'H','I','J','K','L','M','N',
'O','P','Q','R','S','T',
'U','V','W','X','Y','Z',
'0','1','2','3','4','5','6','7','8','9',
'(', ')', '[', ']') THEN
v_PY := v_PY||v_char;
END IF;
END IF;
WHEN 166 THEN --????
IF (n_ord_low>160) AND (n_ord_low<185) THEN --A1--B8
v_PY := v_PY||get_greece_alphabet_py(n_ord_low-160);
ELSE
IF (n_ord_low>192) AND (n_ord_low<217) THEN --C1--D8
v_PY := v_PY||get_greece_alphabet_py(n_ord_low-192);
END IF;
END IF;
ELSE
BEGIN
n_temp := n_ord_high-128;
n_ord_low := n_ord_low-63;
n_temp1 := trunc(n_temp/10,0);
n_temp1 := n_temp-n_temp1*10;
IF n_temp1=0 THEN
n_temp1 := 10;
END IF;
--DBMS_OUTPUT.PUT_LINE('n_temp = '||to_char(n_temp,'9999999'));
--DBMS_OUTPUT.PUT_LINE('n_temp1 = '||to_char(n_temp1,'9999999'));
CASE
WHEN n_temp<11 THEN
n_temp1 := get_py_index_01(n_temp1,n_ord_low);
WHEN n_temp<21 THEN
n_temp1 := get_py_index_02(n_temp1,n_ord_low);
WHEN n_temp<31 THEN
n_temp1 := get_py_index_03(n_temp1,n_ord_low);
WHEN n_temp<41 THEN
n_temp1 := get_py_index_04(n_temp1,n_ord_low);
WHEN n_temp<51 THEN
n_temp1 := get_py_index_05(n_temp1,n_ord_low);
WHEN n_temp<61 THEN
n_temp1 := get_py_index_06(n_temp1,n_ord_low);
WHEN n_temp<71 THEN
n_temp1 := get_py_index_07(n_temp1,n_ord_low);
WHEN n_temp<81 THEN
n_temp1 := get_py_index_08(n_temp1,n_ord_low);
WHEN n_temp<91 THEN
n_temp1 := get_py_index_09(n_temp1,n_ord_low);
WHEN n_temp<101 THEN
n_temp1 := get_py_index_10(n_temp1,n_ord_low);
WHEN n_temp<111 THEN
n_temp1 := get_py_index_11(n_temp1,n_ord_low);
WHEN n_temp<121 THEN
n_temp1 := get_py_index_12(n_temp1,n_ord_low);
WHEN n_temp<121 THEN
n_temp1 := get_py_index_13(n_temp1,n_ord_low);
ELSE
n_temp1 := 0;
END CASE;
v_PY := v_PY||GetHzPY_by_index(n_temp1);
END;
END CASE;
END IF;
END IF;
END LOOP;
RETURN Upper(v_PY);
--DBMS_OUTPUT.PUT_LINE(v_PY);
END GetHzFullPYUpper; FUNCTION GetHzFullPYsubstr(p_String varchar2,s float, e float)
RETURN VARCHAR2 IS
--declare
--p_String varchar2(200) := '???????';
v_char varchar2(2); --????
n_loop number; --??
n_len number; --????
n_ascii number; --??ASCII?
n_ord_high number; --n_ascii/156
n_ord_low number; --n mod 256
n_temp number;
n_temp1 number;
v_PY varchar2(32767); BEGIN
v_PY := '';
n_len := length(p_String);
FOR n_loop IN 1..n_len LOOP
v_char := substr(p_string,n_loop,1);
IF upper(v_char) IN (
'A','B','C','D','E','F','G',
'H','I','J','K','L','M','N',
'O','P','Q','R','S','T',
'U','V','W','X','Y','Z',
'0','1','2','3','4','5','6','7','8','9',
'(', ')', '[', ']','.', '!', '@', '#', '$',
'%', '^', '&', '*', '-', '+','<', '>', '?', ':', '"') THEN
v_PY := v_PY||v_char;
ELSE
n_ascii := ascii(v_char);
n_ord_high := trunc(n_ascii/256,0);
n_ord_low := n_ascii-(n_ord_high*256);
--DBMS_OUTPUT.PUT_LINE('n_ascii = '||to_char(n_ascii,'9999999'));
--DBMS_OUTPUT.PUT_LINE('n_ord_high = '||to_char(n_ord_high,'9999999'));
--DBMS_OUTPUT.PUT_LINE('n_ord_low = '||to_char(n_ord_low,'9999999'));
IF (n_ord_high>128) and (n_ord_low>63) THEN
CASE n_ord_high
WHEN 162 THEN --????
IF n_ord_low>160 THEN
v_PY := v_PY||get_roma_num_py(n_ord_low-160);
END IF;
WHEN 163 THEN --??ASCII
IF n_ord_low>128 THEN
v_char := chr(n_ord_low-128);
IF upper(v_char) IN (
'A','B','C','D','E','F','G',
'H','I','J','K','L','M','N',
'O','P','Q','R','S','T',
'U','V','W','X','Y','Z',
'0','1','2','3','4','5','6','7','8','9',
'(', ')', '[', ']') THEN
v_PY := v_PY||v_char;
END IF;
END IF;
WHEN 166 THEN --????
IF (n_ord_low>160) AND (n_ord_low<185) THEN --A1--B8
v_PY := v_PY||get_greece_alphabet_py(n_ord_low-160);
ELSE
IF (n_ord_low>192) AND (n_ord_low<217) THEN --C1--D8
v_PY := v_PY||get_greece_alphabet_py(n_ord_low-192);
END IF;
END IF;
ELSE
BEGIN
n_temp := n_ord_high-128;
n_ord_low := n_ord_low-63;
n_temp1 := trunc(n_temp/10,0);
n_temp1 := n_temp-n_temp1*10;
IF n_temp1=0 THEN
n_temp1 := 10;
END IF;
--DBMS_OUTPUT.PUT_LINE('n_temp = '||to_char(n_temp,'9999999'));
--DBMS_OUTPUT.PUT_LINE('n_temp1 = '||to_char(n_temp1,'9999999'));
CASE
WHEN n_temp<11 THEN
n_temp1 := get_py_index_01(n_temp1,n_ord_low);
WHEN n_temp<21 THEN
n_temp1 := get_py_index_02(n_temp1,n_ord_low);
WHEN n_temp<31 THEN
n_temp1 := get_py_index_03(n_temp1,n_ord_low);
WHEN n_temp<41 THEN
n_temp1 := get_py_index_04(n_temp1,n_ord_low);
WHEN n_temp<51 THEN
n_temp1 := get_py_index_05(n_temp1,n_ord_low);
WHEN n_temp<61 THEN
n_temp1 := get_py_index_06(n_temp1,n_ord_low);
WHEN n_temp<71 THEN
n_temp1 := get_py_index_07(n_temp1,n_ord_low);
WHEN n_temp<81 THEN
n_temp1 := get_py_index_08(n_temp1,n_ord_low);
WHEN n_temp<91 THEN
n_temp1 := get_py_index_09(n_temp1,n_ord_low);
WHEN n_temp<101 THEN
n_temp1 := get_py_index_10(n_temp1,n_ord_low);
WHEN n_temp<111 THEN
n_temp1 := get_py_index_11(n_temp1,n_ord_low);
WHEN n_temp<121 THEN
n_temp1 := get_py_index_12(n_temp1,n_ord_low);
WHEN n_temp<121 THEN
n_temp1 := get_py_index_13(n_temp1,n_ord_low);
ELSE
n_temp1 := 0;
END CASE;
v_PY := v_PY||GetHzPY_by_index(n_temp1);
END;
END CASE;
END IF;
END IF;
END LOOP;
RETURN substr(v_PY,s,e);
--DBMS_OUTPUT.PUT_LINE(v_PY);
END GetHzFullPYsubstr; FUNCTION GetHzPYCAP(p_String varchar2) RETURN VARCHAR2 IS
--declare
--p_String varchar2(200) := '???????';
v_char varchar2(2); --????
n_loop number; --??
n_len number; --????
n_ascii number; --??ASCII?
n_ord_high number; --n_ascii/156
n_ord_low number; --n mod 256
n_temp number;
n_temp1 number;
v_PY varchar2(32767); BEGIN
v_PY := '';
n_len := length(p_String);
FOR n_loop IN 1..n_len LOOP
v_char := substr(p_string,n_loop,1);
IF upper(v_char) IN (
'A','B','C','D','E','F','G',
'H','I','J','K','L','M','N',
'O','P','Q','R','S','T',
'U','V','W','X','Y','Z',
'0','1','2','3','4','5','6','7','8','9',
'(', ')', '[', ']','.', '!', '@', '#', '$',
'%', '^', '&', '*', '-', '+','<', '>', '?', ':', '"') THEN
v_PY := v_PY||v_char;
ELSE
n_ascii := ascii(v_char);
n_ord_high := trunc(n_ascii/256,0);
n_ord_low := n_ascii-(n_ord_high*256);
--DBMS_OUTPUT.PUT_LINE('n_ascii = '||to_char(n_ascii,'9999999'));
--DBMS_OUTPUT.PUT_LINE('n_ord_high = '||to_char(n_ord_high,'9999999'));
--DBMS_OUTPUT.PUT_LINE('n_ord_low = '||to_char(n_ord_low,'9999999'));
IF (n_ord_high>128) and (n_ord_low>63) THEN
CASE n_ord_high
WHEN 162 THEN --????
IF n_ord_low>160 THEN
v_PY := v_PY||get_roma_num_py(n_ord_low-160);
END IF;
WHEN 163 THEN --??ASCII
IF n_ord_low>128 THEN
v_char := chr(n_ord_low-128);
IF upper(v_char) IN (
'A','B','C','D','E','F','G',
'H','I','J','K','L','M','N',
'O','P','Q','R','S','T',
'U','V','W','X','Y','Z',
'0','1','2','3','4','5','6','7','8','9',
'(', ')', '[', ']') THEN
v_PY := v_PY||v_char;
END IF;
END IF;
WHEN 166 THEN --????
IF (n_ord_low>160) AND (n_ord_low<185) THEN --A1--B8
v_PY := v_PY||get_greece_alphabet_py(n_ord_low-160);
ELSE
IF (n_ord_low>192) AND (n_ord_low<217) THEN --C1--D8
v_PY := v_PY||get_greece_alphabet_py(n_ord_low-192);
END IF;
END IF;
ELSE
BEGIN
n_temp := n_ord_high-128;
n_ord_low := n_ord_low-63;
n_temp1 := trunc(n_temp/10,0);
n_temp1 := n_temp-n_temp1*10;
IF n_temp1=0 THEN
n_temp1 := 10;
END IF;
--DBMS_OUTPUT.PUT_LINE('n_temp = '||to_char(n_temp,'9999999'));
--DBMS_OUTPUT.PUT_LINE('n_temp1 = '||to_char(n_temp1,'9999999'));
CASE
WHEN n_temp<11 THEN
n_temp1 := get_py_index_01(n_temp1,n_ord_low);
WHEN n_temp<21 THEN
n_temp1 := get_py_index_02(n_temp1,n_ord_low);
WHEN n_temp<31 THEN
n_temp1 := get_py_index_03(n_temp1,n_ord_low);
WHEN n_temp<41 THEN
n_temp1 := get_py_index_04(n_temp1,n_ord_low);
WHEN n_temp<51 THEN
n_temp1 := get_py_index_05(n_temp1,n_ord_low);
WHEN n_temp<61 THEN
n_temp1 := get_py_index_06(n_temp1,n_ord_low);
WHEN n_temp<71 THEN
n_temp1 := get_py_index_07(n_temp1,n_ord_low);
WHEN n_temp<81 THEN
n_temp1 := get_py_index_08(n_temp1,n_ord_low);
WHEN n_temp<91 THEN
n_temp1 := get_py_index_09(n_temp1,n_ord_low);
WHEN n_temp<101 THEN
n_temp1 := get_py_index_10(n_temp1,n_ord_low);
WHEN n_temp<111 THEN
n_temp1 := get_py_index_11(n_temp1,n_ord_low);
WHEN n_temp<121 THEN
n_temp1 := get_py_index_12(n_temp1,n_ord_low);
WHEN n_temp<121 THEN
n_temp1 := get_py_index_13(n_temp1,n_ord_low);
ELSE
n_temp1 := 0;
END CASE;
v_PY := v_PY||substr(GetHzPY_by_index(n_temp1),1,1);
END;
END CASE;
END IF;
END IF;
END LOOP;
RETURN v_PY;
--DBMS_OUTPUT.PUT_LINE(v_PY);
END GetHzPYCAP; FUNCTION GetHzPYCAPLower(p_String varchar2) RETURN VARCHAR2 IS
--declare
--p_String varchar2(200) := '???????';
v_char varchar2(2); --????
n_loop number; --??
n_len number; --????
n_ascii number; --??ASCII?
n_ord_high number; --n_ascii/156
n_ord_low number; --n mod 256
n_temp number;
n_temp1 number;
v_PY varchar2(32767); BEGIN
v_PY := '';
n_len := length(p_String);
FOR n_loop IN 1..n_len LOOP
v_char := substr(p_string,n_loop,1);
IF upper(v_char) IN (
'A','B','C','D','E','F','G',
'H','I','J','K','L','M','N',
'O','P','Q','R','S','T',
'U','V','W','X','Y','Z',
'0','1','2','3','4','5','6','7','8','9',
'(', ')', '[', ']','.', '!', '@', '#', '$',
'%', '^', '&', '*', '-', '+','<', '>', '?', ':', '"') THEN
v_PY := v_PY||v_char;
ELSE
n_ascii := ascii(v_char);
n_ord_high := trunc(n_ascii/256,0);
n_ord_low := n_ascii-(n_ord_high*256);
--DBMS_OUTPUT.PUT_LINE('n_ascii = '||to_char(n_ascii,'9999999'));
--DBMS_OUTPUT.PUT_LINE('n_ord_high = '||to_char(n_ord_high,'9999999'));
--DBMS_OUTPUT.PUT_LINE('n_ord_low = '||to_char(n_ord_low,'9999999'));
IF (n_ord_high>128) and (n_ord_low>63) THEN
CASE n_ord_high
WHEN 162 THEN --????
IF n_ord_low>160 THEN
v_PY := v_PY||get_roma_num_py(n_ord_low-160);
END IF;
WHEN 163 THEN --??ASCII
IF n_ord_low>128 THEN
v_char := chr(n_ord_low-128);
IF upper(v_char) IN (
'A','B','C','D','E','F','G',
'H','I','J','K','L','M','N',
'O','P','Q','R','S','T',
'U','V','W','X','Y','Z',
'0','1','2','3','4','5','6','7','8','9',
'(', ')', '[', ']') THEN
v_PY := v_PY||v_char;
END IF;
END IF;
WHEN 166 THEN --????
IF (n_ord_low>160) AND (n_ord_low<185) THEN --A1--B8
v_PY := v_PY||get_greece_alphabet_py(n_ord_low-160);
ELSE
IF (n_ord_low>192) AND (n_ord_low<217) THEN --C1--D8
v_PY := v_PY||get_greece_alphabet_py(n_ord_low-192);
END IF;
END IF;
ELSE
BEGIN
n_temp := n_ord_high-128;
n_ord_low := n_ord_low-63;
n_temp1 := trunc(n_temp/10,0);
n_temp1 := n_temp-n_temp1*10;
IF n_temp1=0 THEN
n_temp1 := 10;
END IF;
--DBMS_OUTPUT.PUT_LINE('n_temp = '||to_char(n_temp,'9999999'));
--DBMS_OUTPUT.PUT_LINE('n_temp1 = '||to_char(n_temp1,'9999999'));
CASE
WHEN n_temp<11 THEN
n_temp1 := get_py_index_01(n_temp1,n_ord_low);
WHEN n_temp<21 THEN
n_temp1 := get_py_index_02(n_temp1,n_ord_low);
WHEN n_temp<31 THEN
n_temp1 := get_py_index_03(n_temp1,n_ord_low);
WHEN n_temp<41 THEN
n_temp1 := get_py_index_04(n_temp1,n_ord_low);
WHEN n_temp<51 THEN
n_temp1 := get_py_index_05(n_temp1,n_ord_low);
WHEN n_temp<61 THEN
n_temp1 := get_py_index_06(n_temp1,n_ord_low);
WHEN n_temp<71 THEN
n_temp1 := get_py_index_07(n_temp1,n_ord_low);
WHEN n_temp<81 THEN
n_temp1 := get_py_index_08(n_temp1,n_ord_low);
WHEN n_temp<91 THEN
n_temp1 := get_py_index_09(n_temp1,n_ord_low);
WHEN n_temp<101 THEN
n_temp1 := get_py_index_10(n_temp1,n_ord_low);
WHEN n_temp<111 THEN
n_temp1 := get_py_index_11(n_temp1,n_ord_low);
WHEN n_temp<121 THEN
n_temp1 := get_py_index_12(n_temp1,n_ord_low);
WHEN n_temp<121 THEN
n_temp1 := get_py_index_13(n_temp1,n_ord_low);
ELSE
n_temp1 := 0;
END CASE;
v_PY := v_PY||substr(GetHzPY_by_index(n_temp1),1,1);
END;
END CASE;
END IF;
END IF;
END LOOP;
RETURN Lower(v_PY);
--DBMS_OUTPUT.PUT_LINE(v_PY);
END GetHzPYCAPLower; FUNCTION GetHzPYCAPsubstr(p_String varchar2,s float, e float)
RETURN VARCHAR2 IS
--declare
--p_String varchar2(200) := '???????';
v_char varchar2(2); --????
n_loop number; --??
n_len number; --????
n_ascii number; --??ASCII?
n_ord_high number; --n_ascii/156
n_ord_low number; --n mod 256
n_temp number;
n_temp1 number;
v_PY varchar2(32767); BEGIN
v_PY := '';
n_len := length(p_String);
FOR n_loop IN 1..n_len LOOP
v_char := substr(p_string,n_loop,1);
IF upper(v_char) IN (
'A','B','C','D','E','F','G',
'H','I','J','K','L','M','N',
'O','P','Q','R','S','T',
'U','V','W','X','Y','Z',
'0','1','2','3','4','5','6','7','8','9',
'(', ')', '[', ']','.', '!', '@', '#', '$',
'%', '^', '&', '*', '-', '+','<', '>', '?', ':', '"') THEN
v_PY := v_PY||v_char;
ELSE
n_ascii := ascii(v_char);
n_ord_high := trunc(n_ascii/256,0);
n_ord_low := n_ascii-(n_ord_high*256);
--DBMS_OUTPUT.PUT_LINE('n_ascii = '||to_char(n_ascii,'9999999'));
--DBMS_OUTPUT.PUT_LINE('n_ord_high = '||to_char(n_ord_high,'9999999'));
--DBMS_OUTPUT.PUT_LINE('n_ord_low = '||to_char(n_ord_low,'9999999'));
IF (n_ord_high>128) and (n_ord_low>63) THEN
CASE n_ord_high
WHEN 162 THEN --????
IF n_ord_low>160 THEN
v_PY := v_PY||get_roma_num_py(n_ord_low-160);
END IF;
WHEN 163 THEN --??ASCII
IF n_ord_low>128 THEN
v_char := chr(n_ord_low-128);
IF upper(v_char) IN (
'A','B','C','D','E','F','G',
'H','I','J','K','L','M','N',
'O','P','Q','R','S','T',
'U','V','W','X','Y','Z',
'0','1','2','3','4','5','6','7','8','9',
'(', ')', '[', ']') THEN
v_PY := v_PY||v_char;
END IF;
END IF;
WHEN 166 THEN --????
IF (n_ord_low>160) AND (n_ord_low<185) THEN --A1--B8
v_PY := v_PY||get_greece_alphabet_py(n_ord_low-160);
ELSE
IF (n_ord_low>192) AND (n_ord_low<217) THEN --C1--D8
v_PY := v_PY||get_greece_alphabet_py(n_ord_low-192);
END IF;
END IF;
ELSE
BEGIN
n_temp := n_ord_high-128;
n_ord_low := n_ord_low-63;
n_temp1 := trunc(n_temp/10,0);
n_temp1 := n_temp-n_temp1*10;
IF n_temp1=0 THEN
n_temp1 := 10;
END IF;
--DBMS_OUTPUT.PUT_LINE('n_temp = '||to_char(n_temp,'9999999'));
--DBMS_OUTPUT.PUT_LINE('n_temp1 = '||to_char(n_temp1,'9999999'));
CASE
WHEN n_temp<11 THEN
n_temp1 := get_py_index_01(n_temp1,n_ord_low);
WHEN n_temp<21 THEN
n_temp1 := get_py_index_02(n_temp1,n_ord_low);
WHEN n_temp<31 THEN
n_temp1 := get_py_index_03(n_temp1,n_ord_low);
WHEN n_temp<41 THEN
n_temp1 := get_py_index_04(n_temp1,n_ord_low);
WHEN n_temp<51 THEN
n_temp1 := get_py_index_05(n_temp1,n_ord_low);
WHEN n_temp<61 THEN
n_temp1 := get_py_index_06(n_temp1,n_ord_low);
WHEN n_temp<71 THEN
n_temp1 := get_py_index_07(n_temp1,n_ord_low);
WHEN n_temp<81 THEN
n_temp1 := get_py_index_08(n_temp1,n_ord_low);
WHEN n_temp<91 THEN
n_temp1 := get_py_index_09(n_temp1,n_ord_low);
WHEN n_temp<101 THEN
n_temp1 := get_py_index_10(n_temp1,n_ord_low);
WHEN n_temp<111 THEN
n_temp1 := get_py_index_11(n_temp1,n_ord_low);
WHEN n_temp<121 THEN
n_temp1 := get_py_index_12(n_temp1,n_ord_low);
WHEN n_temp<121 THEN
n_temp1 := get_py_index_13(n_temp1,n_ord_low);
ELSE
n_temp1 := 0;
END CASE;
v_PY := v_PY||substr(GetHzPY_by_index(n_temp1),1,1);
END;
END CASE;
END IF;
END IF;
END LOOP;
RETURN substr(v_PY,s,e);
--DBMS_OUTPUT.PUT_LINE(v_PY);
END GetHzPYCAPsubstr; FUNCTION F_TRANS_PINYIN_CAPITAL(P_NAME IN VARCHAR2) RETURN VARCHAR2 AS
V_COMPARE VARCHAR2(100);
V_RETURN VARCHAR2(4000);
FUNCTION F_NLSSORT(P_WORD IN VARCHAR2) RETURN VARCHAR2 AS
BEGIN
RETURN NLSSORT(P_WORD, 'NLS_SORT=SCHINESE_PINYIN_M');
END;
BEGIN
V_COMPARE := F_NLSSORT(SUBSTR(P_NAME, 1, 1));
IF V_COMPARE >= F_NLSSORT(' 吖 ') AND V_COMPARE <= F_NLSSORT('驁 ') THEN
V_RETURN := V_RETURN || 'A';
ELSIF V_COMPARE >= F_NLSSORT('八 ') AND V_COMPARE <= F_NLSSORT('簿 ') THEN
V_RETURN := V_RETURN || 'B';
ELSIF V_COMPARE >= F_NLSSORT('嚓 ') AND V_COMPARE <= F_NLSSORT('錯 ') THEN
V_RETURN := V_RETURN || 'C';
ELSIF V_COMPARE >= F_NLSSORT('咑 ') AND V_COMPARE <= F_NLSSORT('鵽 ') THEN
V_RETURN := V_RETURN || 'D';
ELSIF V_COMPARE >= F_NLSSORT('妸 ') AND V_COMPARE <= F_NLSSORT('樲 ') THEN
V_RETURN := V_RETURN || 'E';
ELSIF V_COMPARE >= F_NLSSORT('发 ') AND V_COMPARE <= F_NLSSORT('猤 ') THEN
V_RETURN := V_RETURN || 'F';
ELSIF V_COMPARE >= F_NLSSORT('旮 ') AND V_COMPARE <= F_NLSSORT('腂 ') THEN
V_RETURN := V_RETURN || 'G';
ELSIF V_COMPARE >= F_NLSSORT('妎 ') AND V_COMPARE <= F_NLSSORT('夻 ') THEN
V_RETURN := V_RETURN || 'H';
ELSIF V_COMPARE >= F_NLSSORT('丌 ') AND V_COMPARE <= F_NLSSORT('攈 ') THEN
V_RETURN := V_RETURN || 'J';
ELSIF V_COMPARE >= F_NLSSORT('咔 ') AND V_COMPARE <= F_NLSSORT('穒 ') THEN
V_RETURN := V_RETURN || 'K';
ELSIF V_COMPARE >= F_NLSSORT('垃 ') AND V_COMPARE <= F_NLSSORT('擽 ') THEN
V_RETURN := V_RETURN || 'L';
ELSIF V_COMPARE >= F_NLSSORT('嘸 ') AND V_COMPARE <= F_NLSSORT('椧 ') THEN
V_RETURN := V_RETURN || 'M';
ELSIF V_COMPARE >= F_NLSSORT('拏 ') AND V_COMPARE <= F_NLSSORT('瘧 ') THEN
V_RETURN := V_RETURN || 'N';
ELSIF V_COMPARE >= F_NLSSORT('筽 ') AND V_COMPARE <= F_NLSSORT('漚 ') THEN
V_RETURN := V_RETURN || 'O';
ELSIF V_COMPARE >= F_NLSSORT('妑 ') AND V_COMPARE <= F_NLSSORT('曝 ') THEN
V_RETURN := V_RETURN || 'P';
ELSIF V_COMPARE >= F_NLSSORT('七 ') AND V_COMPARE <= F_NLSSORT('裠 ') THEN
V_RETURN := V_RETURN || 'Q';
ELSIF V_COMPARE >= F_NLSSORT('亽 ') AND V_COMPARE <= F_NLSSORT('鶸 ') THEN
V_RETURN := V_RETURN || 'R';
ELSIF V_COMPARE >= F_NLSSORT('仨 ') AND V_COMPARE <= F_NLSSORT('蜶 ') THEN
V_RETURN := V_RETURN || 'S';
ELSIF V_COMPARE >= F_NLSSORT('侤 ') AND V_COMPARE <= F_NLSSORT('籜 ') THEN
V_RETURN := V_RETURN || 'T';
ELSIF V_COMPARE >= F_NLSSORT('屲 ') AND V_COMPARE <= F_NLSSORT('鶩 ') THEN
V_RETURN := V_RETURN || 'W';
ELSIF V_COMPARE >= F_NLSSORT('夕 ') AND V_COMPARE <= F_NLSSORT('鑂 ') THEN
V_RETURN := V_RETURN || 'X';
ELSIF V_COMPARE >= F_NLSSORT('丫 ') AND V_COMPARE <= F_NLSSORT('韻 ') THEN
V_RETURN := V_RETURN || 'Y';
ELSIF V_COMPARE >= F_NLSSORT('帀 ') AND V_COMPARE <= F_NLSSORT('咗 ') THEN
V_RETURN := V_RETURN || 'Z';
END IF;
RETURN V_RETURN;
END F_TRANS_PINYIN_CAPITAL; --begin
-- Initialization
--<Statement>;
end;
/
create or replace PACKAGE PKG_FUNC AS
--定义1970年1月1日8点时间常量
START_DATE CONSTANT DATE:=TO_DATE('1970-01-01 08:00:00','YYYY-MM-DD HH24:MI:SS'); --表类型
TYPE TYPE_STRLIST IS TABLE OF VARCHAR2(4000); --功能:将字符串按照指定分割字符分割成记录集
FUNCTION SPLITSTR(pSTR IN VARCHAR2,pSEP IN VARCHAR2:=',') RETURN TYPE_STRLIST PIPELINED; --功能:时间日期转换成距离1970-01-01的秒数
FUNCTION DATE_TO_SECOND(pDATE IN DATE) RETURN INT; --功能:距离1970-01-01的秒数转换成时间日期
FUNCTION SECOND_TO_DATE(pSECOND IN INT) RETURN DATE; --功能:传递字符串参数,返回格式化替换后的时间日期参数
FUNCTION DATE_FORMAT(pDATE IN VARCHAR,pTYPE IN NUMBER) RETURN DATE; --功能:获取两个日期的差值(输入为字符串类型)
FUNCTION DATEDIFF(
Datepart In Varchar2,
StartDate In Varchar2,
EndDate In Varchar2
)
Return VARCHAR2; --功能:获取两个日期的差值(输入为日期类型)
FUNCTION DATEDIFF(
Datepart In Varchar2,
StartDate In DATE,
EndDate In DATE
)
Return VARCHAR2;
END;
/
create or replace PACKAGE BODY PKG_FUNC AS
FUNCTION SPLITSTR
--功能:将字符串按照指定分割字符分割成记录集
--参数:pSTR-字符串,pSEP-指定分割字符,默认为','
--调用:SELECT * FROM TABLE(PKG_FUNC.SPLITSTR('1,2,3,4,5,6,7,8,9,10',','))
--日期:2013-03-03
(
pSTR IN VARCHAR2,
pSEP IN VARCHAR2:=','
)
RETURN TYPE_STRLIST PIPELINED
IS
L_IDX PLS_INTEGER;
V_LIST VARCHAR2(4000):=pSTR;
BEGIN
LOOP
L_IDX := INSTR(V_LIST,pSEP);
IF L_IDX > 0 THEN
PIPE ROW(SUBSTR(V_LIST,1,L_IDX-1));
V_LIST := SUBSTR(V_LIST,L_IDX+LENGTH(pSEP));
ELSE
PIPE ROW(V_LIST);
EXIT;
END IF;
END LOOP;
RETURN;
END; FUNCTION DATE_TO_SECOND
--功能:时间日期转换成距离1970-01-01的秒数
--参数:pDATE-日期格式参数
--调用:SELECT PKG_FUNC.DATE_TO_SECOND(SYSDATE) FROM DUAL;
--日期:2013-03-03
(
pDATE IN DATE
)
RETURN INT
IS
pSECOND INT;
BEGIN
SELECT TRUNC((pDATE-START_DATE)*86400) INTO pSECOND FROM DUAL;
RETURN pSECOND;
END; FUNCTION SECOND_TO_DATE
--功能:距离1970-01-01的秒数转换成时间日期
--参数:pDATE-传递日期格式参数
--调用:SELECT PKG_FUNC.SECOND_TO_DATE(1398733775) FROM DUAL;
--日期:2013-02-17
(
pSECOND IN INT
)
RETURN DATE
IS
pDATE DATE;
BEGIN
SELECT START_DATE+pSECOND/86400 INTO pDATE FROM DUAL;
RETURN pDATE;
END; FUNCTION DATE_FORMAT
--功能:传递字符串参数,返回格式化替换后的时间日期参数
--参数:pDATE-字符串参数,pTYPE-不同类型进行相应处理
--调用:SELECT PKG_FUNC.DATE_FORMAT('',2) FROM DUAL
--日期:2013-02-17
(
pDATE IN VARCHAR,
pTYPE IN NUMBER --处理类别 0:时间可为空 1:最小时间,2:最大时间,其它:系统当前时间
)
--------------------------------------------------------------------------------------
--0-返回的日期时间可为空
--1-返回的日期时间不为空,若传入参数为空,则转换为最小时间
--2-返回的日期时间不为空,若传入参数为空,则转换为最大时间
--其它-返回的日期时间不为空,若传入参数为空,则转换为系统当前时间
RETURN DATE
IS
RTN DATE;
BEGIN
SELECT DECODE(pTYPE,0,TO_DATE(TRIM(pDATE),'YYYY-MM-DD HH24:MI:SS'),
1,TO_DATE(NVL(TRIM(pDATE),'0001-01-01'),'YYYY-MM-DD HH24:MI:SS'),
2,TO_DATE(NVL(TRIM(pDATE),'9999-12-31'),'YYYY-MM-DD HH24:MI:SS'),
NVL(TO_DATE(TRIM(pDATE),'YYYY-MM-DD HH24:MI:SS'),SYSDATE))
INTO RTN FROM DUAL;
RETURN RTN;
END; FUNCTION DATEDIFF
--功能:获取两个日期的差值(输入为字符串类型)
--参数:Datepart-返回间隔时间类型,StartDate-开始日期,EndDate-结束日期
--调用:SELECT PKG_FUNC.DATEDIFF('','2012-01-01','2010-01-01') FROM DUAL
--日期:2017-03-04
(
Datepart In Varchar2,
StartDate In Varchar2,
EndDate In Varchar2
)
Return VARCHAR2
IS
v_DAY VARCHAR2(200);
v_HOUR VARCHAR2(200);
v_MINUTE VARCHAR2(200);
v_SECOND VARCHAR2(200);
ReallyDo VARCHAR2(200);
Begin
SELECT EXTRACT(
DAY FROM (TO_DATE(StartDate, 'YYYY-MM-DD HH24:MI:SS')-
TO_DATE(EndDate, 'YYYY-MM-DD HH24:MI:SS'))
DAY(9) TO SECOND ) INTO v_DAY FROM DUAL;
SELECT EXTRACT(
HOUR FROM (TO_DATE(StartDate, 'YYYY-MM-DD HH24:MI:SS')-
TO_DATE(EndDate, 'YYYY-MM-DD HH24:MI:SS'))
DAY(9) TO SECOND ) INTO v_HOUR FROM DUAL;
SELECT EXTRACT(
MINUTE FROM (TO_DATE(StartDate, 'YYYY-MM-DD HH24:MI:SS')-
TO_DATE(EndDate, 'YYYY-MM-DD HH24:MI:SS'))
DAY(9) TO SECOND ) INTO v_MINUTE FROM DUAL;
SELECT EXTRACT(
SECOND FROM (TO_DATE(StartDate, 'YYYY-MM-DD HH24:MI:SS')-
TO_DATE(EndDate, 'YYYY-MM-DD HH24:MI:SS'))
DAY(9) TO SECOND ) INTO v_SECOND FROM DUAL;
ReallyDo:=v_DAY||'天'||v_HOUR||'小时'||v_MINUTE||'分'||v_SECOND||'秒';
SELECT DECODE(Datepart,'DAY',v_DAY,'D',v_DAY,'HOUR',v_HOUR,'H',v_HOUR,'MINUTE',v_MINUTE,'M',v_MINUTE,'SECOND',v_SECOND,'S',v_SECOND,ReallyDo) INTO ReallyDo FROM DUAL;
Return ReallyDo;
End; FUNCTION DATEDIFF
--功能:获取两个日期的差值(输入为日期类型)
--参数:Datepart-返回间隔时间类型,StartDate-开始日期,EndDate-结束日期
--调用:SELECT PKG_FUNC.DATEDIFF('','2012-01-01','2010-01-01') FROM DUAL
--日期:2017-03-04
(
Datepart In Varchar2,
StartDate In DATE,
EndDate In DATE
)
Return VARCHAR2
IS
v_DAY VARCHAR2(200);
v_HOUR VARCHAR2(200);
v_MINUTE VARCHAR2(200);
v_SECOND VARCHAR2(200);
ReallyDo VARCHAR2(200);
Begin
SELECT EXTRACT(
DAY FROM (StartDate-EndDate)
DAY(9) TO SECOND ) INTO v_DAY FROM DUAL;
SELECT EXTRACT(
HOUR FROM (StartDate-EndDate)
DAY(9) TO SECOND ) INTO v_HOUR FROM DUAL;
SELECT EXTRACT(
MINUTE FROM (StartDate-EndDate)
DAY(9) TO SECOND ) INTO v_MINUTE FROM DUAL;
SELECT EXTRACT(
SECOND FROM (StartDate-EndDate)
DAY(9) TO SECOND ) INTO v_SECOND FROM DUAL;
ReallyDo:=v_DAY||'天'||v_HOUR||'小时'||v_MINUTE||'分'||v_SECOND||'秒';
SELECT DECODE(Datepart,'DAY',v_DAY,'D',v_DAY,'HOUR',v_HOUR,'H',v_HOUR,'MINUTE',v_MINUTE,'M',v_MINUTE,'SECOND',v_SECOND,'S',v_SECOND,ReallyDo) INTO ReallyDo FROM DUAL;
Return ReallyDo;
End;
END;
/
CREATE OR REPLACE PACKAGE PKG_ANALYZE
AS
----定义过滤的表差异数量的对象
TYPE CHETABLECOUNT IS RECORD
(
TABLE_NAME VARCHAR2(40),
DELETECOUNT NUMBER(10),
INSERTCOUNT NUMBER(10),
UPDATECOUNT NUMBER(10)
); --定义过滤的表差异数量集合类型
TYPE CHETABLECOUNTLIST IS TABLE OF CHETABLECOUNT; --获取差异的表记录数量集合
FUNCTION GET_TABLE_COUNT(
pLINKNAME IN VARCHAR, --链接名
pCHECKTABLELIST IN CHECKTABLELIST --源过滤的表类型
)
RETURN CHETABLECOUNTLIST PIPELINED; --获取差异的表记录数量集合
PROCEDURE CHECK_MERGE_COUNT(
pLINKNAME IN VARCHAR, --链接名
pCHECKTABLELIST IN CHECKTABLELIST, --源过滤的表类型
pCURSOR OUT SYS_REFCURSOR
); --功能:获取当前的redo size日志大小
FUNCTION NOW_REDO_SIZE RETURN NUMBER; --功能:开启日志分析,计算初始redo size大小
PROCEDURE START_REDO; --功能:计算生成的日志大小
FUNCTION GET_REDO_SIZE RETURN NUMBER; --功能:查询当前数据库谁在运行什么SQL语句
PROCEDURE SESSION_RUN_SQL(pCURSOR OUT SYS_REFCURSOR); --功能:查询使用CPU多的用户SESSION
PROCEDURE SESSION_CPU_COST(pCURSOR OUT SYS_REFCURSOR); --功能:查询影响性能的SQL语句
PROCEDURE SQL_IO_COST(pCURSOR OUT SYS_REFCURSOR); --功能:分析存储过程、函数(或者包中的存储过程、函数)参数信息
PROCEDURE GET_ARGUMENTS(
DBUSER IN VARCHAR2:=USER,
pPACKAGENAME IN VARCHAR2:=NULL,
pOBJNAME IN VARCHAR2:=NULL,
pCURSOR OUT SYS_REFCURSOR
); --功能:统计分析用户下的单表/索引或者全库表/索引,为NULL则分析全库表/索引,多个对象以','分隔
PROCEDURE ANALYZE_TABLEANDINDEX(DBUSER IN VARCHAR2:=USER,pOBJNAME IN VARCHAR2:=NULL); --功能:分析数据库中单表或所有表产生行迁移和行连接的记录,为NULL则分析全库表,多个表以','分隔
PROCEDURE ANALYZE_CHAINED_ROWS(DBUSER IN VARCHAR2:=USER,pOBJNAME IN VARCHAR2:=NULL); --功能:查询表行数、索引块大小、数据块大小占用情况,为NULL则查询全库表,多个表以','分隔,数据块包含表、分区表、LOB段空间,索引块包含普通索引、分区索引、LOB段索引
PROCEDURE TABLE_ROWSANDSPACE(
DBUSER IN VARCHAR2:=USER,
pOBJNAME IN VARCHAR2:=NULL,
pCURSOR OUT SYS_REFCURSOR
); PROCEDURE VIEW_COUNT(
DBUSER IN VARCHAR2:=USER,
pTBNAME IN VARCHAR2:=NULL,
pCURSOR OUT SYS_REFCURSOR
); --功能:检测设计后的表行总长度是否超过当前所在的表空间最小单元数据块大小(若超过,可能产生行连接),为NULL则查询全库表,多个表以','分隔
PROCEDURE ROW_CHARLENGTH(
DBUSER IN VARCHAR2:=USER,
pOBJNAME IN VARCHAR2:=NULL,
pCURSOR OUT SYS_REFCURSOR
); --功能:检测哪些表中的列名称采用系统关键字(可能引起不必要的错误,如Ora-01747:user.table.column,tabel.coulmn或列说明无效)
PROCEDURE CHECK_COLNAMEISKEYWORD(DBUSER IN VARCHAR2:=USER,pCURSOR OUT SYS_REFCURSOR); --功能:检测数据库中外键上未建立索引的情况
PROCEDURE CHECK_FOREIGNINDEX(DBUSER IN VARCHAR2:=USER,pCURSOR OUT SYS_REFCURSOR); --功能:检测数据库中外键依赖列的类型、长度、小数位与主键列不一致的情况,这可能在其他数据库(如SQL SERVER)中由于严格限制无法建立外键关联
PROCEDURE CHECK_KEYRELATIONTYPE(DBUSER IN VARCHAR2:=USER,pCURSOR OUT SYS_REFCURSOR); --功能:检测数据库中未建立主键或者唯一约束的情况
PROCEDURE CHECK_NOPRIMARY(DBUSER IN VARCHAR:=USER,pCURSOR OUT SYS_REFCURSOR); --功能:返回查询目标库与链接源库表的差异或相同部分的SQL语句
PROCEDURE GET_COMPARETEXT(
pTAG IN NUMBER, --查询模式:1-求同(交集),2-求异(补集)
pLINKNAME IN VARCHAR, --链接名
pTABLENAME IN VARCHAR2:=NULL, --源表,可以为一张或多张表,多个表以','分隔,为空则选择所有表
pMODE IN NUMBER:=1, --匹配模式
pSELTEXT OUT VARCHAR2
); --功能:查询目标库与源库表的差异部分(如果目标表中存在主键相同记录,则同步类型为'UPDATE',不存在则同步类型为'INSERT',目标表中存在而源表中不存在则同步类型为'DELETE')
PROCEDURE CHECK_MERGE_MINUS(
pSOURCETB IN VARCHAR, --源表名,如果为远程链接表,类似为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-只比较基础数据类型,如VARCHAR2、NUMBER、DATE等,
--2-在1基础上比较数据类型的长度和精度,
--3-在2基础上比较列能否为空
AS
pUSER VARCHAR2(200):=USER;
pSELECT VARCHAR2(1000);
pFROM VARCHAR2(1000);
pLINKFROM VARCHAR2(1000);
pOUTCOL VARCHAR2(100);
pSELTYPE VARCHAR2(50);
BEGIN
pSELECT:=Q'{SELECT A.TABLE_NAME AS TABLENAME,B.COLUMN_NAME AS COLUMNNAME,DATA_TYPE,
CASE DATA_TYPE
WHEN 'NUMBER' THEN
CASE NVL(TO_CHAR(B.DATA_SCALE),'0')
WHEN '0' THEN 'INT'
ELSE 'DECIMAL('||NVL(TO_CHAR(B.DATA_PRECISION),'18')||','||B.DATA_SCALE||')'
END
WHEN 'VARCHAR2' THEN 'VARCHAR('||B.CHAR_LENGTH||')'
WHEN 'DATE' THEN 'DATETIME'
WHEN 'BLOB' THEN 'VARBINARY(4000)'
WHEN 'LONG' THEN 'VARCHAR(4000)'
ELSE B.DATA_TYPE
END AS SQLTYPE,
CASE DATA_TYPE
WHEN 'NUMBER' THEN REPLACE(B.DATA_TYPE||'('||NVL(TO_CHAR(B.DATA_PRECISION),'*')||','||NVL(TO_CHAR(B.DATA_SCALE),'*')||')','(*,*)','')
WHEN 'VARCHAR2' THEN B.DATA_TYPE||'('||B.CHAR_LENGTH||')'
ELSE B.DATA_TYPE
END AS ORACLETYPE,
CASE B.NULLABLE WHEN 'Y' THEN 'NULL' ELSE 'NOT NULL' END AS ISNULLABLE,
COLUMN_ID AS COLUMN_ID
FROM }';
pFROM:='SYS.DBA_TABLES A JOIN SYS.DBA_TAB_COLUMNS B ON (A.TABLE_NAME=B.TABLE_NAME AND A.OWNER=B.OWNER) WHERE A.OWNER='''||pUSER
||''' AND (INSTR('',''||'''|| pTABLENAME||'''||'','','',''||A.TABLE_NAME||'','',1)>0 OR '''||pTABLENAME||
''' IS NULL) AND A.TEMPORARY=''N'' ORDER BY TABLENAME,COLUMN_ID'; --查询本地表
pLINKFROM:='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-只比较基础数据类型,如VARCHAR2、NUMBER、DATE等,
--2-在1基础上比较数据类型的长度和精度,
--3-在2基础上比较列能否为空
AS
pSQLTEXT VARCHAR2(4000);
BEGIN
GET_COMPARETEXT(2,pLINKNAME,pTABLENAME,pMODE,pSQLTEXT);
OPEN pCURSOR FOR pSQLTEXT;
END; PROCEDURE CHECK_INTERSECT
--功能:查询目标库与链接源库表的相同部分(求交集)
--参数:
--调用:
/*
DECLARE pCURSOR SYS_REFCURSOR;
BEGIN
PKG_ANALYZE.CHECK_INTERSECT('DATABASE_LINK1','DEV_INFOEXTAB',3,pCURSOR);
END;
*/
--日期:2013-04-1
(
pLINKNAME IN VARCHAR, --链接名
pTABLENAME IN VARCHAR2:=NULL, --源表,可以为一张或多张表,多个表以','分隔,为空则选择所有表
pMODE IN NUMBER:=1, --匹配模式
pCURSOR OUT SYS_REFCURSOR --返回链接库、目标库*有的部分
)
--匹配模式:
--1-只比较基础数据类型,如VARCHAR2、NUMBER、DATE等,
--2-在1基础上比较数据类型的长度和精度,
--3-在2基础上比较列能否为空
AS
pSQLTEXT VARCHAR2(4000);
BEGIN
GET_COMPARETEXT(1,pLINKNAME,pTABLENAME,pMODE,pSQLTEXT);
OPEN pCURSOR FOR pSQLTEXT;
END; PROCEDURE CHECK_DISTINCT
--功能:查询对比目标库与链接源库表数据对比具有相同列数据的部分(如查询重复列数据)
--参数:
--调用:
/*
DECLARE pCURSOR SYS_REFCURSOR;
BEGIN
PKG_ANALYZE.CHECK_DISTINCT('DATABASE_LINK1','DEV_INFOEXTAB','DEVICENAME,DEVICETYPE,DEVICEMODEL,DEVICESN,DEVICEVER,PRODUCTCOMPANY,PRODUCTLINKPERSON,PRODUCTLINKTEL,
BUILDCOMPANY,BUILDTEL,BUILDLINKPERSON,DEVICEAREA,DEVICEPLACE,LINKPERSON,LINKTEL,LINKMOBILE,LINKEMAIL',pCURSOR);
END;
*/
--日期:2013-04-9
(
pLINKNAME IN VARCHAR, --链接名
pTABLENAME IN VARCHAR2, --表名
pCOLNAME IN VARCHAR2, --匹配列名,多个列以逗号分隔
pCURSOR OUT SYS_REFCURSOR --返回链接库、目标库*有的部分
)
AS
pCOLLIST VARCHAR2(2000);
pSQLTEXT VARCHAR2(2000);
BEGIN
SELECT LISTAGG('LOWER(A.'||A.COL||')=LOWER(B.'||A.COL||')',' AND ') WITHIN GROUP(ORDER BY A.ROWN) INTO pCOLLIST FROM (
SELECT ROWNUM AS ROWN,UPPER(regexp_substr(pCOLNAME,'[^,]+',1,LEVEL)) AS COL FROM DUAL
CONNECT BY LEVEL<=LENGTH(pCOLNAME)-LENGTH(REPLACE(pCOLNAME,',',''))+1
) A;
pSQLTEXT:='SELECT * FROM '||pTABLENAME||' A WHERE EXISTS ('||CHR(10)||
'SELECT * FROM '||pTABLENAME||'@'||pLINKNAME||' b WHERE '||pCOLLIST||')';
--SYS.DBMS_OUTPUT.PUT_LINE('/*SQL语句:*/'||pSQLTEXT);
OPEN pCURSOR FOR pSQLTEXT;
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
END;
/
create or replace PACKAGE PKG_MERGE
AS
--功能:同步目标表和源表数据一致
PROCEDURE MERGE_TABLE(
pTARGETTB IN VARCHAR2, --表示目标表,只能为单表名称
pSOURCETB IN VARCHAR2, --表示源表,可为单表、单视图、多表、多视图连接查询的结果集
pTARGETWHERE IN VARCHAR2, --目标表条件列,多个列以','分隔.列数和顺序与源表条件列一致
pSOURCEWHERE IN VARCHAR2, --源表条件列,多个列以','分隔.列数和顺序与目标表条件列一致
pTARGETCOL IN VARCHAR2, --目标表记录操作列,多个列以','分隔.列数和顺序与源表记录操作列一致
pSOURCECOL IN VARCHAR2 --源表记录操作列,多个列以','分隔.列数和顺序与目标表记录操作条件列一致;
); --功能:同步表,条件为主键和唯一约束进行匹配
PROCEDURE MERGE_TABLE(
pTARGETTB IN VARCHAR2, --表示目标表,只能为单表名称
pSOURCETB IN VARCHAR2, --表示源表,只能为单表名称,源表和目标表结构和类型保持一致
pKEY IN VARCHAR2:=NULL, --匹配条件,多列以逗号分隔
pMODE IN NUMBER:=1, --如果记录在目的数据库上存在而在源数据库表中不存在,处理方式:1-删除目的数据库中的记录、其他-不予操作
pMSG OUT NUMBER --返回消息,1-同步成功,-1:失败,-2:无主键和唯一约束
); --功能:同步表,条件为主键和唯一约束进行匹配,源数据库来自远程链接
PROCEDURE MERGE_LINK_TABLE(
pLINKNAME IN VARCHAR2, --链接名
pTBLIST IN VARCHAR2:=NULL, --表示目标表,可以为一张或多张表,多个表以','分隔
pMODE IN NUMBER:=1, --如果记录在目的数据库上存在而在源数据库表中不存在,处理方式:1-删除目的数据库中的记录、其他-不予操作
pMSG OUT NUMBER, --返回消息,1-同步成功,-1:失败,-2:无主键和唯一约束
pFILTER IN VARCHAR2:=NULL --条件过滤
); --功能:同步表,条件为主键和唯一约束进行匹配,源数据库来自远程链接,目标数据库也来自远程链接
PROCEDURE MERGE_TWOLINK(
pSOURCELINK IN VARCHAR2, --链接源数据库的链接名
pTARGETLINK IN VARCHAR2, --链接目的数据库的链接名
pTBLIST IN VARCHAR2:=NULL, --表示目标表,可以为一张或多张表,多个表以','分隔
pMODE IN NUMBER:=1, --如果记录在目的数据库上存在而在源数据库表中不存在,处理方式:1-删除目的数据库中的记录、其他-不予操作
pMSG OUT NUMBER --返回消息,1-同步成功,-1:失败,-2:无主键和唯一约束
); --功能:同步表数据(支持低版本数据源往同版本或高版本目标库同步,同时也支持高版本数据源往低版本目标库同步)
PROCEDURE MERGE_INTERSECT(
pLINKNAME IN VARCHAR2, --链接名
pTABLENAME IN VARCHAR2:=NULL, --源表,可以为一张或多张表,多个表以','分隔,为空则选择结构类型一致的所有表
pMODE IN NUMBER:=1 --匹配模式
); --功能:同步本地数据库表,根据列名相同原则来匹配,pTABLENAME为NULL则同步所有表的记录,不为NULL则同步一个或多个表的记录,多个表以','分隔
PROCEDURE MERGE_FROM_DB(
pLINKNAME IN VARCHAR2, --链接名
pTABLENAME IN VARCHAR2:=NULL, --链接数据库同步表,多个表以','分隔
pTABLEEXIXTS IN VARCHAR2:='DELETE' --本地表存在的处理方式
); --功能:同步链接数据库表,根据列名相同原则来匹配,pTABLENAME为NULL则同步所有表的记录,不为NULL则同步一个或多个表的记录,多个表以','分隔
PROCEDURE MERGE_TO_DB(
pLINKNAME IN VARCHAR2, --链接名
pTABLENAME IN VARCHAR2:=NULL, --本地数据库同步表,多个表以','分隔
pTABLEEXIXTS IN VARCHAR2:='DELETE' --链接表存在的处理方式:'DELETE'-直接删除表数据再添加、'APPEND'-追加
);
END;
/
create or replace PACKAGE BODY PKG_MERGE
AS
PROCEDURE MERGE_TABLE
--功能:同步表
--参数:见下方说明
--调用:EXECUTE PKG_MERGE.MERGE_TABLE('DEV_INFOEXTAB','DEV_INFOTAB','DEVICENAME','DEVICENAME','DEVICEID','DEVICEID');
--日期:2013-02-10
(
pTARGETTB IN VARCHAR2, --表示目标表,只能为单表名称
pSOURCETB IN VARCHAR2, --表示源表,可为单表、单视图、多表、多视图连接查询的结果集
pTARGETWHERE IN VARCHAR2, --目标表条件列,多个列以','分隔.列数和顺序与源表条件列一致
pSOURCEWHERE IN VARCHAR2, --源表条件列,多个列以','分隔.列数和顺序与目标表条件列一致
pTARGETCOL IN VARCHAR2, --目标表记录操作列,多个列以','分隔.列数和顺序与源表记录操作列一致
pSOURCECOL IN VARCHAR2 --源表记录操作列,多个列以','分隔.列数和顺序与目标表记录操作条件列一致
)
AS
pUSESOURCE VARCHAR2(4000); --拼接源表结果集,如果是单表可以直接为表名,否则必须用'()'进行包装查询语句
pWHERE VARCHAR2(4000); --拼接MERGER同步源表与目标表的匹配WHERE条件
pUPDATECOL VARCHAR2(4000); --拼接MERGER同步源表与目标表的修改列
pINSERTCOL VARCHAR2(4000); --拼接MERGER同步源表与目标表的添加列
pSQL VARCHAR2(4000); --拼接MERGER同步的完整SQL语句
BEGIN
SELECT DECODE(INSTR(TRIM(UPPER(pSOURCETB)),'SELECT'),1,'('||pSOURCETB||')',pSOURCETB) INTO pUSESOURCE FROM DUAL;--拼接源表结果集
SELECT LISTAGG('S.'||A.COL||'=T.'||B.COL,' AND ') WITHIN GROUP(ORDER BY A.ROWN) INTO pWHERE
FROM (SELECT ROWNUM AS ROWN,UPPER(regexp_substr(pSOURCEWHERE,'[^,]+',1,LEVEL)) AS COL FROM DUAL
CONNECT BY LEVEL<=LENGTH(pSOURCEWHERE)-LENGTH(REPLACE(pSOURCEWHERE,',',''))+1) A
JOIN (SELECT ROWNUM AS ROWN,UPPER(regexp_substr(pTARGETWHERE,'[^,]+',1,LEVEL)) AS COL FROM DUAL
CONNECT BY LEVEL<=LENGTH(pTARGETWHERE)-LENGTH(REPLACE(pTARGETWHERE,',',''))+1) B ON A.ROWN=B.ROWN; --拼接MERGER同步源表与目标表的匹配WHERE条件
SELECT LISTAGG(A.COL||'=T.'||B.COL,',') WITHIN GROUP(ORDER BY A.ROWN) INTO pUPDATECOL
FROM (SELECT ROWNUM AS ROWN,UPPER(regexp_substr(pSOURCECOL,'[^,]+',1,LEVEL)) AS COL FROM DUAL
CONNECT BY LEVEL<=LENGTH(pSOURCECOL)-LENGTH(REPLACE(pSOURCECOL,',',''))+1) A
JOIN (SELECT ROWNUM AS ROWN,UPPER(regexp_substr(pTARGETCOL,'[^,]+',1,LEVEL)) AS COL FROM DUAL
CONNECT BY LEVEL<=LENGTH(pTARGETCOL)-LENGTH(REPLACE(pTARGETCOL,',',''))+1) B ON A.ROWN=B.ROWN; --拼接MERGER同步源表与目标表的修改列
SELECT 'T.'||REPLACE(pSOURCEWHERE||','||pSOURCECOL,',',',T.') INTO pINSERTCOL FROM DUAL; --拼接MERGER同步源表与目标表的添加列
pSQL:='MERGE INTO '||pTARGETTB||' S'||CHR(10)||
'USING '||pUSESOURCE||' T'||CHR(10)||
'ON('||pWHERE||')'||CHR(10)||
' WHEN MATCHED THEN'||CHR(10)||
' UPDATE SET '||pUPDATECOL||CHR(10)||
' WHEN NOT MATCHED THEN'||CHR(10)||
' INSERT ('||pTARGETWHERE||','||pTARGETCOL||')'||' VALUES('||pINSERTCOL||')'; --拼接MERGER同步的完整SQL语句
--SYS.DBMS_OUTPUT.PUT_LINE('/*SQL语句:*/'||pSQL);
EXECUTE IMMEDIATE pSQL;
COMMIT;
EXCEPTION
WHEN OTHERS THEN
SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'同步表数据异常:' ||SQLERRM);
END; PROCEDURE MERGE_TABLE
--功能:同步表,条件为主键和唯一约束进行匹配
--参数:见下方说明
--调用:
/*
DECLARE pMSG NUMBER(2);
BEGIN
PKG_MERGE.MERGE_TABLE('DATABASE_LINK1','USR_ROLETAB',1,pMSG);
DBMS_OUTPUT.PUT_LINE('同步消息:'||pMSG);
END;
*/
--日期:2014-05-13
(
pTARGETTB IN VARCHAR2, --表示目标表,只能为单表名称
pSOURCETB IN VARCHAR2, --表示源表,只能为单表名称,源表和目标表结构和类型保持一致
pKEY IN VARCHAR2:=NULL, --匹配条件,多列以逗号分隔
pMODE IN NUMBER:=1, --如果记录在目的数据库上存在而在源数据库表中不存在,处理方式:1-删除目的数据库中的记录、其他-不予操作
pMSG OUT NUMBER --返回消息,1-同步成功,-1:失败,-2:无主键和唯一约束
)
AS
pWHERE VARCHAR2(4000); --拼接MERGER同步源表与目标表的匹配WHERE条件
pUPDATECOL VARCHAR2(4000); --拼接MERGER同步源表与目标表的修改列
pINSERTCOL VARCHAR2(4000); --拼接MERGER同步源表与目标表的添加列
pSQL VARCHAR2(4000); --拼接MERGER同步的完整SQL语句
PROCEDURE MERGE_NOCONSTRA
AS
BEGIN
IF pKEY IS NOT NULL THEN
SELECT DISTINCT LISTAGG('S."'||COLUMN_VALUE||'"=T."'||COLUMN_VALUE||'"',' AND ')
WITHIN GROUP(ORDER BY 1) OVER() INTO pWHERE FROM (
SELECT * FROM TABLE(PKG_FUNC.SPLITSTR(pKEY))
);
ELSE
SELECT DISTINCT LISTAGG('S."'||B.COLUMN_NAME||'"=T."'||B.COLUMN_NAME||'"',' AND ')
WITHIN GROUP(ORDER BY B.POSITION) OVER(PARTITION BY A.INDEX_NAME) INTO pWHERE FROM SYS.USER_CONSTRAINTS A
JOIN SYS.USER_CONS_COLUMNS B ON (A.owner=b.owner AND A.table_name=b.table_name AND A.constraint_name=B.constraint_name)
WHERE A.TABLE_NAME=pTARGETTB AND A.CONSTRAINT_TYPE='P';
END IF;
EXCEPTION
WHEN NO_DATA_FOUND THEN
pMSG:=1; --无主键和唯一约束则直接添加,2014-08-02修改为去掉唯一约束判定
pSQL:='INSERT INTO '||pTARGETTB||' SELECT * FROM '||pSOURCETB;
--SYS.DBMS_OUTPUT.PUT_LINE(pSQL);
EXECUTE IMMEDIATE pSQL;
--SYS.DBMS_OUTPUT.PUT_LINE('同步无主键和唯一约束的表'||pTARGETTB||'数据成功!');
WHEN OTHERS THEN
pMSG:=-1; --同步失败
--SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'同步无主键和唯一约束的表'||pTARGETTB||'数据异常:' ||SQLERRM);
END;
BEGIN
pWHERE:='';
pUPDATECOL:='';
pINSERTCOL:='';
MERGE_NOCONSTRA; --判断表中是否有主键、唯一约束,如果不存在则直接添加表数据,否则跳过直接进行下一步操作,2014-08-02修改为去掉唯一约束判定
IF pWHERE IS NOT NULL THEN
FOR Y IN
(
SELECT DISTINCT * FROM ( SELECT TA.COLUMN_NAME,TB.COLUMN_NAME AS CONS_COL FROM SYS.USER_TAB_COLUMNS TA
LEFT JOIN(
SELECT A.TABLE_NAME,B.COLUMN_NAME FROM SYS.USER_CONSTRAINTS A
JOIN SYS.USER_CONS_COLUMNS B ON (A.owner=b.owner AND A.table_name=b.table_name AND A.constraint_name=B.constraint_name)
WHERE A.TABLE_NAME=pTARGETTB AND A.CONSTRAINT_TYPE='P'
) TB ON (TA.TABLE_NAME=TB.TABLE_NAME AND TA.COLUMN_NAME=TB.COLUMN_NAME)
WHERE TA.TABLE_NAME=pTARGETTB ORDER BY TA.COLUMN_ID)
) --2014-08-02修改为条件为主键匹配
LOOP
IF Y.CONS_COL IS NULL THEN
pUPDATECOL:=pUPDATECOL||'"'||Y.COLUMN_NAME||'"=T."'||Y.COLUMN_NAME||'",';
END IF;
pINSERTCOL:=pINSERTCOL||',"'||Y.COLUMN_NAME||'"';
END LOOP;
pUPDATECOL:=RTRIM(pUPDATECOL,',');
pSQL:='MERGE INTO '||pTARGETTB||' S'||CHR(10)||
'USING '||pSOURCETB||' T'||CHR(10)||
'ON('||pWHERE||')'||CHR(10);
IF pUPDATECOL IS NOT NULL THEN
pSQL:=pSQL||' WHEN MATCHED THEN'||CHR(10)||
' UPDATE SET '||RTRIM(pUPDATECOL,',')||CHR(10);
END IF;
pSQL:=pSQL||' WHEN NOT MATCHED THEN'||CHR(10)||
' INSERT ('||LTRIM(REPLACE(pINSERTCOL,',',',S.'),',')||')'||' VALUES('||LTRIM(REPLACE(pINSERTCOL,',',',T.'),',')||')';
--SYS.DBMS_OUTPUT.PUT_LINE(pSQL);
EXECUTE IMMEDIATE pSQL;
--SYS.DBMS_OUTPUT.PUT_LINE(pSQL);
IF pMODE=1 THEN --如果记录在目的数据库上存在而在源数据库表中不存在,删除目的数据库中的记录
pSQL:='DELETE FROM '||pTARGETTB||' T WHERE NOT EXISTS(SELECT * FROM '||pSOURCETB||' S WHERE '||pWHERE||')';--删除在目标表中存在而在源表不存在的数据
EXECUTE IMMEDIATE pSQL;
--SYS.DBMS_OUTPUT.PUT_LINE(pSQL);
END IF;
END IF;
pMSG:=1; --同步成功
COMMIT;
EXCEPTION
WHEN OTHERS THEN
pMSG:=-1; --同步失败
SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'同步表数据异常:' ||SQLERRM);
END; PROCEDURE MERGE_LINK_TABLE
--功能:同步表,条件为主键和唯一约束进行匹配,源数据库来自远程链接,2014-08-02修改为去掉唯一约束判定
--参数:见下方说明
--调用:
/*
DECLARE pMSG NUMBER(2);
BEGIN
PKG_MERGE.MERGE_LINK_TABLE('DATABASE_LINK1','USR_ROLETAB',1,pMSG,null);
DBMS_OUTPUT.PUT_LINE('同步消息:'||pMSG);
END;
*/
--日期:2014-05-13
(
pLINKNAME IN VARCHAR2, --链接名
pTBLIST IN VARCHAR2:=NULL, --表示目标表,可以为一张或多张表,多个表以','分隔
pMODE IN NUMBER:=1, --如果记录在目的数据库上存在而在源数据库表中不存在,处理方式:1-删除目的数据库中的记录、其他-不予操作
pMSG OUT NUMBER, --返回消息,1-同步成功,-1:失败,-2:无主键和唯一约束
pFILTER IN VARCHAR2:=NULL --条件过滤
)
AS
pSINGLETBNAME VARCHAR2(50); --保存当前表名
pCLONETBNAME VARCHAR2(50); --中间表名称
pWHERE VARCHAR2(4000); --拼接MERGER同步源表与目标表的匹配WHERE条件
pUPDATECOL VARCHAR2(4000); --拼接MERGER同步源表与目标表的修改列
pINSERTCOL VARCHAR2(4000); --拼接MERGER同步源表与目标表的添加列
pSQL VARCHAR2(4000); --拼接MERGER同步的完整SQL语句
PROCEDURE MERGE_NOCONSTRA
AS
BEGIN
--条件为主键、所有唯一约束、所有唯一索引共同匹配,防止出现违反唯一约束或主键冲突
-- SELECT DISTINCT LISTAGG('('||WHERELIST||')',' OR ') WITHIN GROUP(ORDER BY INDEX_NAME) OVER() INTO pWHERE FROM(
-- SELECT DISTINCT A.INDEX_NAME,
-- LISTAGG('S."'||B.COLUMN_NAME||'"=T."'||B.COLUMN_NAME||'"',' AND ')
-- WITHIN GROUP(ORDER BY B.COLUMN_POSITION) OVER(PARTITION BY A.INDEX_NAME) AS WHERELIST FROM SYS.USER_INDEXES A
-- JOIN SYS.USER_IND_COLUMNS B ON (A.TABLE_NAME=B.TABLE_NAME AND A.INDEX_NAME=B.INDEX_NAME)
-- WHERE A.TABLE_NAME=pSINGLETBNAME AND A.TABLE_TYPE='TABLE' AND A.UNIQUENESS='UNIQUE');
--2014-08-02修改:当主键字段已存在,唯一约束字段值不同时不会进行同步,故去掉唯一约束、唯一索引条件
SELECT DISTINCT LISTAGG('S."'||B.COLUMN_NAME||'"=T."'||B.COLUMN_NAME||'"',' AND ')
WITHIN GROUP(ORDER BY B.POSITION) OVER(PARTITION BY A.INDEX_NAME) INTO pWHERE FROM SYS.USER_CONSTRAINTS A
JOIN SYS.USER_CONS_COLUMNS B ON (A.owner=b.owner AND A.table_name=b.table_name AND A.constraint_name=B.constraint_name)
WHERE A.TABLE_NAME=pSINGLETBNAME AND A.CONSTRAINT_TYPE='P';
EXCEPTION
WHEN NO_DATA_FOUND THEN
pMSG:=1; --无主键和唯一约束则直接添加,2014-08-02修改为去掉唯一约束判定
pSQL:='INSERT INTO '||pSINGLETBNAME||' SELECT * FROM '||pSINGLETBNAME||'@'||pLINKNAME||' '||pFILTER;
EXECUTE IMMEDIATE pSQL;
--SYS.DBMS_OUTPUT.PUT_LINE('同步无主键和唯一约束的表'||pSINGLETBNAME||'数据成功!');
WHEN OTHERS THEN
pMSG:=-1; --同步失败
--SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'同步无主键和唯一约束的表'||pSINGLETBNAME||'数据异常:' ||SQLERRM);
END;
BEGIN
FOR X IN
(
SELECT LEVEL AS RN,REGEXP_SUBSTR(UPPER(pTBLIST),'[^,]+',1,LEVEL) AS TBNAME FROM DUAL
CONNECT BY LEVEL<LENGTH(pTBLIST)-LENGTH(REPLACE(pTBLIST,','))+2
)
LOOP
pSINGLETBNAME:=X.TBNAME;
pWHERE:='';
pUPDATECOL:='';
pINSERTCOL:='';
MERGE_NOCONSTRA; --判断表中是否有主键、唯一约束,如果不存在则直接添加表数据,否则跳过直接进行下一步操作,2014-08-02修改为去掉唯一约束判定
IF pWHERE IS NOT NULL THEN
-- FOR Y IN
-- (
-- SELECT DISTINCT * FROM ( SELECT TA.COLUMN_NAME,TB.COLUMN_NAME AS CONS_COL FROM SYS.USER_TAB_COLUMNS TA
-- LEFT JOIN(
-- SELECT A.TABLE_NAME,B.COLUMN_NAME FROM SYS.USER_INDEXES A
-- JOIN SYS.USER_IND_COLUMNS B ON (A.TABLE_NAME=B.TABLE_NAME AND A.INDEX_NAME=B.INDEX_NAME)
-- WHERE A.TABLE_TYPE='TABLE' AND A.UNIQUENESS='UNIQUE'
-- ) TB ON (TA.TABLE_NAME=TB.TABLE_NAME AND TA.COLUMN_NAME=TB.COLUMN_NAME)
-- WHERE TA.TABLE_NAME=pSINGLETBNAME ORDER BY TA.COLUMN_ID)
-- ) --条件为主键、所有唯一约束、所有唯一索引共同匹配,防止出现违反唯一约束或主键冲突,2014-08-02修改为去掉唯一约束判定
FOR Y IN
(
SELECT DISTINCT * FROM ( SELECT TA.COLUMN_NAME,TB.COLUMN_NAME AS CONS_COL FROM SYS.USER_TAB_COLUMNS TA
LEFT JOIN(
SELECT A.TABLE_NAME,B.COLUMN_NAME FROM SYS.USER_CONSTRAINTS A
JOIN SYS.USER_CONS_COLUMNS B ON (A.owner=b.owner AND A.table_name=b.table_name AND A.constraint_name=B.constraint_name)
WHERE A.TABLE_NAME=pSINGLETBNAME AND A.CONSTRAINT_TYPE='P'
) TB ON (TA.TABLE_NAME=TB.TABLE_NAME AND TA.COLUMN_NAME=TB.COLUMN_NAME)
WHERE TA.TABLE_NAME=pSINGLETBNAME ORDER BY TA.COLUMN_ID)
) --2014-08-02修改为条件为主键匹配
LOOP
IF Y.CONS_COL IS NULL THEN
pUPDATECOL:=pUPDATECOL||Y.COLUMN_NAME||'=T.'||Y.COLUMN_NAME||',';
END IF;
pINSERTCOL:=pINSERTCOL||','||Y.COLUMN_NAME;
END LOOP;
pUPDATECOL:=RTRIM(pUPDATECOL,',');
pSQL:='MERGE INTO '||pSINGLETBNAME||' S'||CHR(10)||
'USING (SELECT * FROM '||pSINGLETBNAME||'@'||pLINKNAME||' '||pFILTER||') T'||CHR(10)||
'ON('||pWHERE||')'||CHR(10);
IF pUPDATECOL IS NOT NULL THEN
pSQL:=pSQL||' WHEN MATCHED THEN'||CHR(10)||
' UPDATE SET '||RTRIM(pUPDATECOL,',')||CHR(10);
END IF;
pSQL:=pSQL||' WHEN NOT MATCHED THEN'||CHR(10)||
' INSERT ('||LTRIM(REPLACE(pINSERTCOL,',',',S.'),',')||')'||' VALUES('||LTRIM(REPLACE(pINSERTCOL,',',',T.'),',')||')';
EXECUTE IMMEDIATE pSQL;
--SYS.DBMS_OUTPUT.PUT_LINE(pSQL);
--SYS.DBMS_OUTPUT.PUT_LINE('同步'||pSINGLETBNAME||'表数据成功!');
IF pMODE=1 THEN --如果记录在目的数据库上存在而在源数据库表中不存在,删除目的数据库中的记录,采用传输数据到中间表的方式进行优化处理
pCLONETBNAME:='TMP_'||pSINGLETBNAME;
PKG_DBMANAGE.CLONE_TEMP_TB(pSINGLETBNAME,pCLONETBNAME); --克隆生成中间临时表
EXECUTE IMMEDIATE 'INSERT INTO '||pCLONETBNAME||' SELECT * FROM '||pSINGLETBNAME||'@'||pLINKNAME; --转储数据到中间表中
pSQL:='DELETE FROM '||pSINGLETBNAME||' T WHERE NOT EXISTS(SELECT * FROM '||pCLONETBNAME||' S WHERE '||pWHERE||')';--删除在目标表中存在而在中间表不存在的数据
EXECUTE IMMEDIATE pSQL;
END IF;
END IF;
END LOOP;
pMSG:=1; --同步成功
COMMIT;
EXCEPTION
WHEN OTHERS THEN
pMSG:=-1; --同步失败
--SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'同步表数据异常:' ||SQLERRM);
END; PROCEDURE MERGE_TWOLINK
--功能:同步表,条件为主键和唯一约束进行匹配,源数据库来自远程链接,目标数据库也来自远程链接
--参数:见下方说明
--调用:
/*
DECLARE pMSG NUMBER(2);
BEGIN
PKG_MERGE.MERGE_TWOLINK('DLIN11','DLINK2','USR_ROLETAB',1,pMSG);
DBMS_OUTPUT.PUT_LINE('同步消息:'||pMSG);
END;
*/
--日期:2014-10-30
(
pSOURCELINK IN VARCHAR2, --链接源数据库的链接名
pTARGETLINK IN VARCHAR2, --链接目的数据库的链接名
pTBLIST IN VARCHAR2:=NULL, --表示目标表,可以为一张或多张表,多个表以','分隔
pMODE IN NUMBER:=1, --如果记录在目的数据库上存在而在源数据库表中不存在,处理方式:1-删除目的数据库中的记录、其他-不予操作
pMSG OUT NUMBER --返回消息,1-同步成功,-1:失败,-2:无主键和唯一约束
)
AS
pSINGLETBNAME VARCHAR2(50); --保存当前表名
pCLONETBNAME VARCHAR2(50); --中间表名称
pTBSQL VARCHAR2(4000); --表记录查询SQL语句
pTBCURSOR SYS_REFCURSOR; --表记录游标
pCONSNAME VARCHAR2(100); --主键或者唯一约束名称
pCOLNAME VARCHAR2(100); --列名
pWHERE VARCHAR2(4000); --拼接MERGER同步源表与目标表的匹配WHERE条件
pUPDATECOL VARCHAR2(4000); --拼接MERGER同步源表与目标表的修改列
pINSERTCOL VARCHAR2(4000); --拼接MERGER同步源表与目标表的添加列
pSQL VARCHAR2(4000); --拼接MERGER同步的完整SQL语句
PROCEDURE MERGE_NOCONSTRA
AS
pSELTXT VARCHAR2(4000);
BEGIN
--条件为主键、所有唯一约束、所有唯一索引共同匹配,防止出现违反唯一约束或主键冲突
-- SELECT DISTINCT LISTAGG('('||WHERELIST||')',' OR ') WITHIN GROUP(ORDER BY INDEX_NAME) OVER() INTO pWHERE FROM(
-- SELECT DISTINCT A.INDEX_NAME,
-- LISTAGG('S."'||B.COLUMN_NAME||'"=T."'||B.COLUMN_NAME||'"',' AND ')
-- WITHIN GROUP(ORDER BY B.COLUMN_POSITION) OVER(PARTITION BY A.INDEX_NAME) AS WHERELIST FROM SYS.USER_INDEXES A
-- JOIN SYS.USER_IND_COLUMNS B ON (A.TABLE_NAME=B.TABLE_NAME AND A.INDEX_NAME=B.INDEX_NAME)
-- WHERE A.TABLE_NAME=pSINGLETBNAME AND A.TABLE_TYPE='TABLE' AND A.UNIQUENESS='UNIQUE');
--2014-08-02修改:当主键字段已存在,唯一约束字段值不同时不会进行同步,故去掉唯一约束、唯一索引条件
pSELTXT:='SELECT DISTINCT LISTAGG(''S."''||B.COLUMN_NAME||''"=T."''||B.COLUMN_NAME||''"'','' AND '')'||CHR(10)||
' WITHIN GROUP(ORDER BY B.POSITION) OVER(PARTITION BY A.INDEX_NAME) FROM 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-只比较基础数据类型,如VARCHAR2、NUMBER、DATE等,
--2-在1基础上比较数据类型的长度和精度,
--3-在2基础上比较列能否为空
AS
pUSER VARCHAR2(200):=USER;
pSQLTEXT VARCHAR2(4000);
TYPE pOBJTYPE IS RECORD
(
TABLENAME SYS.DBA_TABLES.TABLE_NAME%TYPE,
COLLIST VARCHAR2(4000)
) ;
TYPE pOBJTYPELIST IS TABLE OF pOBJTYPE INDEX BY PLS_INTEGER;
pTABCOLLIST pOBJTYPELIST;
pINSERTTEXT VARCHAR2(4000) ;
pRFECUR SYS_REFCURSOR;
pSINGLETBNAME SYS.DBA_TABLES.TABLE_NAME%TYPE;
BEGIN
PKG_ANALYZE.GET_COMPARETEXT(1,pLINKNAME,pTABLENAME,pMODE,pSQLTEXT); --建议使用非严格模式进行匹配
pSQLTEXT:='SELECT DISTINCT TABLENAME,LISTAGG(''"''||COLUMNNAME||''"'','','')'||
'WITHIN GROUP(ORDER BY 1) OVER(PARTITION BY TABLENAME) AS COLLIST FROM ('||pSQLTEXT||')';
OPEN pRFECUR FOR pSQLTEXT;
FETCH pRFECUR BULK COLLECT INTO pTABCOLLIST;
FOR L_ROW IN pTABCOLLIST.FIRST..pTABCOLLIST.LAST
LOOP
pSINGLETBNAME:=pTABCOLLIST(L_ROW).TABLENAME;
pINSERTTEXT:='INSERT INTO '||pSINGLETBNAME||'('||pTABCOLLIST(L_ROW).COLLIST||') SELECT '||pTABCOLLIST(L_ROW).COLLIST||
' FROM '||pSINGLETBNAME||'@'||pLINKNAME;
PKG_DBMANAGE.DELETE_TABLE(pUSER,pSINGLETBNAME) ; --清空本地数据库表记录
EXECUTE IMMEDIATE pINSERTTEXT; --同步链接库表数据到本地库表中
SYS.DBMS_OUTPUT.PUT_LINE('同步表:'||pSINGLETBNAME||'数据成功!') ;
END LOOP;
CLOSE pRFECUR;
EXCEPTION
WHEN OTHERS THEN
SYS.DBMS_OUTPUT.PUT_LINE(SYS.DBMS_UTILITY.FORMAT_ERROR_BACKTRACE||'同步表数据出错:'||SQLERRM||',发生在表:'||pSINGLETBNAME) ;
ROLLBACK;
END; PROCEDURE MERGE_FROM_DB
--功能:同步本地数据库表,根据列名相同原则来匹配,pTABLENAME为NULL则同步所有表的记录,不为NULL则同步一个或多个表的记录,多个表以','分隔
-- 注意:只能从低版本数据源往同版本或高版本目标库同步(即目标库中的表同名列数、类型大于或等于源表列数,同时目标库中不能存在不为空的新列,
-- 以保证可以兼容添加数据到目标库中,否则则可能同步出错)
--参数:见下方说明
--调用:EXECUTE PKG_MERGE.MERGE_FROM_DB('DBLINK');
--日期:2013-03-28
(
pLINKNAME IN VARCHAR2, --链接名
pTABLENAME IN VARCHAR2:=NULL, --本地数据库同步表,多个表以','分隔
pTABLEEXIXTS IN VARCHAR2:='DELETE' --本地表存在的处理方式
)
--本地表存在的处理方式:
--'RECOVER'-所有表全覆盖、
--'DROP'-先删除本地表再创建新表,表结构和数据与链接库表保持一致、
--'DELETE'-直接删除表数据再添加、'APPEND'-追加
AS
pCOLLIST VARCHAR2(32767);
pCOUNT1 PLS_INTEGER;
pCOUNT2 PLS_INTEGER;
pUSER VARCHAR2(200):=USER;
pSQLTEXT VARCHAR2(2000);
pRFECUR SYS_REFCURSOR;
pSINGLETBNAME SYS.DBA_TABLES.TABLE_NAME%TYPE;
BEGIN
IF pTABLEEXIXTS='RECOVER' THEN --模式选择为全覆盖
PKG_DBMANAGE.DROP_ALL_OBJECT(pUSER,8); --删除所有表
END IF;
pSQLTEXT:='SELECT TABLE_NAME FROM 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' 表示二进制类型附件
--注意:
-- 1、对于文本类型的附件,不能用base64的方式发送,否则出错
-- 2、对于多个附件只能用同一种格式发送
P_SERVER VARCHAR2, --邮件服务器地址,可以是域名或者IP
P_PORT NUMBER DEFAULT 25, --邮件服务器端口,默认国内未加密的SMTP端口为25
P_NEED_SMTP INT DEFAULT 0, --是否需要smtp认证,0表示不需要,1表示需要
P_USER VARCHAR2 DEFAULT NULL, --smtp验证需要的用户名
P_PASS VARCHAR2 DEFAULT NULL --smtp验证需要的密码
);
END;
/
CREATE OR REPLACE PACKAGE BODY PKG_MAIL
AS
PROCEDURE SEND_EMAIL
--功能:用oracle发送邮件
--参数:
--调用:
--日期:2017-03-05
(
P_SENDOR VARCHAR2, --发送人邮件地址
P_RECEIVER VARCHAR2, --接收人邮件地址,可以同时发送到多个地址上,地址之间用","或者";"隔开
P_SUB VARCHAR2, --邮件标题
P_CONTENT VARCHAR2, --邮件正文,可以为文本或者HTML。
p_CONTENTTYPE VARCHAR2, --邮件正文类型,1或者txt-表示文本,2或者html表示为html
P_FILENAME VARCHAR2 DEFAULT NULL, --附件名称,必须包含完整的路径,如"d:\temp\a.txt"。可以有多个附件,地址之间用","或者";"隔开
P_ENCODE VARCHAR2 DEFAULT 'bit 7', --附件编码转换格式,其中 p_encode='bit 7' 表示文本类型附件,p_encode='base64' 表示二进制类型附件
--注意:
-- 1、对于文本类型的附件,不能用base64的方式发送,否则出错
-- 2、对于多个附件只能用同一种格式发送
P_SERVER VARCHAR2, --邮件服务器地址,可以是域名或者IP
P_PORT NUMBER DEFAULT 25, --邮件服务器端口,默认国内未加密的SMTP端口为25
P_NEED_SMTP INT DEFAULT 0, --是否需要smtp认证,0表示不需要,1表示需要
P_USER VARCHAR2 DEFAULT NULL, --smtp验证需要的用户名
P_PASS VARCHAR2 DEFAULT NULL --smtp验证需要的密码
)
AS
/*
主要功能:1、支持多收件人。
2、支持中文
3、支持抄送人
4、支持大于32K的附件
5、支持多行正文
6、支持多附件
7、支持文本附件和二进制附件
8、支持HTML格式
注意:如果不是sys用户操作,需开启ACL权限,步骤如下:
BEGIN
DBMS_NETWORK_ACL_ADMIN.CREATE_ACL (
acl => 'email_server_permissions.xml',
description => 'Enables network permissions for the e-mail server',
principal => 'PKGTEST',--进行操作的数据库用户且用户要大写
is_grant => TRUE,
privilege => 'connect');
END; BEGIN
DBMS_NETWORK_ACL_ADMIN.assign_acl (
acl => 'email_server_permissions.xml',
host => 'smtp.mxhichina.com',
lower_port => 25,
upper_port => NULL);
COMMIT;
END; SELECT host, lower_port, upper_port, acl FROM sys.dba_network_acls; BEGIN
dbms_network_acl_admin.add_privilege(
acl => 'utlpkg.xml',
principal =>'PKGTEST',--进行操作的数据库用户且用户要大写
is_grant => TRUE,
privilege => 'connect');
END; SELECT acl,
principal,
privilege,
is_grant,
TO_CHAR(start_date, 'DD-MON-YYYY') AS start_date,
TO_CHAR(end_date, 'DD-MON-YYYY') AS end_date
FROM sys.dba_network_acl_privileges;
/*
/*
调用示例:测试采用新浪邮箱发送已通过
declare phtml varchar2(4000);
begin
phtml:=q'[
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Oracle导出HTML邮件</title>
<style type="text/css">
*{margin:0;padding:0}
body{width:867px; margin:0 auto;background:#2c383e url(images/bgindex.jpg) repeat-x;}
h2{text-align:center;height:50px;line-height:50px;letter-spacing:2px;}
#content{ width:580px; height:850px; float:left; background:#fff url(images/weline.gif) repeat-y left top; padding-left:20px;}
#content h1{background:url(images/job.gif) no-repeat left 20px; height:60px;text-indent:-9999px;}
#content table{width:540px;line-height:30px;font-size:12px; background:#ccc; border-collapse:collapse}
#content table tr {text-align:center; background:#fff}
#content table tr th{font-weight:normal; background:#eee;border:1px solid gray}
#content table tr:hover{background:#CC0}
#content table tr td{border:1px solid gray}
#content table tr td a{ text-decoration:none}
#content table tr td a:hover{ text-decoration:underline}
#content .contentp1{text-align:center; margin-top:30px; font-size:12px;margin-bottom:30px}
#content .contentp2{width:540px;font-size:12px;text-align:right;height:25px;line-height:25px}
</style>
</head>
<body>
<div id="content">
<h2>数据表格展示</h2>
<table>
<tr><th>序号</th><th>职位名称</th><th>招聘人数</th><th>工作地点</th><th>有效时间</th><th>职位描述</th></th>
<tr><td>1</td><td>保安人员</td><td>3至4人</td><td>武汉</td><td>2016.12.08</td><td><a href="#">查看</a></td></tr>
<tr><td>2</td><td>项目技术人员</td><td>18人</td><td>北京</td><td>2016.10.08</td><td><a href="#">查看</a></td></tr>
<tr><td>3</td><td>总经理助理</td><td>3人</td><td>温州</td><td>2016.07.11</td><td><a href="#">查看</a></td></tr>
<tr><td>4</td><td>销售代表</td><td>40人</td><td>温州</td><td>2016.07.11</td><td><a href="#">查看</a></td></tr>
<tr><td>5</td><td>客服</td><td>15人</td><td>温州</td><td>2016.07.11</td><td><a href="#">查看</a></td></tr>
</table>
<p class="contentp1">共计:5 条记录 页次:1/1 每页:5 条 上一页/下一页</p>
<p class="contentp2">来源:Oracle数据库</p>
<p class="contentp2">记录人:dkgll</p>
</div>
</body>
</html>
]';
PKG_MAIL.SEND_EMAIL('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;
/