信息来源:it168
原始连接:
http://tech.it168.com/o/2006-05-15/200605151046345.shtml
Oracle的10R2的jdbc增加了很多的新功能,也解决了不少的bug。前一阵碰到一个10.1的jdbc驱动对9i数据库不兼容的问题,换成10.2的驱动就没有问题了。
但是这会碰到的问题正好反过来,在10g的数据库上使用9i的jdbc驱动正常,而使用10R2的jdbc驱动会报空指针异常。
数据库环境如下:
复制内容到剪贴板
代码:
SQL> CONN YANGTK/YANGTK已连接。
SQL> SELECT * FROM V$VERSION;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
TNS for 32-bit Windows: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production
SQL> CREATE TABLE TEST (ID NUMBER, NAME VARCHAR2(30), CODE CHAR(12));
表已创建。
SQL> CREATE OR REPLACE TYPE T_TEST4 AS OBJECT
2 (
3 ID NUMBER,
4 NAME VARCHAR2(30),
5 CODE VARCHAR2(12),
6 MEMBER PROCEDURE P_TEST
7 );
8 /
类型已创建。
SQL> CREATE OR REPLACE TYPE BODY T_TEST4 AS
2 MEMBER PROCEDURE P_TEST AS
3 BEGIN
4 INSERT INTO TEST VALUES (SELF.ID, SELF.NAME, SELF.CODE);
5 COMMIT;
6 END;
7 END;
8 /
类型主体已创建。程序源码如下:
复制内容到剪贴板
代码:
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.SQLException;
import oracle.sql.STRUCT;
import oracle.sql.StructDescriptor;
import oracle.jdbc.pool.OracleDataSource;
public class TestBug
{
private Connection connection;
public static void main(String args[])
{
TestBug insertObject = new TestBug();
insertObject.dbConnection();
if (insertObject.connection != null)
insertObject.callPlsqlProc();
}
private void dbConnection()
{
try
{
OracleDataSource ods = new OracleDataSource();
ods.setDriverType("thin");
ods.setServerName("172.25.6.201");
ods.setDatabaseName("ytk");
ods.setPortNumber(1521);
ods.setUser("yangtk");
ods.setPassword("yangtk");
connection = ods.getConnection();
} catch (SQLException ex)
{
System.out.print(ex.getMessage());
}
}
private void callPlsqlProc()
{
CallableStatement stmt = null;
try
{
Object objArray[] = new Object[3];
objArray[0] = new Integer(1);
objArray[1] = "yangtk";
objArray[2] = "123456789012";
StructDescriptor colStructDesc =
StructDescriptor.createDescriptor("T_TEST4", connection);
oracle.sql.STRUCT tabStruct =
new STRUCT(colStructDesc, connection, objArray);
stmt = connection.prepareCall("BEGIN T_TEST4.P_TEST(?); END;");
stmt.setObject(1, tabStruct);
stmt.execute();
} catch (SQLException ex)
{
System.out.print(ex.getMessage());
} finally
{
try {
if (stmt != null)
{
stmt.close();
}
} catch (SQLException ex)
{}
}
}
}如果加载920的jdbc驱动,则不会出现任何错误。运行程序后:
复制内容到剪贴板
代码:
SQL> SELECT * FROM TEST;
ID NAME CODE
---------- ------------------------------ ------------
1 yangtk 123456789012但是如果加载10.2的jdbc驱动,则运行后会报空指针异常:
复制内容到剪贴板
代码:
java.lang.NullPointerException
at oracle.jdbc.driver.T4CNamedTypeAccessor.unmarshalOneRow(T4CNamedTypeAccessor.java:147)
at oracle.jdbc.driver.T4CTTIrxd.unmarshal(T4CTTIrxd.java:920)
at oracle.jdbc.driver.T4CTTIrxd.unmarshal(T4CTTIrxd.java:844)
at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:620)
at oracle.jdbc.driver.T4CCallableStatement.doOall8(T4CCallableStatement.java:212)
at oracle.jdbc.driver.T4CCallableStatement.executeForRows(T4CCallableStatement.java:951)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1160)
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3285)
at oracle.jdbc.driver.OraclePreparedStatement.execute(OraclePreparedStatement.java:3390)
at oracle.jdbc.driver.OracleCallableStatement.execute(OracleCallableStatement.java:4223)
at TestBug.callPlsqlProc(TestBug.java:60)
at TestBug.main(TestBug.java:19)
Exception in thread "main" 虽然报异常,但是记录却可以插入:
复制内容到剪贴板
代码:
SQL> SELECT * FROM TEST;
ID NAME CODE
---------- ------------------------------ ------------
1 yangtk 123456789012
1 yangtk 123456789012看来想找一个稳定的jdbc的版本还真难。