我在java应用程序中调用oracle函数,返回一个long raw类型的字节流,100K以下内容是全的。超过100K就截断了。
是不是哪里能设置oracle数据库函数返回长度的最大值?疑惑中

解决方案 »

  1.   

    long raw 能保存2G的内容是不是你java侧的原因呢。
      

  2.   


    作为long raw字段能保存很大的内容,但函数返回long raw的时候,超过100K就会被截断,不知道何故
      

  3.   

    直接使用PLSQL或SQLPLUS调用函数能返回正确的结果么?建议把函数内容贴出来以供参考
      

  4.   


    具体是这样的,我的应用程序不能访问外网,但连接的数据库能访问外网。需要在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;
    }}
      

  5.   

    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 应用程序运行出错
      

  6.   

    错误信息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)
      

  7.   

    不知道这个原因。。没有搞过Java。。
    不过你可以放心。在Oracle中是没有这个问题的。
      

  8.   

    RemoteFileObject.getRemoteFileObject(java.lang.String) return java.lang.String这个函数返回的是什么样的字符串?LONG RAW只能保存二进制数据,所以不知道是否是string转换到ORACLE字符串,ORACLE字符串再转换为LONG RAW。如果是这样,那就有可能会被截断
      

  9.   

    在100K以下的时候,即使写成String也不会出错
    后来我这里改过了,改成了
    RemoteFileObject.getRemoteFileObject(java.lang.String) return byte[]
    但100K以上错误依旧错误依旧。
      

  10.   

    稍微改了下,目前全部完整代码和错误信息如下:
    ----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)
      

  11.   

    只能建议不要使用函数直接接收byte[]数组作为返回值,中间不知道ORACLE会做什么样的数据类型转换。建议直接将byte[]内容插入到表中的long raw字段。试试这样是否可行吧。
      

  12.   


    这当然是可行,我现在就这样做了,java sources里取得数据后先插入数据库中的一个blob字段,返回一个成功标志,java应用程序端取得成功标志,就去数据库中的blob字段取出数据。
    但绕了弯子,还需要定期清理数据库的这些无用的数据。
      

  13.   


    这当然是可行,我现在就这样做了,java sources里取得数据后先插入数据库中的一个blob字段,返回一个成功标志,java应用程序端取得成功标志,就去数据库中的blob字段取出数据。
    但绕了弯子,还需要定期清理数据库的这些无用的数据。其实你可以读取完了之后就清除这个数据,当你的程序稳定之后。或者在每次插入之前先清空表中的数据。对于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[]';