PLSQL程序嵌入JAVA程序.docx
《PLSQL程序嵌入JAVA程序.docx》由会员分享,可在线阅读,更多相关《PLSQL程序嵌入JAVA程序.docx(13页珍藏版)》请在冰豆网上搜索。
PLSQL程序嵌入JAVA程序
众所周知,目前在国内最流行的开发语言是JAVA语言,虽然国外有更多流行的开发语言,JAVA仅是百花齐放中的一朵。
但对国内而言JAVA在近段时期内仍占据霸主地位,国内的开发水平一直是在应用级别,而非研究级别。
国内有着华丽外衣
的程序猿们也只是码农的级别,这也是导致大部分软件企业偏重于业务及架构人才。
09年SUN被ORACLE收购,也是否代表着JAVA衰落的开始,事实应该并非吧。
SUN公司的主打是大型服务器,JAVA只是SUN
公司的附带产品,更说白了初始只是一个码农JamesGosling的想法。
其实从ORACLE8版本开始,ORACLE开始提供对JAVA的
支持,随后的版本则继续增强了ORACLE数据库的JAVA性能,在ORACLE8I开始支持用JAVA编写存储过程。
PLSQL存储过程在数据处理方面确实是个卓越的创新,因为在以往的单会话状态下,每次执行只能支持单个SQL语句。
初做JAVA时,数据库从来都是被当做黑盒在使用,后来才知道有存储过程这个东东,在做JAVA开发时候只是通过CallableStatement
接口来调用过存储过程,也写过几个比较简单的存储过程。
后来做ORACLE数据库开发,过了最初上路的煎熬,慢慢的拆卸了下数据库
这个黑盒的一部分。
后来无意中看到一个简单的程序,HelloWorld这个应该是每个JAVA码农们的初恋吧,再回忆下这个println吧
packagepra;
/**
*java学习
*@authorhehe
*@versionpractise
*/
publicclassHelloWorld{
publicstaticvoidmain(String[]args){
System.out.println("HelloWorld!
");
}
也再回忆下当时很牛X,现在还依然感觉很酷的纯命令编译程序吧
编译带包的java类(以包名为pra,类名为HelloWorld为例):
javac-d.HelloWorld.java
运行带包的类:
javapra.HelloWorld
生成API文档(生成在docs文件夹下):
javadoc-d .\docsHelloWorld.java
生成带相应描述的API文档:
javadoc-version-author -d .\docsHelloWorld.java
打jar包:
jar-cvfpra.jar
解压jar包:
jar-xvfpra.jar
运行jar包中的类:
java-classpathpra.jarpra.HelloWorld或者java-cppra.jarpra.HelloWorld
在介绍PLSQL中嵌入JAVA程序编译输出HelloWorld之前,对钟爱于JAVA的码农们说句话:
"JAVA的魅力依旧是ORACLE取代不了的"
1.下面是个简单的PLSQL程序嵌入JAVA类并编译输出的代码。
CREATEORREPLACEANDCOMPILEJAVASOURCENAMEDHELLOWORLDAS
publicclassHelloWorld
{
publicstaticStringentry()
return"HelloWorld!
";
CREATEORREPLACEFUNCTIONFU_HELLOWORLDRETURNVARCHAR2
ASLANGUAGEJAVA
NAME'HelloWorld.entry()returnjava.lang.String';
SELECTFU_HELLOWORLDFROMDUAL;
2.PLSQL对数据的强大处理功能是毋庸置疑的,但在应用级别还是有居多限制,不过ORACLE官方提供了许多功能还不错的内置包。
现在先来介绍下后续功能的核心包UTL_FILE,ORACLE提供的内置包,包含多种过程及方法,可以实现目录(DIRECTORYORACLE不能
访问操作系统级的文件夹,需要创建特定目录才能够访问)下的文件读取写入,具体实现加密,无从了解其实现原理,其应用可以
与JAVA中的基本流比照。
其功能有极大限制,但是可以实现基本的文件读取写入等操作。
前段时间写了个东东,代码如下,GGMM们可以瞧下,消遣下。
--创建配置表
DECLARE
--action:
创建存储目录文件表
--author:
hehe
--date:
2014-01-23
V_COUNT NUMBER
(2);
V_SQL VARCHAR2(32767);
BEGIN
--判断表存在
SELECTCOUNT(*)INTOV_COUNTFROMUSER_TABLESWHERETABLE_NAME='T_DIRLIST';
IFV_COUNT=1THEN
--如果存在DROP掉
EXECUTEIMMEDIATE'DROPTABLET_DIRLIST';
ENDIF;
--如果不存在,重新创建
V_SQL:
='CREATETABLET_DIRLIST(FILENAMEVARCHAR2(255),FILESIZENUMBER,FILEDATEDATE)';
EXECUTEIMMEDIATEV_SQL;
EXECUTEIMMEDIATE'COMMENTONTABLET_DIRLISTIS''存储目录文件表''';
EXECUTEIMMEDIATE'COMMENTONCOLUMN T_DIRLIST.FILENAMEIS ''文件名称''';
EXECUTEIMMEDIATE'COMMENTONCOLUMN T_DIRLIST.FILESIZEIS ''文件大小''';
EXECUTEIMMEDIATE'COMMENTONCOLUMN T_DIRLIST.FILESIZEIS ''文件最后操作时间''';
--创建序列
SELECTCOUNT(*)INTOV_COUNTFROMUSER_SEQUENCESWHERESEQUENCE_NAME='SEQ';
IFV_COUNT=0THEN
EXECUTEIMMEDIATE'CREATESEQUENCE SEQSTARTWITH1';
END;
/
--创建java类用于文件夹操作
createorreplaceandcompilejavasourcenameddirlistas
importjava.io.*;
importjava.sql.*;
publicclassDirList
action:
获取目录下文件
author:
date:
publicstaticvoidgetList(Stringdirectory)throwsSQLException
//创建文件对象
Filepath=newFile(directory);
String[]fileList=path.list();
StringfileName;
longfileSize;
longfileDate;
//清除表中的所有记录
#sql{deletefromt_dirlist};
#sql{commit};
//循环取出获取目录中的文件名及创建时间
for(inti=0;i { fileName=fileList; //创建文件对象 Filefpath=newFile(directory+'/'+fileName); //获取对象大小 fileSize=fpath.length(); //获取对象的最后修改时间 fileDate=fpath.lastModified(); //向表中插入记录 #sql{insertintot_dirlist(filename,filesize,filedate) values(:fileName,:fileSize,to_date('01/01/1970','mm/dd/yyyy')+:fileDate/(24*60*60*1000))}; } //提交事务 #sql{commit};}}--具体实现包CREATEORREPLACEPACKAGEPA_FILEAS PROCEDUREPR_GETDIRLIST(I_DIRECTORY VARCHAR2); --action:获取目录下的所有文件 --author:hehe --date:2014-01-23 /*参数说明 *I_DIRECTORY目录名称 */ PROCEDUREPR_READTOWRITE_FILE(I_READ_DIR VARCHAR2, I_WRITE_DIR VARCHAR2, I_WRITE_FILEVARCHAR2); --action:读取I_READ_DIR目录下的所有文件,到I_WRITE_DIR目录下的对应文件 --author:hehe --date:2014-01-23 /*参数说明 *I_READ_DIR 读取文件的目录 *I_WRITE_DIR 写入文件的目录 *I_WRITE_FILE写入的文件名 */ PROCEDUREPR_READTOWRITE_DECLARE(I_READ_DIR VARCHAR2, I_READ_FILE VARCHAR2DEFAULT'DECLARE.SQL', I_WRITE_DIR VARCHAR2, I_WRITE_FILEVARCHAR2); --action:读取I_READ_DIR目录下的I_READ_FILE文件,到I_WRITE_DIR目录下的对应文件 --author:hehe --date:2014-01-23 /*参数说明 *I_READ_DIR 读取文件的目录 *I_READ_FILE 读取的文件名 *I_WRITE_DIR 写入文件的目录 *I_WRITE_FILE写入的文件名 */ENDPA_FILE;/CREATEORREPLACEPACKAGEBODYPA_FILEAS PROCEDUREPR_GETDIRLIST(I_DIRECTORYINVARCHAR2)AS --action:获取目录下的所有文件 --author:hehe --date:2014-01-23 /*参数说明 *I_DIRECTORY目录名称 */ LANGUAGEJAVANAME'DirList.getList(java.lang.String)'; PROCEDUREPR_READTOWRITE_FILE(I_READ_DIR VARCHAR2, I_WRITE_DIR VARCHAR2, I_WRITE_FILEVARCHAR2) AS --action:读取I_READ_DIR目录下的所有文件,到I_WRITE_DIR目录下的对应文件 --author:hehe --date:2014-01-23 /*参数说明 *I_READ_DIR 读取文件的目录 *I_WRITE_DIR 写入文件的目录 *I_WRITE_FILE写入的文件名 */ V_READ_DIR VARCHAR2(1000) :=TRIM(UPPER(I_READ_DIR)); V_WRITE_DIR VARCHAR2(1000) :=TRIM(UPPER(I_WRITE_DIR)); V_WRITE_FILE VARCHAR2(1000) :=TRIM(UPPER(I_WRITE_FILE)); V_OWNER VARCHAR2(38) :=SYS_CONTEXT('USERENV','CURRENT_USER'); V_DIR VARCHAR2(32767); V_FILE_WRITE UTL_FILE.FILE_TYPE; V_FILE_READ UTL_FILE.FILE_TYPE; V_BUFFER VARCHAR2(32767); V_FILENAME VARCHAR2(32767); V_GOL VARCHAR2(32767); V_SQL VARCHAR2(32767); V_CUR SYS_REFCURSOR; CURSORCUR_FILENAMEIS SELECT FILENAMEFROMT_DIRLIST WHEREFILENAME<>'DECLARE.SQL' ANDSUBSTR(TRIM(UPPER(FILENAME)),INSTR(TRIM(FILENAME),'.'))='.SQL' ORDERBYFILENAME; BEGIN --获取读取文件的目录下的所有文件 --授予java访问目录权限 V_SQL:='SELECTDIRECTORY_PATH FROMDBA_DIRECTORIESWHEREDIRECTORY_NAMEIN(''' ||V_READ_DIR||''','''||V_WRITE_DIR||''')'; OPENV_CURFORV_SQL; FETCHV_CURINTOV_DIR; WHILEV_CUR%FOUND LOOP V_SQL:='CALL dbms_java.grant_permission('''||V_OWNER||'''' ||',''SYS:java.io.FilePermission'',''' ||V_DIR||''',''read'')'; --DBMS_OUTPUT.put_line(V_SQL); EXECUTEIMMEDIATEV_SQL; V_SQL:='CALLdbms_java.grant_permission('''||V_OWNER||'''' ||',''SYS:java.io.FilePermission'',''' ||V_DIR||'\*'',''read'')'; EXECUTEIMMEDIATEV_SQL; FETCHV_CURINTOV_DIR; ENDLOOP; SELECTDIRECTORY_PATHINTOV_DIR FROMDBA_DIRECTORIESWHEREDIRECTORY_NAME=V_READ_DIR; PR_GETDIRLIST(V_DIR); --首次清除所有记录 V_FILE_WRITE:=UTL_FILE.FOPEN(V_WRITE_DIR,V_WRITE_FILE,'W');--W覆盖写入 --写入空 UTL_FILE.PUT_LINE(V_FILE_WRITE,''); UTL_FILE.FFLUSH(V_FILE_WRITE); UTL_FILE.FCLOSE(V_FILE_WRITE); ----------------------------------------------------------- --打开要写入的文件 V_FILE_WRITE:=UTL_FILE.FOPEN(V_WRITE_DIR,V_WRITE_FILE,'A');--A追加 ----------------------------------------------------------- --循环读取文件下的文件 FORCUR_GET_FILENAMEINCUR_FILENAME LOOP --获取文件名 V_FILENAME:=TRIM(CUR_GET_FILENAME.FILENAME); --写入空行 UTL_FILE.PUT_LINE(V_FILE_WRITE,''); --写入注释 V_GOL:='SETECHOON;'; UTL_FILE.PUT_LINE(V_FILE_WRITE,V_GOL); V_GOL:='REM创建'||SUBSTR(V_FILENAME,1,INSTR(V_FILENAME,'.')-1); UTL_FILE.PUT_LINE(V_FILE_WRITE,V_GOL); V_GOL:='SETECHOOFF;'; UTL_FILE.PUT_LINE(V_FILE_WRITE,V_GOL); --打开文件 V_FILE_READ:=UTL_FILE.FOPEN(V_READ_DIR,V_FILENAME,'R'); LOOP BEGIN --读取文件 UTL_FILE.GET_LINE(V_FILE_READ,V_BUFFER); --写入文件 UTL_FILE.PUT_LINE(V_FILE_WRITE,V_BUFFER); EXCEPTION WHENNO_DATA_FOUNDTHEN EXIT; END; ENDLOOP; --冲刷写入系统文件 UTL_FILE.FFLUSH(V_FILE_WRITE); UTL_FILE.FCLOSE(V_FILE_READ); ENDLOOP; --全部重新刷新输出释放 UTL_FILE.FFLUSH(V_FILE_WRITE); UTL_FILE.FCLOSE(V_FILE_WRITE); UTL_FILE.FCLOSE(V_FILE_READ); EXCEPTION --异常处理,读取不到数据时,关闭流 WHENNO_DATA_FOUNDTHEN UTL_FILE.FCLOSE(V_FILE_WRITE); UTL_FILE.FCLOSE(V_FILE_READ); WHENOTHERSTHEN RAISE; ENDPR_READTOWRITE_FILE; PROCEDUREPR_READTOWRITE_DECLARE(I_READ_DIR VARCHAR2, I_READ_FILE VARCHAR2DEFAULT'DECLARE.SQL', I_WRITE_DIR VARCHAR2, I_WRITE_FILEVARCHAR2) AS --action:读取I_READ_DIR目录下的I_READ_FILE文件,到I_WRITE_DIR目录下的对应文件 --author:hehe --date:2014-01-23 /*参数说明 *I_READ_DIR 读取文件的目录 *I_READ_FILE 读取的文件名 *I_WRITE_DIR 写入文件的目录 *I_WRITE_FILE写入的文件名 */ V_READ_DIR VARCHAR2(1000) :=TRIM(UPPER(I_READ_DIR)); V_READ_FILE VARCHAR2(1000) :=TRIM(I_READ_FILE); V_WRITE_DIR VARCHAR2(1000) :=TRIM(UPPER(I_WRITE_DIR)); V_WRITE_FILE VARCHAR2(1000) :=TRIM(I_WRITE_FILE); V_OWNER VARCHAR2(38) :=SYS_CONTEXT('USERENV','CURRENT_USER'); V_DIR VARCHAR2(32767); V_SEQ NUMBER(38); V_FILE_W
fileName=fileList;
Filefpath=newFile(directory+'/'+fileName);
//获取对象大小
fileSize=fpath.length();
//获取对象的最后修改时间
fileDate=fpath.lastModified();
//向表中插入记录
#sql{insertintot_dirlist(filename,filesize,filedate)
values(:
fileName,:
fileSize,to_date('01/01/1970','mm/dd/yyyy')+:
fileDate/(24*60*60*1000))};
//提交事务
--具体实现包
CREATEORREPLACEPACKAGEPA_FILE
AS
PROCEDUREPR_GETDIRLIST(I_DIRECTORY VARCHAR2);
获取目录下的所有文件
/*参数说明
*I_DIRECTORY目录名称
PROCEDUREPR_READTOWRITE_FILE(I_READ_DIR VARCHAR2,
I_WRITE_DIR VARCHAR2,
I_WRITE_FILEVARCHAR2);
读取I_READ_DIR目录下的所有文件,到I_WRITE_DIR目录下的对应文件
*I_READ_DIR 读取文件的目录
*I_WRITE_DIR 写入文件的目录
*I_WRITE_FILE写入的文件名
PROCEDUREPR_READTOWRITE_DECLARE(I_READ_DIR VARCHAR2,
I_READ_FILE VARCHAR2DEFAULT'DECLARE.SQL',
读取I_READ_DIR目录下的I_READ_FILE文件,到I_WRITE_DIR目录下的对应文件
*I_READ_FILE 读取的文件名
ENDPA_FILE;
CREATEORREPLACEPACKAGEBODYPA_FILE
PROCEDUREPR_GETDIRLIST(I_DIRECTORYINVARCHAR2)AS
LANGUAGEJAVANAME'DirList.getList(java.lang.String)';
I_WRITE_FILEVARCHAR2)
V_READ_DIR VARCHAR2(1000) :
=TRIM(UPPER(I_READ_DIR));
V_WRITE_DIR VARCHAR2(1000) :
=TRIM(UPPER(I_WRITE_DIR));
V_WRITE_FILE VARCHAR2(1000) :
=TRIM(UPPER(I_WRITE_FILE));
V_OWNER VARCHAR2(38) :
=SYS_CONTEXT('USERENV','CURRENT_USER');
V_DIR VARCHAR2(32767);
V_FILE_WRITE UTL_FILE.FILE_TYPE;
V_FILE_READ UTL_FILE.FILE_TYPE;
V_BUFFER VARCHAR2(32767);
V_FILENAME VARCHAR2(32767);
V_GOL VARCHAR2(32767);
V_CUR SYS_REFCURSOR;
CURSORCUR_FILENAMEIS
SELECT FILENAMEFROMT_DIRLIST
WHEREFILENAME<>'DECLARE.SQL'
ANDSUBSTR(TRIM(UPPER(FILENAME)),INSTR(TRIM(FILENAME),'.'))='.SQL'
ORDERBYFILENAME;
--获取读取文件的目录下的所有文件
--授予java访问目录权限
='SELECTDIRECTORY_PATH FROMDBA_DIRECTORIESWHEREDIRECTORY_NAMEIN('''
||V_READ_DIR||''','''||V_WRITE_DIR||''')';
OPENV_CURFORV_SQL;
FETCHV_CURINTOV_DIR;
WHILEV_CUR%FOUND
LOOP
='CALL dbms_java.grant_permission('''||V_OWNER||''''
||',''SYS:
java.io.FilePermission'','''
||V_DIR||''',''read'')';
--DBMS_OUTPUT.put_line(V_SQL);
='CALLdbms_java.grant_permission('''||V_OWNER||''''
||V_DIR||'\*'',''read'')';
ENDLOOP;
SELECTDIRECTORY_PATHINTOV_DIR FROMDBA_DIRECTORIESWHEREDIRECTORY_NAME=V_READ_DIR;
PR_GETDIRLIST(V_DIR);
--首次清除所有记录
V_FILE_WRITE:
=UTL_FILE.FOPEN(V_WRITE_DIR,V_WRITE_FILE,'W');--W覆盖写入
--写入空
UTL_FILE.PUT_LINE(V_FILE_WRITE,'');
UTL_FILE.FFLUSH(V_FILE_WRITE);
UTL_FILE.FCLOSE(V_FILE_WRITE);
-----------------------------------------------------------
--打开要写入的文件
=UTL_FILE.FOPEN(V_WRITE_DIR,V_WRITE_FILE,'A');--A追加
--循环读取文件下的文件
FORCUR_GET_FILENAMEINCUR_FILENAME
--获取文件名
V_FILENAME:
=TRIM(CUR_GET_FILENAME.FILENAME);
--写入空行
--写入注释
V_GOL:
='SETECHOON;';
UTL_FILE.PUT_LINE(V_FILE_WRITE,V_GOL);
='REM创建'||SUBSTR(V_FILENAME,1,INSTR(V_FILENAME,'.')-1);
='SETECHOOFF;';
--打开文件
V_FILE_READ:
=UTL_FILE.FOPEN(V_READ_DIR,V_FILENAME,'R');
--读取文件
UTL_FILE.GET_LINE(V_FILE_READ,V_BUFFER);
--写入文件
UTL_FILE.PUT_LINE(V_FILE_WRITE,V_BUFFER);
EXCEPTION
WHENNO_DATA_FOUNDTHEN
EXIT;
--冲刷写入系统文件
UTL_FILE.FCLOSE(V_FILE_READ);
--全部重新刷新输出释放
--异常处理,读取不到数据时,关闭流
WHENOTHERSTHEN
RAISE;
ENDPR_READTOWRITE_FILE;
V_READ_FILE VARCHAR2(1000) :
=TRIM(I_READ_FILE);
=TRIM(I_WRITE_FILE);
V_SEQ NUMBER(38);
V_FILE_W
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1