db2数据库的Clob域出现字符串过长插入失败的问题

在工作中,出现一个问题就是读文本文件插入到数据库表clob域中,数据库错误码是-102,文件大小超过37.5kb就会出现这个错误,而clob域最大容量是2g。

后来在网上查找资料,终于有大神说出了问题的根本原因。

大神如是说:

这个是执行命令行命令字条串长度的问题,
你可以用参数传入的方式进行操作。

的确,我的代码中是:

public static void main(String[] args) {
		java.io.File file = new java.io.File("E:/aaa.dat");
		java.io.InputStreamReader isr = null;
		String line,result="";
		try {
			isr = new java.io.InputStreamReader(new java.io.FileInputStream(file),"utf-8");
			java.io.BufferedReader br = new java.io.BufferedReader(isr);
			
			while ((line = br.readLine()) != null) {
				result+=line;
			}
		} catch (java.io.IOException e) {
			e.printStackTrace();
		}
		Connection conn = null;
		try {
			Class.forName("com.ibm.db2.jcc.DB2Driver");
			String url="jdbc:db2://localhost:50000/testdb";
			String user ="test";
			String passwd = "test";
			
			conn = java.sql.DriverManager.getConnection(url, user,passwd);
			if (conn == null) {
				System.out.println("获取数据库连接失败!");
				return;
			}
			String sql = "INSERT INTO CLOB_TABLE"
					+ "(TRAN_DATE,TRAN_TIME,INS_DATETIME,FILE_NAME,CLOB_CONTENT)"
					+ "VALUES('20160330','153835046','20160331104726','aaa.dat',"'
					+ result + "')";
			PreparedStatement stmt = conn.prepareStatement(sql);
			if (!(stmt.executeUpdate() > 0)) {
				System.out.print("保存信息失败");
			}
		} catch (ClassNotFoundException e1) {
			e1.printStackTrace();
		}catch (SerialException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}
}
当aaa.dat这个文件内容大小超过37.5kb时,就会插库失败,数据库错误码是-102,查了一下是字符串常量太长,一开始以为是数据库中的Clob域不能存放超过37.5kb的内容,后来查了一下Clob域最大可以容纳2g的内容,想到是不是Clob默认大小没有2g,是不是需要修改数据库或者表的设置。直到在网上看到大神的回答。

将代码修改一下,就可以了。(改为用参数传入的方式)

public static void main(String[] args) {
		java.io.File file = new java.io.File("E:/aaa.dat");
		java.io.InputStreamReader isr = null;
		String line,result="";
		try {
			isr = new java.io.InputStreamReader(new java.io.FileInputStream(file),"utf-8");
			java.io.BufferedReader br = new java.io.BufferedReader(isr);
			
			while ((line = br.readLine()) != null) {
				result+=line;
			}
		} catch (java.io.IOException e) {
			e.printStackTrace();
		}
		Connection conn = null;
		try {
			Class.forName("com.ibm.db2.jcc.DB2Driver");
			String url="jdbc:db2://localhost:50000/testdb";
			String user ="test";
			String passwd = "test";
			
			conn = java.sql.DriverManager.getConnection(url, user,passwd);
			if (conn == null) {
				System.out.println("获取数据库连接失败!");
				return;
			}
			String sql = "INSERT INTO CLOB_TABLE"
					+ "(TRAN_DATE,TRAN_TIME,INS_DATETIME,FILE_NAME,CLOB_CONTENT)"
					+ "VALUES('20160330','153835046','20160331104726','aaa.dat',"
					+ "?)";
			PreparedStatement stmt = conn.prepareStatement(sql);
			java.sql.Clob c = new javax.sql.rowset.serial.SerialClob(result
					.toCharArray());
			stmt.setClob(1, c);
			if (!(stmt.executeUpdate() > 0)) {
				System.out.print("保存信息失败");
			}
		} catch (ClassNotFoundException e1) {
			e1.printStackTrace();
		}catch (SerialException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}
}

补充一个db2函数,在查找原因的时候发现的。

使用length(CLOB_CONTENT)来查询Clob域的内容长度,当然varchar等其他域也可以使用length函数。

在db2中没有datalength和len函数,只能使用length函数。


另外,在修改后遇到一个问题,到目前我还没查出原因。

查询时,查询到的结果Clob域很大的时候,就会出现错误,数据库错误码是-433(指定的值太长)。

查询的sql是

select * from CLOB_TABLE where CLOB_CONTENT is not null and CLOB_CONTENT !='' and TRAN_DATE='20160330'

我发现是CLOB_CONTENT !=''这个地方出了问题,只要我把这里删了就查询成功了,使用like '*'也可以。

但我没找到原因,只能把这句删了。


最后,补充一个前端小细节。

当label用来显示长字符窜时,会使得横向滚动条很小,拉起来也不方便,我们会选择把后面的内容隐藏起来,只显示前面的部分内容,然后用省略号代码后面被隐藏的部分。

把label的style设置为"text-overflow:ellipsis;white-space:nowrap;overflow:hidden"

然后给label设置一个宽度,超过这个宽度就会自动隐藏起来。

可是当字符串很长时,虽然拖动滚动条就会很慢,建议在js做预先的处理,把字符串先截一部分出来。


你可能感兴趣的:(工作笔记,db2,数据库)