首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

ORA-01461「僅能綁定 LONG 值」錯誤:VARCHAR2 超長自動轉 LONG 陷阱

     編輯:Oracle 資料庫相關知識

Hibernate 批次寫入 Oracle 時拋出 ORA-01461: can bind a LONG value only for insert into a LONG column。經查,欄位定義為 VARCHAR2(1024),但實際寫入資料超過 4000 位元組上限,導致 Oracle 隱式轉換為 LONG 型別,JDBC 驅動無法綁定而報錯。

一、錯誤堆疊關鍵訊息

Caused by: java.sql.BatchUpdateException: ORA-01461: 僅能綁定要插入 LONG 列的 LONG 值
    at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(...)

二、根因深度解析

  1. Oracle VARCHAR2 最大長度為 4000 位元組(MAX_STRING_SIZE=STANDARD 時)。
  2. 當插入資料超過 4000 位元組,Oracle 內部會嘗試將該值視為 LONG 型別處理。
  3. JDBC PreparedStatement.setString() 綁定的是 VARCHAR2,不支援 LONG 綁定,因而拋出 ORA-01461。
  4. 欄位雖定義 VARCHAR2(1024),但若字元集為 UTF-8,1024 字元最多 3072 位元組,仍在 4000 內;問題通常發生在 CLOB/大文本誤存入 VARCHAR2 或 字元集轉換膨脹。

三、解決方案

方案一:業務層面截斷或驗證(優先)

// 寫入前檢查
if (str.getBytes("UTF-8").length > 4000) {
    str = truncateToBytes(str, 4000, "UTF-8");
}

確保資料長度符合 VARCHAR2 物理限制。

方案二:改用 CLOB 型別(根治)

  1. 資料庫端:ALTER TABLE ... MODIFY COL_NAME CLOB;
  2. Hibernate 映射:@Lob @Column(columnDefinition="CLOB") private String content;
  3. JDBC 綁定:使用 setCharacterStream() 或 setClob()。

方案三:外部化儲存(超大物件)

  • 將大文本存入檔案系統/物件儲存(S3、NAS),資料庫僅存儲路徑/URL。
  • 適用於超過 4GB 的超大物件(CLOB 上限)。

四、避坑指南

誤區正確認知
VARCHAR2(4000) 就能存 4000 字元上限是 4000 位元組,UTF-8 下中文僅能存 ~1333 字元
超過 4000 會自動轉 CLOB會轉為 LONG(已棄用),不支援綁定,需顯式用 CLOB
LONG 可正常用 JDBC 操作LONG 已不建議使用,Oracle 12c+ 可能完全移除

五、檢查腳本:尋找潛在風險欄位

SELECT OWNER, TABLE_NAME, COLUMN_NAME, DATA_TYPE, CHAR_LENGTH, CHAR_USED
FROM DBA_TAB_COLUMNS
WHERE DATA_TYPE IN ('VARCHAR2','NVARCHAR2','CHAR','NCHAR')
  AND CHAR_LENGTH * CASE WHEN CHAR_USED='C' THEN 1 ELSE 3 END > 4000
ORDER BY OWNER, TABLE_NAME;

此查詢可找出定義長度可能超過 4000 位元組的欄位,提前排查。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved