| 屬性 | 規格 |
|---|---|
| 數據類別 | 變長字符串 |
| 最大長度 | 2 GB (2^31 - 1 字節) |
| 存儲方式 | 行內存儲 (小於 ~4KB) 或行外 LOB 段 (大於 ~4KB),與表數據同段 |
| 字符集 | 數據庫字符集 (NLS_CHARACTERSET) |
| 主要用途 | 歷史原因存儲超長文本 (數據字典視圖定義、舊應用大文本) |
| 狀態 | 已棄用,Oracle 8.0+ 引入 LOB (CLOB/NCLOB) 替代,**新開發嚴禁使用** |
Oracle 內部數據字典視圖 (如 `ALL_VIEWS.TEXT`, `ALL_TRIGGERS.TRIGGER_BODY`, `ALL_SOURCE.TEXT`, `ALL_CONSTRAINTS.SEARCH_CONDITION`) 歷史使用 LONG 存儲定義文本。12c+ 逐步遷移至 CLOB (如 `DBA_VIEWS.TEXT_VC` CLOB 版本),但為兼容性保留 LONG 列。
| 能力 | LONG | CLOB / NCLOB |
|---|---|---|
| 最大長度 | 2 GB | 4 GB ~ 128 TB (取決於塊大小) |
| 每表列數 | 1 | 無限制 |
| 索引支持 | 無 | Oracle Text (Context/CTXCAT/CTXRULE)、Function-based 索引、JSON 索引 (21c+) |
| 分區/聚簇 | 不支持 | 完全支持 |
| SQL 函數 | 無 | SUBSTR, INSTR, LENGTH, UPPER/LOWER, REPLACE, REGEXP_*, JSON_* 等全支持 |
| PL/SQL 變量 | 不支持 | 原生支持 `CLOB` 變量、DBMS_LOB 操作 |
| 分布式查詢 | 不支持 | 支持 (DBLink 讀寫) |
| 觸發器引用 | 不支持 | 支持 `:NEW.clob_col`, `:OLD.clob_col` |
| 存儲選項 | 行內/行外固定 | ENABLE STORAGE IN ROW / DISABLE STORAGE IN ROW、SECUREFILE / BASICFILE、壓縮/去重/加密 |
| 並行 DML | 不支持 | 支持 |
| 工具兼容性 | 極差 | 優秀 (JDBC/ODP.NET/ODBC/SQL*Plus/Data Pump/Expdp/Impdp/GoldenGate 完美支持) |
-- 1. 確認表結構
DESC old_table_with_long;
-- 2. 執行轉換 (僅元數據操作,數據不移動,極快)
ALTER TABLE old_table_with_long MODIFY (long_col CLOB);
-- 3. 驗證
DESC old_table_with_long; -- 長列類型變為 CLOB
SELECT long_col FROM old_table_with_long WHERE ROWNUM=1; -- 可正常 SELECT
-- 4. 後續可選:啟用 SecureFile、壓縮、去重
ALTER TABLE old_table_with_long MODIFY LOB (long_col) (COMPRESS HIGH DEDUPLICATE ENCRYPT USING 'AES256');
注意:轉換後原有限制解除,但**現有索引/約束/觸發器/視圖/PL/SQL 依賴可能失效**,需重新編譯/重建。
-- 1. 創建新表 (含 CLOB 列)
CREATE TABLE new_table AS
SELECT pk_col, other_cols, TO_LOB(long_col) AS clob_col
FROM old_table_with_long;
-- 2. 重建索引/約束/權限/觸發器/同義詞
-- 3. 切換表名 (RENAME + SYNONYM 或應用層切換)
RENAME old_table_with_long TO old_table_with_long_bak;
RENAME new_table TO old_table_with_long;
# 1. 導出 (含 LONG 表)
expdp system/pass directory=dp_dir dumpfile=long_tab.dmp logfile=exp.log tables=schema.old_table_with_long
# 2. 導入時自動轉換 (12c+ impdp 遇到 LONG 自動轉 CLOB)
# 或預先創建目標表含 CLOB 列,使用 TABLE_EXISTS_ACTION=TRUNCATE/REPLACE
impdp system/pass directory=dp_dir dumpfile=long_tab.dmp logfile=imp.log \
table_exists_action=REPLACE \
remap_table=schema.old_table_with_long:schema.new_table_clob \
transform=segment_attributes:n:table # 可選:去除存儲屬性
DECLARE
CURSOR c_long IS SELECT long_col FROM old_table WHERE pk = 1;
l_long_val LONG; -- 僅用於 FETCH 目標,不可操作
BEGIN
OPEN c_long;
FETCH c_long INTO l_long_val; -- 僅能 FETCH,不能 DBMS_OUTPUT/SUBSTR
CLOSE c_long;
END;
/
-- SQL*Plus 腳本
SET LONG 2000000000
SET LONGCHUNKSIZE 32767
SET LINESIZE 32767
SET PAGESIZE 0
SET TRIMSPOOL ON
SPOOL long_data.txt
SELECT long_col FROM old_table WHERE pk = 1;
SPOOL OFF
現代驅動程序將 LONG 視為流 (Stream/Blob/Clob) 處理,可繞過 SQL 層限制直接讀寫大對象。但**強烈建議先遷移至 CLOB**。