Recently in db2 experiences Category

Metalink上也许会有我的一篇文章

| 1 Comment

前两天写过一篇文章----"如何在oracle里使用java存储过程连接db2",这篇文章的英文版也许以后会在metalink上出现----Note 984464.1 - How To Connect To DB2 Using Java Stored Procedure

 

关于如何在oracle里使用java存储过程连接db2,我是开了SR的,oracle的一位叫susan的工程师跟进了上述SR,虽然她并没有给我实质性的帮助,但是她的回复中提到了JCC,就是她提到的这一点,使得我最后顺利的解决了上述问题。

 

SR还是应该善加利用的!虽然oracle的工程师不一定能帮你解决问题,但是他们有庞大的资源库,这个是第三方的支持难以望其项背的!而且他们的回复往往可以给你带来好的启示。

 

后来我告诉susan,非常感谢她的帮助,这个问题我自己已经解决了,她接着在SR中提到:

Hi Hua,

Before closing the SR could you provide the steps of your solution , that will help us to improve our knowledge base
since I'll use that information to create a new knowledge Note

Thanks
Susan
Global Customer Support

 

在我上传了我那篇文章的英文版后,我在上述SR中看到了如下内容:

ODM Answer 02-Jan-2010 5:59:24 GMT+08:00 PM Oracle Support 

Unscheduled 

Comments

--------

Complete Steps are defined in new created Note 984464.1 - How To Connect To DB2 Using Java Stored Procedure

 

 

ODM Question 02-Jan-2010 5:58:33 GMT+08:00 PM Oracle Support 

Unscheduled 

Comments

 

另外,新版的metalink可能是由于广泛使用flash的缘故,会导致你的有些SR无法打开,如果你碰到了这种情况,你可以登陆supporthtml.oracle.com,在这里面,你的SR是能够正常打开的。

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

| No Comments

我不知道我做的这件事情是否还有其他人成功做过,但这篇文章里记录的方法你在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里的存储过程的语法跟上述过程是一样,这里不再赘述。

Recent Comments

  • 毕业论文: 学习了。 read more
  • cui hua: 不用改数据,你改row directory里的指针就可以了——这就是我文中提到的update internal。 read more
  • yangjiawei: 领导,不好意思,再请问一下 我现在遇到一个问题,我现在已经将ind$里两个索引的状态改好了,数据库也拉起来了~! 但是在修改obj$里name里为DEPENDENCY$这一行数据的data_object_id时遇到了困难,因为他原先的长度为2个字节,现在由于我move了一下,他的长度变成了4个字节,结果如下: 原先: col 1[2] @906: 0xc1 0x5d ==>92 read more
  • cui hua: 可以从上述sql中推断出等待的顺序(如何推断我已经在文中提到了),是不是太直观,但是综合上述症状来看,只有我文中提到的这种可能。 read more
  • yangjiawei: 我最近也正好再研究这些比较Internal的东西,所以想麻烦您能对这个问题写一个比较详细的解释及解决方案,我对这些也是比较感兴趣的,可以吗? read more
  • publover: 好文,但是不明白是如何确定这个等待队列的?否则就无法看出是谁阻塞了谁,但是从SQL中看不出来等待的顺序是什么 read more
  • cui hua: 这些东西过于internal和复杂了,我不打算对外发布,误导了你反而不好。做好备份就可以了,有了完善的备份这些手段都是没有意义的。 read more
  • yangjiawei: 领导啊~能否将详细的处理过程写一份,发给我啊?我很期待能跟您学习一下~!:) read more
  • cui hua: 这个就是128 128 0 read more
  • cui hua: kamus,你是对的。但我这里指的是一种极限情况,其实我也觉得我这里的算法可能是有问题的。 read more

About this Archive

This page is an archive of recent entries in the db2 experiences category.

article index is the previous category.

my life is the next category.

Find recent content on the main index or look in the archives to find all content.