如何在oracle里使用java存储过程连接db2

| No Comments | No TrackBacks

我不知道我做的这件事情是否还有其他人成功做过,但这篇文章里记录的方法你在metalink或者google上是找不到的,因为这来源于我这几天以来不断的艰苦尝试。

 

在这篇文章里,我们利用oracle里的java存储过程成功连上了db2 v9 for z/OS,并且执行了sql和其中的一个db2存储过程。

 

这个问题来源于我现在正在做的项目的需要,我们需要连主机并执行主机里的存储过程。当然,.net前台或者java前台连主机是没问题的,但是我们还是希望能够在oracle数据库端直连db2 v9 for z/OS,因为这样可以减少前台同oracle数据库端的交互并且可以避免冗余代码。

 

第一个思路是安装Transparent Gateway(即tg4drda),安装完后发现连db2 v9 for z/OS是没问题的,也能读出其中表里的数据,但就是不能执行其中的存储过程。这大致是因为10gR2tg4drda不支持LOB的缘故,oracletg4drda的文档里明确指出:

When the gateway receives a call to run a stored procedure on the DRDA Server (for example DB2/OS390), it first does a lookup of the procedure name in the server catalog. The information that defines a stored procedure is stored in different forms on each DRDA Server. For example, DB2/OS390 V5.0 uses the table SYSIBM.SYSPROCEDURES, while DB2/OS390 V6.1 uses the table SYSIBM.SYSROUTINES.

db2 v9SYSIBM.SYSROUTINES里新引入了一个LOB列,这大概就是10gR2tg4drda不能执行db2 v9 for z/OS里的存储过程的原因

 

第二个思路就是使用java存储过程,因为JDBC驱动应该是能连上db2 v9 for z/OS的,但是我在实际用的过程中发现oracle里并不自带JDBC for db2的驱动,所以在缺省情况下,你在oraclejava存储过程里是连不上db2的。

 

怎么办?

我们现在来想办法把JDBC for db2的驱动加载到oracle里。

 

如下是一个完整的例子,就以这个当作是给需要的朋友们的新年礼物 :)

1、找到所需要的JDBC for db2的驱动

安装"DB2 Connect Personal Edition V9.1 for Windows(32-bit)",装完后从安装路径(我的是D:\Program Files\IBM\SQLLIB\java)下把db2java.zipdb2jcc.jardb2jcc_license_cu.jardb2jcc_javax.jardb2jcc_license_cisuz.jar拷到$ORACLE_HOME /jdbc/lib下。

 

2、用loadjava把上述驱动导入到oracle中,注意这里要以sys用户执行导入,导入的过程中会出一些错误,没关系,可以忽略掉,导入的语法为:

loadjava -user sys/oracle@ipratest /u01/app/oracle/product/10.2.0/jdbc/lib/db2java.zip -force

loadjava -user sys/oracle@ipratest /u01/app/oracle/product/10.2.0/jdbc/lib/db2jcc_license_cisuz.jar -force

loadjava -user sys/oracle@ipratest /u01/app/oracle/product/10.2.0/jdbc/lib/db2jcc_license_cu.jar -force

loadjava -user sys/oracle@ipratest /u01/app/oracle/product/10.2.0/jdbc/lib/db2jcc.jar -force

loadjava -user sys/oracle@ipratest /u01/app/oracle/product/10.2.0/jdbc/lib/db2jcc_javax.jar -force

 

3、然后在sys用户下写java存储过程和wrapper function,注意一定要是在sys用户下,否则用不了JCC驱动,核心的代码为:

DriverManager.registerDriver(new com.ibm.db2.jcc.DB2Driver());         

conn = DriverManager.getConnection("jdbc:db2://10.1.21.215:446/LOCDSN3", "xbsyl", "abcd");

         

//执行一个db2存储过程----------begin------------------------------

callname = "{CALL " + ProcedureName + "(?,?)}";         

proc = conn.prepareCall(callname);

proc.setString(1, InputString);

proc.registerOutParameter(2, Types.VARCHAR);

proc.execute();       

OutputString = proc.getString(2);

//执行一个db2存储过程----------End-------------------------------- 

 

//执行一个sql-----------------begin------------------------------

Statement st = conn.createStatement();

String sqlStr= Sqltext;

ResultSet rs = st.executeQuery(sqlStr);

while (rs.next())

{

  OutputString = rs.getString(1);

}          

//执行一个sql------------------End---------------------------------

 

4、测试一下调wrapper function的效果,我这里写了两个wrapper function,分别是F_SYS_CALL_DB2_BY_SQLF_SYS_CALL_DB2_PROC。其中F_SYS_CALL_DB2_BY_SQL是在db2 v9 for z/OS上执行一个我传入的sql语句,并返回查询的结果;F_SYS_CALL_DB2_PROC是在db2 v9 for z/OS上执行一个我传入的db2存储过程,它的输入参数是要调用的db2存储过程的名字,输出参数就是执行这个db2存储过程后的返回值,我们来实际看一下效果:

首先我在一个安装了tg4drda的库里执行一个sql

SQL> select deptname from DSN8910.DEPT@plhi3 where deptno='A00';

 

DEPTNAME

------------------------------------------------------------------------

SPIFFY COMPUTER SERVICE DIV.

这里的plhi3就是指向db2 v9 for z/OSdb link,可以看到查询结果为SPIFFY COMPUTER SERVICE DIV

 

然后我在未安装tg4drda的库里执行我写好的F_SYS_CALL_DB2_BY_SQL

SQL> set serveroutput on size 1000000;

SQL> var vc_return_flag varchar2(2000);

SQL> begin

  2  :vc_return_flag := F_SYS_CALL_DB2_BY_SQL('select deptname from DSN8910.DEPT where deptno=''A00''');

  3  end;

  4  /

 

PL/SQL procedure successfully completed

vc_return_flag

---------

SPIFFY COMPUTER SERVICE DIV.

 

可以看到返回的结果与tg4drda的结果一致,即我们已经通过java存储过程连上了db2 v9 for z/OS.

执行db2 v9 for z/OS里的存储过程的语法跟上述过程是一样,这里不再赘述。

No TrackBacks

TrackBack URL: http://dbsnake.com/cgi-bin/mt/mt-tb.cgi/100

Leave a comment