記錄兩個在 Oracle JDBC 開發中高頻出現的棘手異常及其解決之道。
Exception in thread "main" java.sql.SQLException:
ORA-00600: internal error code, arguments: [ttcgcshnd-1], [0], [], [], [], [], [], []
原因:使用了不相容的 JDBC 驅動 JAR(常見於專案引用錯誤版本)。
解決:改用 Oracle 安裝目錄下的 jdbc/lib/classes12.jar(或對應版本的 ojdbc6.jar/ojdbc8.jar),確保驅動與資料庫版本匹配。
java.sql.SQLException: 資料大小超出此類型的最大值: 3000
場景:表欄位定義為 VARCHAR(3000),嘗試寫入長字串時拋出。
根因:Oracle JDBC 驅動對 setString 有隱性長度限制,且 CHAR/VARCHAR 在某些版本行為不一。
解決:改用 setCharacterStream 以串流方式寫入大文本:
String longText = "我".repeat(1000); // 約 3000 bytes
PreparedStatement pst = conn.prepareStatement("INSERT INTO test(name, addr) VALUES(?, ?)");
pst.setString(1, "kingfish");
pst.setCharacterStream(2,
new InputStreamReader(new ByteArrayInputStream(longText.getBytes("UTF-8"))),
longText.length());
pst.executeUpdate();
import java.sql.*;
import java.io.*;
import java.util.*;
public class TestOracleLargeText {
public static void main(String[] args) {
String url = "jdbc:oracle:thin:@localhost:1521:oradb";
try (Connection conn = DriverManager.getConnection(url, "system", "manager")) {
char[] chars = new char[1000];
Arrays.fill(chars, '我');
String s = new String(chars);
try (PreparedStatement pst = conn.prepareStatement("INSERT INTO test(name, addr) VALUES(?, ?)")) {
pst.setString(1, "kingfish");
pst.setCharacterStream(2,
new InputStreamReader(new ByteArrayInputStream(s.getBytes("UTF-8"))),
s.length());
pst.executeUpdate();
}
try (Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT addr FROM test WHERE name='kingfish'")) {
if (rs.next()) {
String val = rs.getString(1);
System.out.println("長度: " + val.length() + " 內容: " + val);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
核心原則:大文本欄位(CLOB/VARCHAR2 > 4000)請務必使用
setCharacterStream或setClob,避開setString限制。