oracle 更新Clob字段

本文介绍了解决在WebLogic服务器环境下使用Oracle数据库时更新CLOB字段遇到的ClassCastException异常的方法,并提供了具体的代码示例。文章还讨论了不同数据库类型在处理CLOB时的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

oracle 更新Clob字段的时候报

java.lang.ClassCastException: weblogic.jdbc.wrapper.Clob_oracle_sql_CLOB

 

原代码:

oracle.sql.CLOB clob=(oracle.sql.CLOB)rs.getClob("1");   

BufferedWriter out = new BufferedWriter(clob.getCharacterOutputStream());


 BufferedReader in = new BufferedReader(new FileReader(infile));
    
    int c;

    while ((c=in.read())!=-1) {

    out.write(c);

    }
    in.close();

    out.close();

 

 

网上查了蛮久,有说是包衝突的,有的说是代理成了还是用java.sql.Clob     什麼都有,自己用的是weblogic发布的,最后只是简单修改就OK了:

java.sql.Clob clob = (java.sql.Clob)rs.getClob("xsl1");
 Writer  out = clob.setCharacterStream(1);


    BufferedReader in = new BufferedReader(new FileReader(infile));
    
    int c;

    while ((c=in.read())!=-1) {

    out.write(c);

    }
    in.close();

    out.close();

 

 

-->上面写于2014-05-21

-->下面写于2014-08-06

知道为什么会报错了,因为是用的weblogic服务器,返回的是java.sql.Clob 类型。而且还发现些问题,就是在oracle里面的大字段类型,如果是普通的文本保存最好就用CLOB类型,以前用了BLOB,会出现乱码的问题,而且当本地没有问题,sit有问题就无语了。

 

--insert clob type

      DataFactory df = new DataFactory("");
      StringBuffer sql = new StringBuffer();
     sql.append("INSERT INTO table (LOGINID,SESSIONID,clob_1) "); 
   //oracle 用empty_clob(),sybase无这种类型,可以插入空
   if(Constants.DBTYPE.equals(Constants.DBTYPE_ORACLE)) {
    sql.append("values("+FormatMan.toSQLStr(loginId)+","+FormatMan.toSQLStr(sessionId)+","+FormatMan.toSQLStr(funcName)+",empty_clob())");
    new DBUtil().execInsert(sql.toString(),conn);
   }else if ( Constants.DBTYPE.equals(Constants.DBTYPE_SYBASE) ) {
    sql.append("values("+FormatMan.toSQLStr(loginId)+","+FormatMan.toSQLStr(sessionId)+","+FormatMan.toSQLStr(funcName)+",'')");
    new DBUtil().execInsert(sql.toString(),conn);
   }

 

--update clob type

public void updateClobData(String jsonData,Connection conn) throws SQLException, IOException{
     byte[] jsonBytes = jsonData.getBytes();
     Writer writer = null;
     java.sql.Clob java_clob = null;
     oracle.sql.CLOB oracle_clob = null;
     ResultSet rs = null;
     PreparedStatement ps = null;
      
  String execSQL = "SELECT clob1 FROM table FOR UPDATE";
  ps = conn.prepareStatement(execSQL);
  rs = ps.executeQuery();
  if(rs.next()){
   
if("weblogic".equalsIgnoreCase(DBUtil.server_type)){ //weblogic server
     
     if ( Constants.DBTYPE.equals(Constants.DBTYPE_ORACLE) ) {//oracle db  直接转成流在写进去
      
       java_clob = (java.sql.Clob)rs.getClob("clob1");
       writer = java_clob.setCharacterStream(1);//java.sql.Clob
      
       writer.write(jsonData);
       writer.flush();
     }else{ //sybase数据库  因为db里面的数据类型是long varchar类型,所以其实也就是个string来的,可以用普通的update 语句就可以。
      blob =  ( rs).getBlob("clob1")+"";
       if(blob!=null)
        {
         if(jsonData!=null )
         {
          blob = jsonData;        
         } 
           }
      String sqlexc = "update table set clob1=?  "

      ps = conn.prepareStatement(sqlexc); 
      ps.setString(1, blob);
      ps.executeUpdate();
      
     }
     
     
     }else{//jboss server
     
      clobOracle = (oracle.sql.CLOB)rs.getClob("JSONDATA");
      writer = clobOracle.getCharacterOutputStream();
     
      writer.write(jsonData);
      writer.flush();
     
     }  

 


   if (rs != null) {
   
    rs.close();
    rs=null;
   }
  
   if (ps != null) {
   
    ps.close();
    ps=null;
   }
      
   if (writer!=null){
    writer.close();
   }
   
   if (oracle_clob!=null)
    oracle_clob.close();
   if (java_clob!=null)
    java_clob=null;
  }
 
 
 jsonBytes = null;
 }

 

--read clob type

String sql = "select jsondata  from table ;

Collection col = dbUtil.execSelect(sql);

String jsondata = "";
   String uiLangCode = "";
   String errMsg = "";
   String sysDate = "";
   String timeout_ = "";
   java.sql.Clob clob = null;
   Writer writer = null;
   boolean isTimeout=false;
   if (col != null && col.size() > 0) {
       Iterator it = col.iterator();
    Data data=null;
    
    while (it.hasNext()) {
     
     data = (Data) it.next();     
      clob=data.getClobProperty(colName[0]);
     
      if (clob != null){
      
        int valueLength = 65536;
        StringBuffer tempValue = new StringBuffer("");
        re = clob.getCharacterStream();
        char[]buffer = new char[65536];
        while ((valueLength = re.read(buffer)) > 0){
         tempValue.append(buffer, 0, valueLength);
       }
         if(re!=null){
       re.close();
         }
         jsondata=tempValue.toString();
        }
      
      }
   
    /*
    StringBuffer byte_data = new StringBuffer();
       byte[] b = new byte[4096];
       for (int n; (n = is.read(b)) != -1;) {
        byte_data.append(new String(b, 0, n));
       }

    jsondata = byte_data.toString();
    */
     }

 

<think>好的,我需要帮助用户优化达梦数据库中CLOB字段的查询性能。首先,我应该回顾一下用户的问题,确保完全理解他们的需求。用户提到的是达梦数据库,这是一个国产数据库,可能和Oracle有一些相似之处,但具体优化方法可能有所不同。CLOB字段通常用于存储大量文本数据,比如XML、JSON或者长文本。查询性能问题可能出现在数据读取、索引使用、SQL写法或者存储结构上。我需要从多个方面考虑可能的优化策略。首先,考虑字段使用合理性。用户是否真的需要使用CLOB?有时候,设计上的问题可能导致过度使用CLOB,比如将可以结构化的数据存储为CLOB,这样查询时会比较低效。如果可能,建议用户将部分数据拆分到其他表或者使用更合适的数据类型。其次,索引方面。CLOB字段本身无法创建普通索引,但达梦可能支持函数索引或全文检索。比如,如果用户经常查询某个关键字,可以建立全文索引,这样能加快文本搜索的速度。需要确认达梦是否支持类似Oracle的文本索引功能。然后,SQL查询优化。避免在WHERE条件中直接使用CLOB字段,因为这样的操作会导致全表扫描。如果必须使用,可以考虑使用函数索引,比如SUBSTR函数截取部分内容创建索引。同时,分页查询时,如果涉及CLOB字段,分页效率可能较低,建议使用游标或者分批处理。 存储参数调整也是可能的优化点。比如,设置合适的存储空间,避免频繁扩展,或者调整缓存大小,提高IO效率。此外,达梦可能有针对大字段的特定参数设置,需要查阅相关文档。应用层优化方面,可以考虑缓存频繁查询的结果,减少数据库访问次数。同时,批量处理代替逐条处理,减少事务开销。例如,引用[3]中提到批量插入和更新时使用分批提交,类似的方法可能适用于查询优化。 另外,分区表技术可能有效。将大表按时间或范围分区,缩小查询的数据范围,减少CLOB字段的扫描量。达梦支持表分区,需要确认用户的数据是否适合分区。最后,检查执行计划。通过分析SQL的执行计划,找出性能瓶颈,比如全表扫描或高成本操作,针对性地优化。达梦可能提供类似Oracle的执行计划分析工具,需要用户生成并查看。可能还需要考虑硬件和配置优化,比如增加内存、使用更快的磁盘,或者调整数据库的缓存参数,提升IO性能。同时,确保数据库统计信息是最新的,帮助优化器生成更好的执行计划。 在生成相关问题的时候,需要覆盖用户可能进一步询问的方向,比如具体如何创建全文索引、分区表的实际应用、执行计划的分析方法等。这样可以帮助用户深入解决优化问题。</think>### 达梦数据库CLOB字段查询性能调优方法 #### 1. **字段使用合理性评估** - **避免滥用CLOB**:若存储内容长度可预测(如小于4000字符),建议改用`VARCHAR`类型,避免CLOB的额外开销[^3]。 - **拆分大字段**:将频繁查询的字段(如摘要、标题)从CLOB中分离,存储为独立字段。 #### 2. **索引优化** - **全文检索**:为CLOB字段创建全文索引,支持快速关键字搜索: ```sql CREATE CONTEXT INDEX idx_clob_content ON table_name(clob_column) LEXER DEFAULT_LEXER; ``` 查询时使用`CONTAINS()`函数: ```sql SELECT * FROM table_name WHERE CONTAINS(clob_column, '关键词'); ``` - **函数索引**:若需按固定位置截取内容查询,可对截取结果建索引: ```sql CREATE INDEX idx_substr_clob ON table_name(SUBSTR(clob_column, 1, 100)); ``` #### 3. **SQL查询优化** - **避免直接操作CLOB**:减少在WHERE条件中使用`LIKE`或`=`操作CLOB字段,优先通过关联字段筛选。 - **分页优化**:分页查询时通过`ROWID`或主键关联,避免全表扫描: ```sql SELECT t.* FROM ( SELECT ROWID rid, ROWNUM rn FROM table_name WHERE ... ORDER BY ... ) tmp, table_name t WHERE tmp.rid = t.ROWID AND tmp.rn BETWEEN 1 AND 10; ``` #### 4. **存储参数调整** - **设置合理存储空间**:创建表时指定CLOB字段的存储参数,减少空间碎片: ```sql CREATE TABLE table_name ( id INT, clob_column CLOB STORAGE (INITIAL 4096 NEXT 4096) ); ``` - **缓存优化**:增大`BUFFER`和`MAX_BUFFER`参数,提升大字段读取效率。 #### 5. **应用层优化** - **结果集缓存**:对频繁查询的CLOB内容使用缓存(如Redis),减少数据库访问[^3]。 - **分批读取**:通过游标逐批获取数据,避免一次性加载大量CLOB内容。 #### 6. **分区表技术** - **按范围/时间分区**:将大表按业务逻辑拆分,缩小查询范围: ```sql CREATE TABLE table_name ( id INT, clob_column CLOB, create_time DATE ) PARTITION BY RANGE(create_time) ( PARTITION p2023 VALUES LESS THAN (DATE '2024-01-01'), PARTITION p2024 VALUES LESS THAN (MAXVALUE) ); ``` #### 7. **执行计划分析** - 使用达梦的`EXPLAIN`工具分析SQL执行计划: ```sql EXPLAIN SELECT * FROM table_name WHERE CONTAINS(clob_column, 'test'); ``` - 重点关注全表扫描、临时表生成等高成本操作。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值