2009-01-19 51 views
4

時獲取的列值被截斷我有一個程序使用非常簡單的查詢從Oracle 10g(10.2.0.3)中提取大型數據集。幾乎可以將查詢/邏輯稱爲「導出」類,因爲它從具有最小where子句的表中選擇列(即,它返回大部分(如果不是全部)行)。SQLException:執行while(rs.getNext())

的【JAVA]代碼是樣板,我們都看到:

Connection con = null; 
PreparedStatement pstmt = null; 
ResultSet rs = null; 
try { 
    con = getConnection(Person); 
    pstmt = con.prepareStatement(
      "SELECT ID, FIRST_NAME, LAST_NAME, ... FROM PERSON WHERE ..."); 
    rs = pstmt.executeQuery(); 
    while (rs.next()) { 
     // write the data to a file 
    } 
} 
finally { 
    if (rs != null) try { rs.close(); } catch (Exception e) { } 
    if (pstmt != null) try {pstmt.close(); } catch (Exception e) { } 
    if (con != null) try { con.close() ; } catch (Exception e) { } 
} 

的getConnection是我自己的方法,該方法返回一個Connection對象到用於「人」表中的Oracle數據庫。這感覺像一個平凡的編程問題,但我已經寫了這麼多次的代碼,從來沒有這個問題。

我收到一個java.sql.SQLException:ORA-01406:fetched列值在while(rs.next())行被截斷。我讀過的Oracle文檔說「FETCH操作被迫截斷字符串」。它建議使用更大的列緩衝區來保存最大的列。但這沒有意義。在上面代碼中被註釋爲「將數據寫入文件」的部分中,我簡單地寫每一列與rs.getBigDecimal(「ID」),rs.getString(「FIRST_NAME」等等一樣。事實上,使用一個空的while循環重現該區域,這個循環對ResultSet什麼都不做,也就是說,只是迭代ResultSet導致拋出SQLException

返回的數據集的大小應該大約爲100萬行。後通過循環約600,000行/迭代例外。任何想法?

回答

1

是Person表或視圖?

在某個時刻,在幕後,爪哇必須制定出一個用於數據的數據長度,而且我顧它是做錯了。首先,逐個刪除列,以便確定哪一列出錯。然後,可能會通過塊(例如1-100000,100001-200000等)中的數據來查找導致錯誤的塊。然後縮小塊(100000-150000等),直到找到導致問題的單行。通過查看該行,可能很明顯是什麼問題。如果不是,請嘗試使用DUMP函數查看數據中的字節。

在數值列的數據不對應於列定義它是可能的。這通常是一個錯誤,可能是磁盤損壞,有時通過OCI創建的奇怪數據。你可以嘗試做一個

SELECT COUNT(*) FROM PERSON WHERE ID != TRUNC(ID); 

如果你的數據庫使用多字節字符集,這可能會混淆與字符串的東西。此外,如果有一個字符串非傳統字符(例如ASCII 0-31)

0

對我來說,要做的第一件事就是看「故障」的數據,通過修改你的循環,以顯示其觸發行例外。

+0

當的SQLException在rs.next()拋出,我沒有訪問導致錯誤的行。異常之前的最後一行不會顯示任何奇怪的內容。我仍在調查,但我傾向於編碼/字符寬度問題,如igor-db所示。 – brmiller 2009-01-20 03:46:38

0

首先嚐試getMaxFieldSize上查詢,你明確地最大費爾德大小是什麼知道的方式。我不是一個Oracle程序員(PostgreSQL的),但我確實知道,甲骨文應該有一個,如果不是最好的,元數據支持。與最大字段大小限制修改SQL查詢。那至少會讓你走到一半。

公衆詮釋getMaxFieldSize() 拋出的SQLException

Returns the maximum number of bytes allowed for any column value. 

此限制是可用於任何 列值返回 字節的最大數目。此限制僅適用於BINARY,VARBINARY,LONGVARBINARY, CHAR,VARCHAR和LONGVARCHAR 列中的 列。如果超出限制,則會丟棄多餘的數據。

Returns: 
    the current max column size limit; zero means unlimited 
Throws: 
    SQLException - if a database access error occurs 
0

順便說一句,你應該考慮使用Apache Commons DBUtils關閉您的資源。這將允許您更換您的最終條款的內容,有一行:

DBUtils.closeQuietly(con, pstmt, rs);