-- 定義 4000 位元組欄位
VARCHAR2(4000) abc;
-- 嘗試插入 1500 個中文字
INSERT INTO table_name(abc) VALUES ('這裡有1500個漢字……');
-- 錯誤:ORA-12899: value too large for column
測試發現:1 個中文字 = 3 位元組 (UTF8),4000 / 3 ≈ 1333 字,1500 字超出限制。
SQL> SELECT * FROM v$nls_parameters WHERE parameter = 'NLS_CHARACTERSET';
PARAMETER VALUE
------------------ ----------------
NLS_CHARACTERSET AL32UTF8
AL32UTF8 (UTF-8):中文字編碼佔 3 位元組,英文/數字/符號佔 1 位元組。VARCHAR2(4000 BYTE) 以位元組為單位,故中文容量大幅縮水。
| 字符集 | 中文編碼 | VARCHAR2(4000) 中文容量 | 適用場景 |
|---|---|---|---|
| AL32UTF8 / UTF8 | 3 bytes | ~1,333 字 | 多語言、國際化、Unicode 標準 |
| ZHS16GBK | 2 bytes | ~2,000 字 | 簡體中文為主、舊系統相容 |
| ZHT16BIG5 / ZHT16MSWIN950 | 2 bytes | ~2,000 字 | 繁體中文為主、台灣/香港舊系統 |
| ZHS16CGB231280 | 2 bytes | ~2,000 字 | GB2312 標準、極舊系統 |
| US7ASCII | 不支援中文 | 0 | 純英文環境 |
-- 方式 1:明確指定 CHAR 語意
ALTER TABLE table_name MODIFY abc VARCHAR2(4000 CHAR);
-- 方式 2:Session 級預設 CHAR 語意
ALTER SESSION SET NLS_LENGTH_SEMANTICS = CHAR;
-- 後續建表 VARCHAR2(4000) 自動為字元語意
優勢:VARCHAR2(4000 CHAR) 固定可存 4000 字元,不受字符集影響。UTF8 環境下中文容量從 1333 字提升至 4000 字 (佔 12000 位元組)。
注意:最大位元組上限仍為 4000 bytes (資料庫區塊限制),極端情況 (全 4-byte 字元如 Emoji) 仍可能受限。
SHUTDOWN IMMEDIATE;
STARTUP MOUNT;
ALTER SYSTEM ENABLE RESTRICTED SESSION;
ALTER SYSTEM SET JOB_QUEUE_PROCESSES = 0;
ALTER DATABASE OPEN;
ALTER DATABASE CHARACTER SET ZHS16GBK; -- 或 AL32UTF8/ZHS16GBK
SHUTDOWN IMMEDIATE;
STARTUP;
風險:
ALTER TABLE table_name MODIFY abc CLOB;
CLOB 以字元為單位管理,無 4000 位元組硬限制,適合長文本、文章、日誌儲存。
NLS_LENGTH_SEMANTICS = CHAR 系統級預設,所有 VARCHAR2 自動為字元語意VARCHAR2(n CHAR),優先處理中文業務欄位DBA_TAB_COLUMNS 找出 CHAR_USED = 'B' 且含中文業務的欄位-- 找出所有 BYTE 語意且可能存中文的欄位
SELECT owner, table_name, column_name, data_type, data_length, char_used
FROM dba_tab_columns
WHERE char_used = 'B'
AND data_type LIKE 'VARCHAR2%'
AND owner NOT IN ('SYS','SYSTEM')
ORDER BY data_length DESC;
UTF8 環境下 VARCHAR2 位元組語意是中文系統的隱形殺手。改用 CHAR 語意 (VARCHAR2(n CHAR)) 是零風險、零遷移、即時生效的最佳解法。字符集遷移屬核彈級操作,非萬不得已不可為。