oracle函数返回long raw类型的时候,貌似有长度限制,100K以上会被截断!

cxz7531 2013-05-06 10:58:33
我在java应用程序中调用oracle函数,返回一个long raw类型的字节流,100K以下内容是全的。超过100K就截断了。
是不是哪里能设置oracle数据库函数返回长度的最大值?疑惑中
...全文
553 13 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
vanjayhsu 2013-05-08
  • 打赏
  • 举报
回复
引用 12 楼 cxz7531 的回复:
[quote=引用 11 楼 vanjayhsu 的回复:] 只能建议不要使用函数直接接收byte[]数组作为返回值,中间不知道ORACLE会做什么样的数据类型转换。建议直接将byte[]内容插入到表中的long raw字段。试试这样是否可行吧。
这当然是可行,我现在就这样做了,java sources里取得数据后先插入数据库中的一个blob字段,返回一个成功标志,java应用程序端取得成功标志,就去数据库中的blob字段取出数据。 但绕了弯子,还需要定期清理数据库的这些无用的数据。[/quote] 其实你可以读取完了之后就清除这个数据,当你的程序稳定之后。或者在每次插入之前先清空表中的数据。对于JAVA函数和JAVA存储过程研究较少。 或者是可以尝试在函数中声明一个long raw的变量,JAVA函数先返回到变量,然后再return变量作为返回值,看看是否有效果。 ----test函数---- create or replace function test(url varchar2) return LONG RAW as language java name 'RemoteFileObject.getRemoteFileObject(java.lang.String) return byte[]';
vanjayhsu 2013-05-07
  • 打赏
  • 举报
回复
RemoteFileObject.getRemoteFileObject(java.lang.String) return java.lang.String 这个函数返回的是什么样的字符串?LONG RAW只能保存二进制数据,所以不知道是否是string转换到ORACLE字符串,ORACLE字符串再转换为LONG RAW。如果是这样,那就有可能会被截断。。。
Kobayashi 2013-05-07
  • 打赏
  • 举报
回复
不知道这个原因。。没有搞过Java。。 不过你可以放心。在Oracle中是没有这个问题的。
cxz7531 2013-05-07
  • 打赏
  • 举报
回复
引用 11 楼 vanjayhsu 的回复:
只能建议不要使用函数直接接收byte[]数组作为返回值,中间不知道ORACLE会做什么样的数据类型转换。建议直接将byte[]内容插入到表中的long raw字段。试试这样是否可行吧。
这当然是可行,我现在就这样做了,java sources里取得数据后先插入数据库中的一个blob字段,返回一个成功标志,java应用程序端取得成功标志,就去数据库中的blob字段取出数据。 但绕了弯子,还需要定期清理数据库的这些无用的数据。
vanjayhsu 2013-05-07
  • 打赏
  • 举报
回复
只能建议不要使用函数直接接收byte[]数组作为返回值,中间不知道ORACLE会做什么样的数据类型转换。建议直接将byte[]内容插入到表中的long raw字段。试试这样是否可行吧。
cxz7531 2013-05-07
  • 打赏
  • 举报
回复
稍微改了下,目前全部完整代码和错误信息如下: ----test函数---- create or replace function test(url varchar2) return LONG RAW as language java name 'RemoteFileObject.getRemoteFileObject(java.lang.String) return byte[]'; ---oracle java source--- create or replace and compile java source named remotefilemanager as import java.io.BufferedInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.net.URI; import java.net.URLConnection; public class RemoteFileObject { public static byte[] getRemoteFileObject(String urlPath) { String ret = ""; byte[] datas = null; URI uri = null; URLConnection connection = null; BufferedInputStream in = null; ByteArrayOutputStream out = null; try { uri = new URI(urlPath); connection = uri.toURL().openConnection(); in = new BufferedInputStream(connection.getInputStream()); out = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len; while ((len = in.read(buffer)) != -1) { out.write(buffer, 0, len); } datas = out.toByteArray(); // ret = new String(datas, "ISO-8859-1"); } catch (Exception e) { e.printStackTrace(); } finally { if (in != null) { try { in.close(); } catch (IOException e) { } } if (out != null) { try { out.close(); } catch (IOException e) { } } } return datas; //return ret; } } -----java应用程序---- public static void main(String[] args) { Connection conn = null; String fname = "test.jpg"; String url = "http://localhost:8080/" + fname; try { Class.forName("oracle.jdbc.driver.OracleDriver"); conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:cweb", "dcm", "dcm"); CallableStatement cs; cs = conn.prepareCall("{? = call test(?)}"); cs.registerOutParameter(1, Types.LONGVARBINARY); cs.setString(2, url);//http://172.19.31.229:7001/tgtpApp/images/ico1.png cs.execute(); byte[] bytes = cs.getBytes(1); System.out.println(bytes.length); } catch (Exception e) { e.printStackTrace(); } finally { if (conn != null) { try { conn.close(); } catch (Exception e) { } } } } 出错信息: java.sql.SQLException: ORA-24345: 出现截断或空读取错误 ORA-06512: 在 "DCM.TEST", line 1 ORA-06512: 在 line 1 at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112) at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:331) at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:288) at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:743) 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 MainJavaSource.main(MainJavaSource.java:63)
cxz7531 2013-05-07
  • 打赏
  • 举报
回复
引用 8 楼 vanjayhsu 的回复:
RemoteFileObject.getRemoteFileObject(java.lang.String) return java.lang.String 这个函数返回的是什么样的字符串?LONG RAW只能保存二进制数据,所以不知道是否是string转换到ORACLE字符串,ORACLE字符串再转换为LONG RAW。如果是这样,那就有可能会被截断。。。
在100K以下的时候,即使写成String也不会出错 后来我这里改过了,改成了 RemoteFileObject.getRemoteFileObject(java.lang.String) return byte[] 但100K以上错误依旧错误依旧。
u010412956 2013-05-06
  • 打赏
  • 举报
回复
long raw 能保存2G的内容。。。是不是你java侧的原因呢。
cxz7531 2013-05-06
  • 打赏
  • 举报
回复
错误信息 java.sql.SQLException: ORA-24345: 出现截断或空读取错误 ORA-06512: 在 "DCM.TEST", line 1 ORA-06512: 在 line 1 at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112) at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:331) at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:288) at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:743) 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 MainJavaSource.main(MainJavaSource.java:63)
cxz7531 2013-05-06
  • 打赏
  • 举报
回复
java应用程序代码是: private byte[] getAttachContent(String AttachUrl) { byte[] bytes = null; try{ Connection conn = DataSourceUtils.getConnection((DataSource) BeanUtil.getBean("dataSource")); CallableStatement cs; cs = conn.prepareCall("{? = call test(?)}"); cs.registerOutParameter(1, Types.LONGVARBINARY); cs.setString(2, AttachUrl);//http://172.19.31.229:7001/tgtpApp/images/ico1.png cs.execute(); bytes = cs.getBytes(1); }catch (Exception e) { e.printStackTrace(); } return bytes; } test函数的url 参数就是类似http://172.19.31.229:7001/tgtpApp/images/ico1.png 这样的路径。 经过测试javasource中取得的数据是完整的,但java 应用程序运行出错
cxz7531 2013-05-06
  • 打赏
  • 举报
回复
引用 3 楼 vanjayhsu 的回复:
直接使用PLSQL或SQLPLUS调用函数能返回正确的结果么?建议把函数内容贴出来以供参考
具体是这样的,我的应用程序不能访问外网,但连接的数据库能访问外网。需要在java代码中调用数据库的一个test函数,test函数调用一个oracle javasource,让javasource去访问外网取得数据,返给test函数,再返给应用程序。 ---test函数--- create or replace function test(url varchar2) return LONG RAW as language java name 'RemoteFileObject.getRemoteFileObject(java.lang.String) return java.lang.String'; ---javasource--- create or replace and compile java source named remotefilemanager as import java.io.BufferedInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.net.URI; import java.net.URLConnection; public class RemoteFileObject { public static byte[] getRemoteFileObject(String urlPath) { String ret = ""; byte[] datas = null; URI uri = null; URLConnection connection = null; BufferedInputStream in = null; ByteArrayOutputStream out = null; try { uri = new URI(urlPath); connection = uri.toURL().openConnection(); in = new BufferedInputStream(connection.getInputStream()); out = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len; while ((len = in.read(buffer)) != -1) { out.write(buffer, 0, len); } datas = out.toByteArray(); ret = new String(datas, "ISO-8859-1"); } catch (Exception e) { e.printStackTrace(); } finally { if (in != null) { try { in.close(); } catch (IOException e) { } } if (out != null) { try { out.close(); } catch (IOException e) { } } } return datas; //return ret; } }
vanjayhsu 2013-05-06
  • 打赏
  • 举报
回复
直接使用PLSQL或SQLPLUS调用函数能返回正确的结果么?建议把函数内容贴出来以供参考
cxz7531 2013-05-06
  • 打赏
  • 举报
回复
引用 1 楼 u010412956 的回复:
long raw 能保存2G的内容。。。是不是你java侧的原因呢。
作为long raw字段能保存很大的内容,但函数返回long raw的时候,超过100K就会被截断,不知道何故

17,382

社区成员

发帖
与我相关
我的任务
社区描述
Oracle 基础和管理
社区管理员
  • 基础和管理社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧