如何在Oracle中使用Java存储过程 (详解) 博客分类: Oracle JavaOracleSQLSQL ServerJDBC
程序员文章站
2024-03-22 14:52:40
...
其实,这篇短文,我早就应该写了。因为,java存储过程今后在各大数据库厂商中越来越流行,功能也越来越强大。这里以Oracle为例,介绍一下java存储过程的具体用法。
任何转载,请尊重版权。(作者:iihero on csdn)
一、如何创建java存储过程?
通常有三种方法来创建java存储过程。
1. 使用oracle的sql语句来创建:
e.g. 使用create or replace and compile java source named "<name>" as
后边跟上java源程序。要求类的方法必须是public static的,才能用于存储过程。
SQL>createorreplaceandcompilejavasourcenamed"javademo1"
2as
3importjava.sql.*;
4publicclassJavaDemo1
5{
6publicstaticvoidmain(String[]argv)
7{
8System.out.println("hello,javademo1");
9}
10}
11/
Java已创建。
SQL>showerrorsjavasource"javademo1"
没有错误。
SQL>createorreplaceprocedurejavademo1
2as
3languagejavaname'JavaDemo1.main(java.lang.String[])';
4/
过程已创建。
SQL>setserveroutputon
SQL>calljavademo1();
调用完成。
SQL>calldbms_java.set_output(5000);
调用完成。
SQL>calljavademo1();
hello,javademo1
调用完成。
SQL>calljavademo1();
hello,javademo1
调用完成。
2as
3importjava.sql.*;
4publicclassJavaDemo1
5{
6publicstaticvoidmain(String[]argv)
7{
8System.out.println("hello,javademo1");
9}
10}
11/
Java已创建。
SQL>showerrorsjavasource"javademo1"
没有错误。
SQL>createorreplaceprocedurejavademo1
2as
3languagejavaname'JavaDemo1.main(java.lang.String[])';
4/
过程已创建。
SQL>setserveroutputon
SQL>calljavademo1();
调用完成。
SQL>calldbms_java.set_output(5000);
调用完成。
SQL>calljavademo1();
hello,javademo1
调用完成。
SQL>calljavademo1();
hello,javademo1
调用完成。
2. 使用外部class文件来装载创建
e.g. 这里既然用到了外部文件,必然要将class文件放到oracle Server的某一目录下边。
publicclassOracleJavaProc
{
publicstaticvoidmain(String[]argv)
{
System.out.println("It'saJavaOracleprocedure.");
}
}
SQL>grantcreateanydirectorytoscott;
授权成功。
SQL>connscott/tiger@iihero.oracledb
已连接。
SQL>createorreplacedirectorytest_diras'd:\oracle';
目录已创建。
SQL>createorreplacejavaclassusingbfile(test_dir,'OracleJavaProc.CLASS')
2/
Java已创建。
SQL>createorreplaceproceduretestjavaprocaslanguagejavaname'OracleJavaProc.main(java.lang.String[])';
2/
过程已创建。
SQL>calltestjavaproc();
调用完成。
SQL>executetestjavaproc;
PL/SQL过程已成功完成。
SQL>setserveroutputonsize5000
SQL>calldbms_java.set_output(5000);
调用完成。
SQL>executetestjavaproc;
It'saJavaOracleprocedure.
{
publicstaticvoidmain(String[]argv)
{
System.out.println("It'saJavaOracleprocedure.");
}
}
SQL>grantcreateanydirectorytoscott;
授权成功。
SQL>connscott/tiger@iihero.oracledb
已连接。
SQL>createorreplacedirectorytest_diras'd:\oracle';
目录已创建。
SQL>createorreplacejavaclassusingbfile(test_dir,'OracleJavaProc.CLASS')
2/
Java已创建。
SQL>createorreplaceproceduretestjavaprocaslanguagejavaname'OracleJavaProc.main(java.lang.String[])';
2/
过程已创建。
SQL>calltestjavaproc();
调用完成。
SQL>executetestjavaproc;
PL/SQL过程已成功完成。
SQL>setserveroutputonsize5000
SQL>calldbms_java.set_output(5000);
调用完成。
SQL>executetestjavaproc;
It'saJavaOracleprocedure.
3. 我推荐的一种方法,直接使用loadjava命令远程装载并创建。
先创建一个类, e.g.
importjava.sql.*;
importoracle.jdbc.*;
publicclassOracleJavaProc{
//Addasalgradetothedatabase.
publicstaticvoidaddSalGrade(intgrade,intlosal,inthisal){
System.out.println("CreatingnewsalgradeforEMPLOYEE...");
try{
Connectionconn=
DriverManager.getConnection("jdbc:default:connection:");
Stringsql=
"INSERTINTOsalgrade"+
"(GRADE,LOSAL,HISAL)"+
"VALUES(?,?,?)";
PreparedStatementpstmt=conn.prepareStatement(sql);
pstmt.setInt(1,grade);
pstmt.setInt(2,losal);
pstmt.setInt(3,hisal);
pstmt.executeUpdate();
pstmt.close();
}
catch(SQLExceptione){
System.err.println("ERROR!AddingSalgrade:"
+e.getMessage());
}
}
}
importoracle.jdbc.*;
publicclassOracleJavaProc{
//Addasalgradetothedatabase.
publicstaticvoidaddSalGrade(intgrade,intlosal,inthisal){
System.out.println("CreatingnewsalgradeforEMPLOYEE...");
try{
Connectionconn=
DriverManager.getConnection("jdbc:default:connection:");
Stringsql=
"INSERTINTOsalgrade"+
"(GRADE,LOSAL,HISAL)"+
"VALUES(?,?,?)";
PreparedStatementpstmt=conn.prepareStatement(sql);
pstmt.setInt(1,grade);
pstmt.setInt(2,losal);
pstmt.setInt(3,hisal);
pstmt.executeUpdate();
pstmt.close();
}
catch(SQLExceptione){
System.err.println("ERROR!AddingSalgrade:"
+e.getMessage());
}
}
}
使用loadjava命令将其装载到服务器端并编译:
D:eclipse3.1workspacedbtest>loadjava-uscott/tiger@iihero.oracledb-v-resolveOr
acleJavaProc.java
arguments:'-u''scott/tiger@iihero.oracledb'-v''-resolve''OracleJavaProc.java'
creating:sourceOracleJavaProc
loading:sourceOracleJavaProc
resolving:sourceOracleJavaProc
acleJavaProc.java
arguments:'-u''scott/tiger@iihero.oracledb'-v''-resolve''OracleJavaProc.java'
creating:sourceOracleJavaProc
loading:sourceOracleJavaProc
resolving:sourceOracleJavaProc
查询一下状态:
连接到:
Oracle9iEnterpriseEditionRelease9.2.0.1.0-Production
WiththePartitioning,OLAPandOracleDataMiningoptions
JServerRelease9.2.0.1.0-Production
SQL>SELECTobject_name,object_type,statusFROMuser_objectsWHEREobject_typeLIKE'JAVA%';
OBJECT_NAME
--------------------------------------------------------------------------------
OBJECT_TYPESTATUS
--------------------------------------------------
OracleJavaProc
JAVACLASSVALID
OracleJavaProc
JAVASOURCEVALID
Oracle9iEnterpriseEditionRelease9.2.0.1.0-Production
WiththePartitioning,OLAPandOracleDataMiningoptions
JServerRelease9.2.0.1.0-Production
SQL>SELECTobject_name,object_type,statusFROMuser_objectsWHEREobject_typeLIKE'JAVA%';
OBJECT_NAME
--------------------------------------------------------------------------------
OBJECT_TYPESTATUS
--------------------------------------------------
OracleJavaProc
JAVACLASSVALID
OracleJavaProc
JAVASOURCEVALID
测试一下存储过程:
SQL>createorreplaceprocedureadd_salgrade(idnumber,losalnumber,hisalnum
ber)aslanguagejavaname'OracleJavaProc.addSalGrade(int,int,int)';
2/
过程已创建。
SQL>setserveroutputonsize2000
SQL>calldbms_java.set_output(2000);
调用完成。
SQL>executeadd_salgrade(6,10000,15000);
CreatingnewsalgradeforEMPLOYEE...
PL/SQL过程已成功完成。
SQL>select*fromsalgradewheregrade=6;
GRADELOSALHISAL
------------------------------
61000015000
ber)aslanguagejavaname'OracleJavaProc.addSalGrade(int,int,int)';
2/
过程已创建。
SQL>setserveroutputonsize2000
SQL>calldbms_java.set_output(2000);
调用完成。
SQL>executeadd_salgrade(6,10000,15000);
CreatingnewsalgradeforEMPLOYEE...
PL/SQL过程已成功完成。
SQL>select*fromsalgradewheregrade=6;
GRADELOSALHISAL
------------------------------
61000015000
二、如何更新你已经编写的java存储过程?
假如要往类OracleJavaProc里添加一个存储过程方法,如何开发?
正确的步骤应该是先dropjava, 改程序,再loadjava。
e.g.修改OracleJavaProc类内容如下:
importjava.sql.*;
importoracle.jdbc.*;
publicclassOracleJavaProc{
//Addasalgradetothedatabase.
publicstaticvoidaddSalGrade(intgrade,intlosal,inthisal){
System.out.println("CreatingnewsalgradeforEMPLOYEE...");
try{
Connectionconn=
DriverManager.getConnection("jdbc:default:connection:");
Stringsql=
"INSERTINTOsalgrade"+
"(GRADE,LOSAL,HISAL)"+
"VALUES(?,?,?)";
PreparedStatementpstmt=conn.prepareStatement(sql);
pstmt.setInt(1,grade);
pstmt.setInt(2,losal);
pstmt.setInt(3,hisal);
pstmt.executeUpdate();
pstmt.close();
}
catch(SQLExceptione){
System.err.println("ERROR!AddingSalgrade:"
+e.getMessage());
}
}
publicstaticintgetHiSal(intgrade)
{
try{
Connectionconn=
DriverManager.getConnection("jdbc:default:connection:");
Stringsql="SELECThisalFROMsalgradeWHEREgrade=?";
PreparedStatementpstmt=conn.prepareStatement(sql);pstmt.setInt(1, grade);
ResultSetrset=pstmt.executeQuery();
intres=0;
if(rset.next())
{
res=rset.getInt(1);
}
rset.close();
returnres;
importoracle.jdbc.*;
publicclassOracleJavaProc{
//Addasalgradetothedatabase.
publicstaticvoidaddSalGrade(intgrade,intlosal,inthisal){
System.out.println("CreatingnewsalgradeforEMPLOYEE...");
try{
Connectionconn=
DriverManager.getConnection("jdbc:default:connection:");
Stringsql=
"INSERTINTOsalgrade"+
"(GRADE,LOSAL,HISAL)"+
"VALUES(?,?,?)";
PreparedStatementpstmt=conn.prepareStatement(sql);
pstmt.setInt(1,grade);
pstmt.setInt(2,losal);
pstmt.setInt(3,hisal);
pstmt.executeUpdate();
pstmt.close();
}
catch(SQLExceptione){
System.err.println("ERROR!AddingSalgrade:"
+e.getMessage());
}
}
publicstaticintgetHiSal(intgrade)
{
try{
Connectionconn=
DriverManager.getConnection("jdbc:default:connection:");
Stringsql="SELECThisalFROMsalgradeWHEREgrade=?";
PreparedStatementpstmt=conn.prepareStatement(sql);pstmt.setInt(1, grade);
ResultSetrset=pstmt.executeQuery();
intres=0;
if(rset.next())
{
res=rset.getInt(1);
}
rset.close();
returnres;
}
catch(SQLExceptione)
{
System.err.println("ERROR!QueryingSalgrade:"
+e.getMessage());
return -1;
}
}
}
catch(SQLExceptione)
{
System.err.println("ERROR!QueryingSalgrade:"
+e.getMessage());
return -1;
}
}
}
如何更新呢?
D:eclipse3.1workspacedbtest>dropjava-uscott-vOracleJavaProc
D:/tiger@iihero.oracledbeclipse3.1workspacedbtest>loadjava-uscott-v-resolveOr
acleJavaProc/tiger@iihero.oracledb.java
arguments:'-u''scott/tiger@iihero.oracledb''-v''-resolve''OracleJavaProc.java'
creating:sourceOracleJavaProc
loading:sourceOracleJavaProc
resolving:sourceOracleJavaProc
D:/tiger@iihero.oracledbeclipse3.1workspacedbtest>loadjava-uscott-v-resolveOr
acleJavaProc/tiger@iihero.oracledb.java
arguments:'-u''scott/tiger@iihero.oracledb''-v''-resolve''OracleJavaProc.java'
creating:sourceOracleJavaProc
loading:sourceOracleJavaProc
resolving:sourceOracleJavaProc
后边的应用示例:
SQL>createorreplacefunctionquery_hisal(gradenumber)returnnumberaslangu
agejavaname'OracleJavaProc.getHiSal(int)returnint';
2/
函数已创建。
SQL>setserveroutputonsize2000
SQL>calldbms_java.set_output(2000);
调用完成。
SQL>selectquery_hisal(5)fromdual;
QUERY_HISAL(5)
--------------
9999
agejavaname'OracleJavaProc.getHiSal(int)returnint';
2/
函数已创建。
SQL>setserveroutputonsize2000
SQL>calldbms_java.set_output(2000);
调用完成。
SQL>selectquery_hisal(5)fromdual;
QUERY_HISAL(5)
--------------
9999
全文完!
用法个人见解:不要手动drop java source, 不要手动drop procedure。