用Java Class创建Oracle存储过程

一、背景

前不久,领导布置了一个任务,要在Oracle端以存储过程(函数)的方式调用Java class类。经过一两天折腾,搞定了任务,现在做个简单总结。

二、实现方式

整个过程有两个步骤:创建Java class和创建存储过程,其中创建存储过程(函数)必须在Oracle端进行,而创建java class则有两种方式,第一种是直接在Oracle端进行,第二种是Java IDE中生成class后再导入到Oracle。

经测试,两种方式的效果相同。为方便调试,先按第一种方式进行,成功后将class和函数删除,再按第二种方式重新创建。

三、具体过程

3.1 在Oracle端创建Java class

在Sqlplus或Pl-Sql Developer的sql窗口中进行,示例代码如下:

create or replace and compile java source named javatest as

public class JavaTest

{

  public static String FuncTest (String data, String key)

  {

    return "This is " + data + "...  || This is " + key + "...";

  }

}

执行后,会分别生成一个名为javatest的Java Source对象和Java class对象。

3.2 在Oracle端创建存储过程

同样在Oracle端中进行,示例代码如下:

create or replace function f_javatest_functest(p_data in varchar2, p_key in varchar2) return varchar2 as

language java name 'JavaTest.FuncTest(java.lang.String, java.lang.String) return java.lang.String';

执行后,会生成一个名为f_javatest_functest的函数。

此后,可以在sql语句中调用该函数:

select f_javatest_functest('This is data...', 'This is key...') from dual;

This is data... || This is key...

3.3 删掉Java Source和函数

在Oracle端中删掉上述步骤中创建的Java Source(会自动删掉Java class,反之则不会)和函数。细节略。

3.4 在IDE中创建java class

在Java IDE中创建相同的class,源文件(.java)或类文件(.class)均可。如果是类文件,要注意编译时JDK须与oracle的JVM保持一致,11g对应JDK1.5,10g对应1.4。细节略。

3.5 向Oracle导入java class

这里需要使用oracle提供的loadjava命令行工具,它可以导入源文件、类文件、依赖包及资源文件等等。该工具与sqlplus在同一目录。

如果该类使用了其它依赖包或资源文件,须在导入该类之前先导入它们:

loadjava -u username/password -r -v D:JarPathyourjar.jar

loadjava -u username/password -r D:PropPathyourprop.properties

考虑到JVM版本差异问题,推荐导入源文件(.java):

loadjava -u username/password -r -v D:PathJavaTest.java

如果不存在JVM版本差异,可以直接导入类文件(.class):

loadjava -u username/password -r D:PathJavaTest.class

导入成功后,可在oracle端中查询到新生成了Java class对象,但没有Java Source对象。因此采用这种方式可以隐藏代码实现细节。

有关loadjava的具体用法,参见loadjava --help

3.6 重新创建存储过程

与3.2相同,从略。

3.7 删掉或更改java class、依赖包、资源文件

如果是删除单个class,是可以在Sqlplus或Pl-Sql Developer中进行的。但这种方式难以应付有多个依赖包、资源文件的情况,此时要使用dropjava工具。具体用法从略。

在更改java class、依赖包、资源文件后,需要重新编译存储过程(函数)。

四、注意事项

  • 存储过程(函数)应尽量少依赖外部jar包,尤其是有嵌套依赖情形的jar,目前没搜索到如何自动加载嵌套依赖class、以及如何防止依赖class冲突的方法;
  • 某些情况下,可能需要事先以SYSDBA对用户赋予相应权限,例如:

EXEC Dbms_Java.Grant_Permission('USERNAME','SYS:java.lang.RuntimePermission', '*', 'read , write, execute, delete');

注意:USERNAME若非系统事先所建用户,必须全大写。

原文地址:https://www.cnblogs.com/wggj/p/6813388.html