JAVA读取、写入、更新CLOB字段

news/2024/5/19 0:01:42 标签: java, jdbc, clob

        jdbc或PL/SQL中通过insert语句插入数据时,如果有CLOB字段,且插入的数据长度超过4000,且会报ORA-01704字符串文字太长的错。

一.java jdbc方式处理

        对于CLOB字段,其实就需要通过流的方式处理,如下是从网上搜集的一些处理方式。

1.CharacterStream方式

java">/*
--建表语句如下:
create table t_clob(
		id varchar2(32) primary key,
		clobfield CLOB
		);
 */

/**
 * 读取CLOB字段的代码示例
 */
public void readClob() {
	//自定义的数据库连接管理类 
	Connection conn = DbManager.getInstance().getConnection();
	try {
		PreparedStatement stat = conn
				.prepareStatement("select clobfield from t_clob where id='1'");
		ResultSet rs = stat.executeQuery();
		if (rs.next()) {
			oracle.sql.CLOB clob = (oracle.sql.CLOB) rs
					.getClob("clobfield");
			String value = clob.getSubString(1, (int) clob.length());
			System.out.println("CLOB字段的值:" + value);
		}
		conn.commit();
	} catch (SQLException e) {
		e.printStackTrace();
	}

	DbManager.getInstance().closeConnection(conn);
}

/**
 * 写入、更新CLOB字段的代码示例
 */
public void writeClob() {
	//自定义的数据库连接管理类 
	Connection conn = DbManager.getInstance().getConnection();
	try {
		conn.setAutoCommit(false);
		// 1.这种方法写入CLOB字段可以。
		PreparedStatement stat = conn
				.prepareStatement("insert into t_clob (id,clobfield) values(sys_guid(),?)");
		String clobContent = "This is a very very long string";
		StringReader reader = new StringReader(clobContent);
		stat.setCharacterStream(1, reader, clobContent.length());
		stat.executeUpdate();

		// 2.使用类似的方法进行更新CLOB字段,则不能成功 
		// stat.close();
		// stat =null;
		// stat =
		// conn.prepareStatement("update t_clob set clobfield=? where id=1");
		// stat.setCharacterStream(1, reader, clobContent.length());
		// stat.executeUpdate();

		// 3.需要使用for update方法来进行更新,
		// 但是,特别需要注意,如果原来CLOB字段有值,需要使用empty_clob()将其清空。
		// 如果原来是null,也不能更新,必须是empty_clob()返回的结果。
		stat = conn
				.prepareStatement("select clobfield from t_clob where id='1' for update");
		ResultSet rs = stat.executeQuery();
		if (rs.next()) {
			oracle.sql.CLOB clob = (oracle.sql.CLOB) rs
					.getClob("clobfield");
			Writer outStream = clob.getCharacterOutputStream();
			char[] c = clobContent.toCharArray();
			outStream.write(c, 0, c.length);
			outStream.flush();
			outStream.close();
		}
		conn.commit();
	} catch (SQLException | IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	DbManager.getInstance().closeConnection(conn);
}

2.BufferedReader方式

        CLOB用于存储大量的字符数据,读取CLOB的JDBC代码如下所示。

java">import java.sql.*;
import java.io.*;

public class ReadClob {
	public static void main(String[] args) {
		PreparedStatement pstmt = null;
		ResultSet rset = null;
		BufferedReader reader = null;
		Connection conn = null;
		String driver = "oracle.jdbc.driver.OracleDriver";
		String strUrl = "jdbc:oracle:thin@127.0.0.1:1521:ORCL";
		try {
			Class.forName(driver);
			conn = DriverManager.getConnection(strUrl, "scott", "tiger");
			pstmt = conn
					.prepareStatement("select v_clob form ord where ORD_id =?");
			pstmt.setInt(1, 1);
			rset = pstmt.executeQuery();
			while (rset.next()) {
				Clob clob = rset.getClob(1);// java.sql.Clob类型
				reader = new BufferedReader(new InputStreamReader(clob
						.getAsciiStream()));
				String line = null;
				while ((line = reader.readLine()) != null) {
					System.out.println(line);
				}
			}
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

        程序代码从结果集中获取CLOB字段,再将其转化为IO流进行读取。那么,JDBC将大量自读数据写入CLOB字段的操作需要首先用“for update”字句查找CLOB字段,然后从结果集中获取CLOB字段并转化为oracle.sql.CLOB类型进行写入操作。 

java">//写入操作
String stmtString = "select v_clob form ord  where ord_id =? for update";
pstmt = conn.prepareStatement(stmtString);
pstmt.setInt(1, 2);
rset = pstmt.executeQuery();
while(rset.next()){
	//造型为oracle.sql.CLOB
	CLOB clob = (CLOB)rset.getClob(1);
	String newClobDate = new String("NEW CLOOB DATE");
	Writer writer = clob.getCharacterOutputStream();
	//OutStream writer = clob.getAsciiOutputStream();
	writer.write(newClobDate);
}

3.生成一个clob对象,通过预处理的setClob达到插入更新的目的。

        方法一:

java">Connection con = dbl.loadConnection();
strSql = "insert into table1(id,a) values (1,EMPTY_CLOB())";
dbl.executeSql(strSql);
String str2 = "select a from table1 where id=1";

ResultSet rs = dbl.openResultSet(str2);
if(rs.next()){
    CLOB c = ((OracleResultSet)rs).getCLOB("a");
    c.putString(1, "长字符串");
    String sql = "update table1 set a=? where id=1";
    PreparedStatement pstmt = con.prepareStatement(sql);
    pstmt.setClob(1, c);
    pstmt.executeUpdate();
    pstmt.close();
}
con.commit();

        方法二:

java">Connection con = dbl.loadConnection();
CLOB clob   = oracle.sql.CLOB.createTemporary(con, false,oracle.sql.CLOB.DURATION_SESSION);
clob.putString(1,  "长字符串");
Sql1 = "update table1 set a=? where id=1";
PreparedStatement pst = con.prepareStatement(Sql1);
pst.setClob(1, clob);
pst.executeUpdate();
pst.close();
con.commit();

 

二.sql方式

        当通过insert语句直接插入大量字符串(主要是html的内容),超过4000字符时候,就会报:ORA-01489: 字符串连接的结果过长。

        虽然字段是clob,足以存储,但是通过这种直接插入的时候,因为没有强制指定带插入字符串为clob类型,oracle会把插入的字符串作为 “字符串类型”处理,由于oracle有最大字符串限制(不超过4000个字符),所以会报错。

        解决思路:指定待插入字符串类型为clob,可以使用过程或存储过程。

实例:

DECLARE
 REALLYBIGTEXTSTRING CLOB := '待插入的海量字符串';
BEGIN
   INSERT INTO test_table VALUES('test', REALLYBIGTEXTSTRING, '0');
end ;
/
commit;

补充:插入html内容,可能含有空格  ,字符&是oracle的关键字,因此插入之前要转义,如:'||chr(38)||'nbsp;


http://www.niftyadmin.cn/n/1317109.html

相关文章

spring mvc使用@InitBinder标签对表单数据绑定

在SpringMVC中,bean中定义了Date,double等类型,如果没有做任何处理的话,日期以及double都无法绑定。 解决的办法就是使用spring mvc提供的InitBinder标签。 在我的项目中是在BaseController中增加方法initBinder,并使用…

Ehcache介绍

1.相关背景 局部访问性原则:被访问的数据以及临近的数据很有可能被再次访问到。 Locality of Reference,Data that is near other data or has recently been used is more likely to be used again. 长尾原则:二八原则。 If 20% of objects …

CoronaSDK DisplayObject Summary (2511 API)

著名跨平台手游引擎Corona SDK的Display对象创建方式汇总:第一部分:分组类Group:display.newGroup()Container:display.newContainer( [parent, ] width, height )第二部分:图像类ImageSheet:(图像列表) graphics.newImageSheet( filename, [baseDir, ] …

Java设计模式-设计模式的六大原则

所谓无招胜有招,练一门功夫分为内功和外功。外功好比招式,就是所谓的23种设计模式。而内功呢,就是心法,那就是这6种法则。光会外功那是花拳绣腿,内功修为才是境界。如此众多的设计模式,学完2遍,…

softInputMode- 软件盘的设置

今天遇到一个问题&#xff0c;就是软件盘弹出来以后&#xff0c;会把之前的布局界面整个的挤到屏幕的外面&#xff0c;而且按下返回建以后&#xff0c;这个软件盘占据的空间会留下一个黑色的背景。在网上查找了很多的方法&#xff0c;刚开始都是说&#xff0c;如下方法 <act…

Java 程序员应该了解的 10 个面向对象设计原则

面向对象设计原则是OOPS&#xff08;Object-Oriented Programming System&#xff0c;面向对象的程序设计系统&#xff09;编程的核心&#xff0c;但大多数Java程序员追逐像Singleton、Decorator、Observer这样的设计模式&#xff0c;而不重视面向对象的分析和设计。甚至还有经…

IOS SDK详解

来源&#xff1a;http://blog.csdn.net/column/details/huangwenchen-ios-sdk.html?page1#42803301 博客专栏>移动开发专栏>IOS SDK详解分享到&#xff1a;新浪微博腾讯微博IOS SDK详解本专栏从IOS SDK中常用的Framework出发&#xff0c;继而深入的介绍各个Framework。每…

Java实现将一个字符串转换成无重复的有序列表

将一个字符串转换成无重复的有序列表&#xff0c;方法很多&#xff0c;但步骤应该主要就是先转换成String数组&#xff0c;再去重&#xff0c;最后转换成有序列表。 而其实每步都有很多种方式&#xff0c;如去重可以直接用for循环&#xff0c;也可以用hashSet&#xff0c;当然如…