为什么使用ResultSet.CONCUR_READ_ONLY标志呢?这样只能读取结果集,写数据肯定不成功的。
应该是使用可写的结果集才对。

解决方案 »

  1.   

    Oracle JDBC驱动处理clob似乎有问题,用jtds驱动包可解决此问题
      

  2.   

    ResultSet.CONCUR_READ_ONLY是针对返回的结果集的吧,我的是update语句,不是对返回结果集进行操作
      

  3.   

    改用JDBC 3.0驱动也能解决问题,但是现在没办法改变环境,只有去遵守
      

  4.   

    package jdbc.day4 ;
    import java.sql.*;
    import java.io.*;
    /*
     *用于演示Blob字段的插入与查询。
     */
    public class BlobSample{
    /*
     *向mp3_table中插入一条数据
     *name : 歌曲的名称
     *path  : 歌曲的路径
     */
    public void insertBlob( String name , String path ) {
    Connection conn = null;
    PreparedStatement pstm = null ;
    ResultSet rs = null; 
    try{
    //获得一个数据库连接,
    Class.forName( "oracle.jdbc.driver.OracleDriver" );
    conn = DriverManager.getConnection( 
                  "jdbc:oracle:thin:@192.168.1.100:1521:sid",
                  "user", "pwd" ) ;
    // *在使用Blob时,必须设置AutoCommit属性为false .*
    conn.setAutoCommit( false );

    //1 , 向表中插入一个空的Blob字段。
    //"empyt_blob()" 是Oracle提供的一个SQL函数,用于创建一个空的Blob对象。
    pstm = conn.prepareStatement( 
               "insert into mp3_table( name, mp3 ) values( ? , empty_blob() )" ) ;
     pstm.setString( 1 , name ) ;
     pstm.executeUpdate();
     //*此处不能提交事务,因为mp3的内容还没有插入到数据库中 * 
     System.out.println( "insert empty blob successful ......" );
    //2,获得blog字段的输出流。
    //2.1 将刚刚插入的空字段查询出来。
    pstm.close();
    //在查询时必须使用for update子句,确保数据的线程安全。
    pstm = conn.prepareStatement(
             "select mp3 from mp3_table where name = ? for update" );
    pstm.setString( 1 , name ) ;
    rs = pstm.executeQuery();
       if( rs.next() ){
        //在使用Blob时要强制转化成oracle.sql.BLOB
        //该类由JDBC driver提供( classes12.jar ) ;
        Blob b = rs.getBlob( 1 );
        oracle.sql.BLOB ob = (oracle.sql.BLOB ) b ;
        OutputStream os = ob.getBinaryOutputStream();
        System.out.println( "get binary outputStream successful ...." );
        //通过输出流将数据写入数据库。
        InputStream is = new FileInputStream( path ) ;
        byte buffer[] = new byte[ 4096 ] ;
        int len = 0 ;
        while( true ){
        len = is.read( buffer ) ;
        if( len == -1 ) break ;
        os.write( buffer , 0 , len ) ;
        System.out.println( len + " bytes writed ." );
        }
        //必须在Commit之前关闭输入输出流。
        is.close();
        os.close();
       
        //提交事务
        conn.commit();
        System.out.println( "insert " + name + " successful ... " );
       }

    }catch(Exception  e ){
    e.printStackTrace();
    if( conn != null ) try{ conn.rollback(); } catch( Exception e1 ){}
    }finally{
    if( rs != null ) try{ rs.close() ; }catch( Exception e ) {}
    if( pstm != null ) try{ pstm.close(); }catch( Exception e ){}
    if( conn != null ) try{ conn.close(); } catch( Exception e ){}
    }
    }

    /*
     * 这个方法的功能是在mp3_table中根据名称查询mp3,
     * 并且把查询结果保存在磁盘的文件中。
     *name : 用来制定mp3的名称。
     *path :  用来制定保存mp3的文件路径。
     */
    public void queryBlob( String name , String path ) {
    Connection conn = null;
    PreparedStatement pstm = null;
    ResultSet rs = null;

    try{
    // 连接数据库
    Class.forName( "oracle.jdbc.driver.OracleDriver" );
    conn = DriverManager.getConnection( 
                 "jdbc:oracle:thin:@192.168.1.100:1521:tarena" , 
                 "sd0605" , "sd0605" );
     conn.setAutoCommit( false ) ;
     //执行查询语句
     pstm = conn.prepareStatement( "select mp3 from mp3_table where name=? for update" ); 
     pstm.setString( 1 , name ) ;
     rs = pstm.executeQuery();
     //获得执行结果。
     if( rs.next() ){
      Blob b = rs.getBlob( 1 ) ;
      //获得输入流,此处不需要做强制类型转化
      InputStream is = b.getBinaryStream();
      OutputStream os = new FileOutputStream(  path );
      byte buffer[] = new byte[ 4096 ] ;
      int len = 0 ;
      while( true ){
      len = is.read( buffer ) ;
      if( len == -1 ) break ;
      os.write( buffer , 0 , len ) ;
      System.out.println( len + " bytes read" );
      }
      //在提交事务之前关闭输入,输出流 。
      is.close();
      os.close();
      //提交事务
      conn.commit();
    }
    }catch(Exception e ){
    e.printStackTrace();
    //如果在执行过程中出现异常,回滚数据库操作。
    if( conn != null ) try{ conn.rollback(); }catch( Exception e1 ){}
    }finally{
    if( rs != null ) try{ rs.close(); }catch(Exception e ){}
    if( pstm != null ) try{ pstm.close(); }catch( Exception e ){}
    if( conn != null ) try{ conn.close(); }catch( Exception e ) {}
    }
    }
    public static void main( String args[] ) {
    BlobSample sample = new BlobSample();
    //sample.insertBlob( "dc.mp3" , "d:/dc.mp3" );
    sample.queryBlob( "dc.mp3" , "d:/copy.mp3" );
    }
    }
      

  5.   

    楼上的这种方法已经试过,由于数据库连接是从WebLogic的连接池中获得的,BEA在上面做了手脚,容易出现类型转换异常。问题自己解决了,使用了比较偏激的方法,继续听取各高手的意见
      

  6.   

    weblogic.jdbc.rmi.SerialOracleClob tempClob = (weblogic.jdbc.rmi.SerialOracleClob) clob;
    weblogic.jdbc.rmi.internal.OracleTClobImpl tempClobImpl = (weblogic.jdbc.rmi.internal.OracleTClobImpl) tempClob
    .getTheRealClob();
    CLOB oClob = (CLOB) tempClobImpl.getTheRealClob(); CLOB oClob = (CLOB) clob;
    Writer writer = oClob.getCharacterOutputStream();
    writer.write("Begin" + clobValue + "End");
    writer.flush();
    writer.close();最终使用了这种方式,可能对容器以及连接池的驱动类型等具有极强的依赖