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做預先的處理,把字符串先截一部分出來。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章