Oracle 不允許直接修改含資料的 NOT NULL 欄位資料類型。本文提供標準的「臨時欄位遷移法」,透過新增暫存欄位、資料轉移、類型修改、資料回寫、清理暫存欄位五步驟,安全完成類型變更,保持欄位名稱不變、避免表遷移。
-- 1. 新增臨時欄位(目標類型)
ALTER TABLE tablename ADD filedname_temp VARCHAR2(20);
-- 2. 將原欄位資料搬移至暫存欄位,原欄位置 NULL
UPDATE tablename SET filedname_temp = filedname, filedname = NULL;
COMMIT;
-- 3. 修改原欄位類型(現為空,可直接修改)
ALTER TABLE tablename MODIFY filedname VARCHAR2(20);
-- 4. 資料回寫,暫存欄位置 NULL
UPDATE tablename SET filedname = filedname_temp, filedname_temp = NULL;
COMMIT;
-- 5. 刪除暫存欄位
ALTER TABLE tablename DROP COLUMN filedname_temp;
-- 6. 恢復 NOT NULL 約束
ALTER TABLE tablename MODIFY filedname NOT NULL;
-- 7. 驗證
SELECT * FROM tablename;
| 項目 | 說明 |
|---|---|
| 前置條件 | 需停機維護窗口(鎖表更新) |
| 資料量影響 | 雙重全表掃描更新,大表產生大量 Undo/Redo,耗時較長 |
| 優點 | 欄位名不變、無表遷移、索引/約束/視圖依賴自動維持 |
| 替代方案 | 線上重定義 (DBMS_REDEFINITION) 支援零停機,但操作複雜 |
| 類型轉換風險 | 確保資料符合新類型格式(如 NUMBER→VARCHAR2 需無非數值字元) |
-- 12c 支援隱式類型轉換的線上修改(視版本與類型組合而定)
ALTER TABLE tablename MODIFY filedname VARCHAR2(20); -- 若資料相容可能直接成功
但對於 NOT NULL 欄位,傳統臨時欄位法仍是最通用、最穩妥的做法。執行前請務必備份、驗證資料相容性、預估維護窗口時長。