ORACLE 操作 CLOB 字段

方法一:


Oracle中,LOB(Large Object,大型对象)类型的字段现在用得越来越多了。因为这种类型的字段,容量大(最多能容纳4GB的数据),且一个表中可以有多个这种类型的字段,很灵活,适用于数据量非常大的业务领域(如图象、档案等)。而LONG、LONG RAW等类型的字段,虽然存储容量也不小(可达2GB),但由于一个表中只能有一个这样类型的字段的限制,现在已很少使用了。

 

 

LOB类型分为BLOB和CLOB两种:BLOB即二进制大型对象(Binary Large Object),适用于存贮非文本的字节流数据(如程序、图象、影音等)。而CLOB,即字符型大型对象(Character Large Object),则与字符集相关,适于存贮文本型的数据(如历史档案、大部头著作等)。

 

下面以程序实例说明通过JDBC操纵Oracle数据库LOB类型字段的几种情况。

 

先建立如下两个测试用的数据库表,Power Designer PD模型如下:

 

 

建表SQL语句为:

CREATE TABLE TEST_CLOB ( ID NUMBER(3), CLOBCOL CLOB)

CREATE TABLE TEST_BLOB ( ID NUMBER(3), BLOBCOL BLOB)

 

一、 CLOB对象的存取

 

1、往数据库中插入一个新的CLOB对象

 

public static void clobInsert(String infile) throws Exception

{

 

boolean defaultCommit = conn.getAutoCommit();

conn.setAutoCommit(false);

 

try {

 

stmt.executeUpdate("INSERT INTO TEST_CLOB VALUES ('111', EMPTY_CLOB())");

 

ResultSet rs = stmt.executeQuery("SELECT CLOBCOL FROM TEST_CLOB WHERE ID='111' FOR UPDATE");

while (rs.next()) {

 

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

 

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();

}

 

conn.commit();

} catch (Exception ex) {

 

conn.rollback();

throw ex;

}

 

 

conn.setAutoCommit(defaultCommit);

}

 

2、修改CLOB对象(是在原CLOB对象基础上进行覆盖式的修改)

 

public static void clobModify(String infile) throws Exception

{

 

boolean defaultCommit = conn.getAutoCommit();

conn.setAutoCommit(false);

 

try {

 

ResultSet rs = stmt.executeQuery("SELECT CLOBCOL FROM TEST_CLOB WHERE ID='111' FOR UPDATE");

while (rs.next()) {

 

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

 

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();

}

 

conn.commit();

} catch (Exception ex) {

 

conn.rollback();

throw ex;

}

 

 

conn.setAutoCommit(defaultCommit);

}

 

3、替换CLOB对象(将原CLOB对象清除,换成一个全新的CLOB对象)

 

public static void clobReplace(String infile) throws Exception

{

 

boolean defaultCommit = conn.getAutoCommit();

conn.setAutoCommit(false);

 

try {

 

stmt.executeUpdate("UPDATE TEST_CLOB SET CLOBCOL=EMPTY_CLOB() WHERE ID='111'");

 

ResultSet rs = stmt.executeQuery("SELECT CLOBCOL FROM TEST_CLOB WHERE ID='111' FOR UPDATE");

while (rs.next()) {

 

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

 

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();

}

 

conn.commit();

} catch (Exception ex) {

 

conn.rollback();

throw ex;

}

 

 

conn.setAutoCommit(defaultCommit);

}


方法二:


Oracle中,Varchar2支持的最大字节数为4KB,所以对于某些长字符串的处理,我们需要用CLOB类型的字段,CLOB字段最大支持4GB。 
还有其他几种类型: 
blob:二进制,如果exe,zip 
clob:单字节码,比如一般的文本文件. 
nlob:多字节码,如UTF格式的文件. 
以下就是对CLOG字段的操作方法,在我们的项目中帮助文档部分用到。 
1、首先是写入 

  1. /* 以下表PF_HELP_CONTENT中的HCONTENT字段时CLOB类型的 */  
  2. // 通过序列器生成帮助ID   
  3. Map map = Query.getMap("Select TO_CHAR(SEQ_HID.nextval) HID FROM DUAL ");   
  4. hid = String.valueOf(map.get("HID"));   
  5. //插入一条数据,注意CLOB字段,需要先插入一个空的clob类型 empty_clob(),然后再单独更新clob字段   
  6. sql = "Insert INTO PF_HELP_CONTENT(HID,HCONTENT) VALUES (?,empty_clob())  ";   
  7. try  
  8. {             
  9.      //执行插入   
  10.      rtn = DbUtils.executeUpdate(sql,hid);       
  11.      /* 插入成功后,修改HCONTENT字段内容 */  
  12.      //取得数据库连接                            
  13.      Connection conn = DbUtils.getConnection();   
  14.      //手动提交   
  15.      conn.setAutoCommit(false);   
  16.      //定义ResultSet 和 Clob 变量   
  17.      ResultSet rs = null;   
  18.      oracle.sql.CLOB clob = null;   
  19.      //更新SQL   
  20.      String sqlclob = "Select HCONTENT FROM PF_HELP_CONTENT Where HID=? FOR Update ";   
  21.      java.sql.PreparedStatement pstmt = conn.prepareStatement(sqlclob);   
  22.      //hid是varchar2类型的,所以用setString   
  23.      pstmt.setString(1,hid);   
  24.      //执行update语句   
  25.      rs= pstmt.executeQuery();   
  26.      if(rs.next())   
  27.      {   
  28.         //取得刚才的HCONTENT的内容,也就是刚才添加的empty_clob()   
  29.         clob = (oracle.sql.CLOB)rs.getClob(1);   
  30.      }   
  31.      //需要用clob.getCharacterOutputStream()流方式输出   
  32.      Writer write = clob.getCharacterOutputStream();   
  33.      //写入具体内容,helpform.getHContent() 存的是帮助的内容   
  34.      write.write(helpform.getHContent());   
  35.      write.flush();   
  36.      write.close();   
  37.      rs.close();   
  38.      //提交   
  39.      conn.commit();   
  40.      conn.close();   
  41. }   
  42. catch(Exception ex)   
  43. {   
  44.     //.........   
  45. }  

2、修改CLOB字段内容  
  1. /* 修改跟插入时基本一致,也是用for update来实现 */  
  2. //如果修改前的字段内容长度大于当前修改的长度时,末尾的部分内容仍然会存在   
  3. //所以在修改内容前,需要将PF_HELP_CONTENT内容置空   
  4. sql = " Update PF_HELP_CONTENT SET HCONTENT=empty_clob() Where HID=? ";   
  5. try  
  6. {         
  7.  rtn = DbUtils.executeUpdate(sql,hid);   
  8.  //以下操作跟添加时一样                                  
  9.  Connection conn = DbUtils.getConnection();   
  10.  conn.setAutoCommit(false);   
  11.  ResultSet rs = null;   
  12.  oracle.sql.CLOB clob = null;   
  13.  String sqlclob = "Select HCONTENT FROM PF_HELP_CONTENT Where HID=? FOR Update ";   
  14.  java.sql.PreparedStatement pstmt = conn.prepareStatement(sqlclob);   
  15.  pstmt.setString(1,hid);   
  16.  rs= pstmt.executeQuery();   
  17.  if(rs.next())   
  18.  {   
  19.     clob = (oracle.sql.CLOB)rs.getClob(1);   
  20.  }   
  21.  Writer write = clob.getCharacterOutputStream();   
  22.  write.write(helpform.getHContent());   
  23.  write.flush();   
  24.  write.close();   
  25.  rs.close();   
  26.  conn.commit();   
  27.  conn.close();                                   
  28. }   
  29. catch(Exception ex)   
  30. {   
  31.   //...   
  32. }  

================================================================================================

Tomcat+oracel
方法1:
oracle.sql.CLOB clob = (oracle.sql.CLOB) resultSet.getClob("TVALUE"); //初始化
Writer outStream = clob.getCharacterOutputStream(); */


方法二:
oracle.sql.CLOBclob = (oracle.sql.CLOB)resultSet.getClob(1);   
Writer write = clob.getCharacterOutputStream();   


weblogic+ oracle 
weblogic.jdbc.wrapper.Clob clob = (weblogic.jdbc.wrapper.Clob) resultSet.getClob("TVALUE");
writer = ((java.sql.Clob) clob).setCharacterStream(0L);


mysql+Tomcat+weblogic

String sql = "UPDATE "+tableClob.Name+" SET TVALUE=? WHERE TRID="+clobRowId+"";
PreparedStatement pst = conn.prepareStatement(sql);
Reader reader = new StringReader(colValue);
pst.setCharacterStream(1, reader);
int num = pst.executeUpdate(); 

================================================================================================


3、取出CLOB字段的文本内容 
  1. /* 前面部分都一致 */  
  2. Connection conn = DbUtils.getConnection();   
  3. conn.setAutoCommit(false);   
  4. ResultSet rs = null;   
  5. oracle.sql.CLOB clob = null;   
  6. String sqlclob = "Select HCONTENT FROM PF_HELP_CONTENT Where HID=? ";   
  7. java.sql.PreparedStatement pstmt = conn.prepareStatement(sqlclob);   
  8. pstmt.setString(1,hid);   
  9. rs= pstmt.executeQuery();   
  10. if(rs.next())   
  11. {   
  12.     //rs.getClob(1)中参数1指的是HCONTENT字段索引,第一个字段从1开始而不是从0。   
  13.     //也可以用字段名来取rs.getClob("HCONTENT")   
  14.     clob = (oracle.sql.CLOB)rs.getClob(1);   
  15. }   
  16. if(clob==null || clob.length()==0)   
  17. {   
  18.     hcontent = "";   
  19. }else  
  20. {   
  21.     //取CLOB字段内容为字符串   
  22.     hcontent=clob.getSubString((long)1,(int)clob.length());   
  23. }   
  24. rs.close();   
  25. conn.close();   
  26. request.setAttribute("HCONTENT",hcontent);  


  27. 转自: http://blog.csdn.net/yoland/article/details/6455982


=========================================================================================

  1. -建表语句如下: 
  2. create table t_clob( 
  3.         id varchar2(32) primary key, 
  4.         clobfield CLOB 
  5.         ); 
  6.  */  
  7.   
  8. /** 
  9.  * 读取CLOB字段的代码示例 
  10.  *  
  11.  * 作者:wallimn<br/> 
  12.  * 时间:2015-1-16<br/> 
  13.  * 联系:wallimn@sohu.com<br/> 
  14.  */  
  15. public void readClob() {  
  16.     //自定义的数据库连接管理类   
  17.     Connection conn = DbManager.getInstance().getConnection();  
  18.     try {  
  19.         PreparedStatement stat = conn  
  20.                 .prepareStatement("select clobfield from t_clob where id='1'");  
  21.         ResultSet rs = stat.executeQuery();  
  22.         if (rs.next()) {  
  23.             oracle.sql.CLOB clob = (oracle.sql.CLOB) rs  
  24.                     .getClob("clobfield");  
  25.             String value = clob.getSubString(1, (int) clob.length());  
  26.             System.out.println("CLOB字段的值:" + value);  
  27.         }  
  28.         conn.commit();  
  29.     } catch (SQLException e) {  
  30.         e.printStackTrace();  
  31.     }  
  32.   
  33.     DbManager.getInstance().closeConnection(conn);  
  34. }  
  35.   
  36. /** 
  37.  * 写入、更新CLOB字段的代码示例 
  38.  *  
  39.  * 作者:wallimn<br/> 
  40.  * 时间:2015-1-16<br/> 
  41.  * 联系:wallimn@sohu.com<br/> 
  42.  */  
  43. public void writeClob() {  
  44.     //自定义的数据库连接管理类   
  45.     Connection conn = DbManager.getInstance().getConnection();  
  46.     try {  
  47.         conn.setAutoCommit(false);  
  48.         // 1.这种方法写入CLOB字段可以。  
  49.         PreparedStatement stat = conn  
  50.                 .prepareStatement("insert into t_clob (id,clobfield) values(sys_guid(),?)");  
  51.         String clobContent = "This is a very very long string";  
  52.         StringReader reader = new StringReader(clobContent);  
  53.         stat.setCharacterStream(1, reader, clobContent.length());  
  54.         stat.executeUpdate();  
  55.   
  56.         // 2.使用类似的方法进行更新CLOB字段,则不能成功   
  57.         // stat.close();  
  58.         // stat =null;  
  59.         // stat =  
  60.         // conn.prepareStatement("update t_clob set clobfield=? where id=1");  
  61.         // stat.setCharacterStream(1, reader, clobContent.length());  
  62.         // stat.executeUpdate();  
  63.   
  64.         // 3.需要使用for update方法来进行更新,  
  65.         // 但是,特别需要注意,如果原来CLOB字段有值,需要使用empty_clob()将其清空。  
  66.         // 如果原来是null,也不能更新,必须是empty_clob()返回的结果。  
  67.         stat = conn  
  68.                 .prepareStatement("select clobfield from t_clob where id='1' for update");  
  69.         ResultSet rs = stat.executeQuery();  
  70.         if (rs.next()) {  
  71.             oracle.sql.CLOB clob = (oracle.sql.CLOB) rs  
  72.                     .getClob("clobfield");  
  73.             Writer outStream = clob.getCharacterOutputStream();  
  74.             char[] c = clobContent.toCharArray();  
  75.             outStream.write(c, 0, c.length);  
  76.             outStream.flush();  
  77.             outStream.close();  
  78.         }  
  79.         conn.commit();  
  80.     } catch (SQLException | IOException e) {  
  81.         // TODO Auto-generated catch block  
  82.         e.printStackTrace();  
  83.     }  
  84.   
  85.     DbManager.getInstance().closeConnection(conn);  
  86.   
  87. }  


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Oracle解析CLOB字段可以使用DBMS_LOB包提供的功能。 CLOBOracle数据库中一种特殊的数据类型,用于存储大文本数据。在解析CLOB字段时,需要使用DBMS_LOB包中的一些过程和函数。 首先,可以使用DBMS_LOB.GETLENGTH函数获取CLOB字段的长度。这个函数返回CLOB字段的字符数。 然后,可以使用DBMS_LOB.SUBSTR函数截取指定长度的CLOB字段的子字符串。这个函数接受两个参数,第一个参数是CLOB字段本身,第二个参数是截取的起始位置,第三个参数是截取的长度。它返回指定长度的子字符串。 另外,可以使用DBMS_LOB.FILEEXISTS函数检查CLOB字段是否关联了外部文件,返回TRUE或FALSE。 如果CLOB字段关联了外部文件,可以使用DBMS_LOB.FILEOPEN函数打开这个文件,然后可以使用DBMS_LOB.READ函数从文件中读取数据。 另外,可以使用DBMS_LOB.CREATETEMPORARY函数创建一个临时LOB对象,可以将CLOB字段的数据复制到该临时LOB对象中,然后可以使用DBMS_LOB.READ函数从临时LOB对象中读取数据。 在解析CLOB字段时,需要注意的是,CLOB字段可能存储了非常大的文本数据,所以需要谨慎处理,以避免内存溢出或性能问题。可以使用块大小和缓冲区大小等参数来提高解析CLOB字段的效率。 总之,通过使用DBMS_LOB包提供的函数和过程,我们可以很方便地解析CLOB字段并进行各种操作,例如获取长度、截取子字符串、读取关联文件等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值