【问题】

环境:EOS Platform 7.2 weblogic10.3.5 jdk 1.6  oracle 11.0.2.1766

问题现场:Java调用存储过程时,传入xml类型的参数,执行报错:

java.sql.SQLRecoverableException: IO 错误: 22 char of CLOB data cannot be read
 at oracle.jdbc.driver.OraclePreparedStatement.setReaderContentsForClobCritical(OraclePreparedStatement.java:5564)
 at oracle.jdbc.driver.OraclePreparedStatement.setCharacterStreamInternal(OraclePreparedStatement.java:9584)
 ......
 at com.tl.pssc.interfaces.service.impl.longshine.yk.Yk0207115.handleDataProdure(Yk0207115.java:238)
 at com.tl.pssc.interfaces.service.impl.longshine.yk.Yk0207115.exe(Yk0207115.java:70)
        ......
 at oracle.jdbc.driver.OraclePreparedStatement.setReaderContentsForClobCritical(OraclePreparedStatement.java:5548)
 ... 45 more

EOS Platform7.2开发版调用正常

附:存储过程:

CREATE OR REPLACE PACKAGE BODY XXX."PKG_XXX" IS

PROCEDURE PKG_XXX(
       IN_WS_CODE VARCHAR2,
       IN_XML     CLOB,
       IN_XML_OA CLOB,
       OUT_CODE   OUT VARCHAR2,
       OUT_MSG    OUT VARCHAR2) IS 
BEGIN
      OUT_CODE       := '1';
      OUT_MSG        := 'OK';
      COMMIT;
      END PKG_XXX;
END XX;

Java调用的主要代码:

conn = ConnectionHelper.getCurrentContributionConnection("default");
readerNewXml = new StringReader(newStrXml);
readerOldXml = new StringReader(oldXml);
callableStatement = conn.prepareCall("{call XX.PKG_XXX(?,?,?,?,?)}");
callableStatement.setString(1, serviceCode);
callableStatement.setCharacterStream(2, readerNewXml, newStrXml.getBytes("UTF-8").length);
callableStatement.setCharacterStream(3, readerOldXml, oldXml.getBytes("UTF-8").length);
callableStatement.registerOutParameter(4, java.sql.Types.VARCHAR);
callableStatement.registerOutParameter(5, java.sql.Types.VARCHAR);
callableStatement.execute();
outCode = callableStatement.getString(4);
outMsg = callableStatement.getString(5);

【解答】

 问题原因:

1、代码中参数字符串中包含汉字,使用string.getBytes("utf-8").length方式每个汉字占3位,得到的字符串长度比实际字符数长;

2、weblogic11g使用的oracle数据库驱动包为ojdbc6,此驱动中相关实现方法会根据参数中传入的字符串长度读取字符串内容,实际长度小于参数传入长度时抛出异常。

 

解决方式有两种:

第一种:

callableStatement.setCharacterStream(index, reader, length); 使用此方法时第三个参数直接使用string.length()方法获取字符串长度,如:callableStatement.setCharacterStream(2, readerNewXml, newStrXml.length());

第二种:

将callableStatement.setCharacterStream(index, reader, length)替换为callableStatement.setObject(index, string)方法,如:callableStatement.setObject(2, newStrXml);

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

<span '="" normal;="" rgba(0,="" 0);="" 0,="" rgb(0,="" 14px;="" ";="" yahei="" microsoft=""><span '="" normal;="" rgba(0,="" 0);="" 0,="" rgb(0,="" 14px;="" ";="" yahei="" microsoft=""> 

 

 

 

 

 

 

 

 <span '="" normal;="" rgba(0,="" 0);="" 0,="" rgb(0,="" 14px;="" ";="" yahei="" microsoft=""> 

You may want to use a panel to highlight important steps.
  1. Use numbered lists to provide step-by-step help.
  2. Copy and paste or drag and drop images to add them to this page.

Related articles

Related articles appear here based on the labels you select. Click to edit the macro and add or change labels.

Related issues