您的位置:首页 > 数据库

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

2016-04-06 15:43 441 查看
在工作中,出现一个问题就是读文本文件插入到数据库表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 数据库