「既存のテーブルに新しい列を追加したい」「テキスト型を数値型に変更したい」「不要なカラムを削除したい」。
データベースの運用や開発中、こうした要件は頻繁に発生します。Oracle Databaseでは、これらの操作に ALTER TABLE 文を使用します。
この記事では、Oracle SQL を使用した 列の追加、変更、削除の具体的な手順を解説します。特に、「データが入っている状態で型変更を行うとエラーになる」 という実務でよくある壁の乗り越え方を、実機で動くサンプル付きで詳しく紹介します。
💰 【PR】Oracleエンジニアの市場価値、調べてみませんか?
Oracleのスキルは需要が高く、特定の資格や経験を持っていると年収が大幅にアップするケースがあります。まずはIT専門のエージェントで非公開求人をチェックしてみませんか?
この記事で分かること
- 列の追加・変更・削除 の基本構文(
ALTER TABLE) - 【重要】データが入った列のデータ型を変更する安全な手順
- 実務で遭遇しやすいトラブル(ORAエラー)と対処法
- [FAQ] 列の並び順変更や、誤って削除した際の復旧について
結論:列操作のやることリスト(基本構文)
時間がない方向けに、基本構文をまとめました。
- 列の追加:ALTER TABLE 表名 ADD (列名 データ型 [DEFAULT 値] [制約]);
- 列の変更 (単純な桁数拡張など):ALTER TABLE 表名 MODIFY (列名 新しいデータ型 [DEFAULT 新しい値]);
- 列の変更 (データあり・型変更):MODIFY ではなく「新列追加 → データ移行 → 旧列削除」の手順が必要(後述)。
- 列の削除:ALTER TABLE 表名 DROP COLUMN 列名;
- 列名の変更 (リネーム):ALTER TABLE 表名 RENAME COLUMN 旧列名 TO 新列名;
注意:
ALTER TABLEは DDL(データ定義言語) です。実行すると即座にオートコミットされ、ROLLBACKで取り消すことはできません。
1. 背景と基礎:ALTER TABLE とは?
データベース設計書(DD)に変更があった場合、テーブル構造を変更する必要があります。Oracle Databaseでは、表(テーブル)の定義変更に ALTER TABLE 文を使用します。
初心者向け一口メモ
- 影響範囲: 列を追加しても既存データには影響しません(NULLが入るか、指定したデフォルト値が入ります)。
- ロック: DDL実行中、そのテーブルは一瞬(または処理終了まで)ロックされ、他のユーザーは変更できなくなります。業務時間中の実行は慎重に行う必要があります。
2. 実践:列の追加・変更・削除の手順
ここからは実際のSQLを用いて解説します。ご自身の検証環境で試すことができます。
前提:サンプル表の作成
まずは検証用の社員テーブル(employees)を作成します。
-- サンプル表の作成
CREATE TABLE employees (
emp_id NUMBER(5) CONSTRAINT pk_emp PRIMARY KEY,
emp_name VARCHAR2(100),
hire_date DATE,
note VARCHAR2(50) -- 後で型変更のテストに使用
);
-- テストデータの投入 (US形式の名前を使用)
INSERT INTO employees (emp_id, emp_name, hire_date, note)
VALUES (1001, 'John Doe', SYSDATE, '12345');
COMMIT;
SQL> CREATE TABLE employees (
2 emp_id NUMBER(5) CONSTRAINT pk_emp PRIMARY KEY,
3 emp_name VARCHAR2(100),
4 hire_date DATE,
5 note VARCHAR2(50)
6 );
Table created.
SQL> INSERT INTO employees (emp_id, emp_name, hire_date, note)
2 VALUES (1001, 'John Doe', SYSDATE, '12345');
1 row created.
SQL> COMMIT;
Commit complete.
SQL> SELECT * FROM employees;
EMP_ID EMP_NAME HIRE_DATE NOTE
---------- --------------- --------- --------------------
1001 John Doe 13-DEC-25 12345
手順1:列の追加 (ADD)
電話番号 (phone_number) 列を追加します。
-- 列の追加
ALTER TABLE employees ADD (phone_number VARCHAR2(15));
SQL> DESC employees
Name Null? Type
----------------------------------------- -------- ----------------------------
EMP_ID NOT NULL NUMBER(5)
EMP_NAME VARCHAR2(100)
HIRE_DATE DATE
NOTE VARCHAR2(50)
SQL> ALTER TABLE employees ADD (phone_number VARCHAR2(15));
Table altered.
SQL> DESC employees
Name Null? Type
----------------------------------------- -------- ----------------------------
EMP_ID NOT NULL NUMBER(5)
EMP_NAME VARCHAR2(100)
HIRE_DATE DATE
NOTE VARCHAR2(50)
PHONE_NUMBER VARCHAR2(15)
複数の列を一度に追加する場合は、カッコ内でカンマ区切りにします。
ALTER TABLE employees ADD (
email VARCHAR2(100),
department_id NUMBER(4)
);
SQL> ALTER TABLE employees ADD (
2 email VARCHAR2(100),
3 department_id NUMBER(4)
4 );
Table altered.
SQL> DESC employees
Name Null? Type
----------------------------------------- -------- ----------------------------
EMP_ID NOT NULL NUMBER(5)
EMP_NAME VARCHAR2(100)
HIRE_DATE DATE
NOTE VARCHAR2(50)
PHONE_NUMBER VARCHAR2(15)
EMAIL VARCHAR2(100)
DEPARTMENT_ID NUMBER(4)
手順2:列の変更 (MODIFY) とエラー対処
列の定義変更には2つのパターンがあります。「スムーズにいく場合」と「エラーになる場合」です。
ケースA:スムーズにいく場合(桁数の拡張)
社員名 (emp_name) の桁数を 100バイト から 200バイト に拡張します。これはデータが入っていても問題ありません。
-- 列の桁数拡張
ALTER TABLE employees MODIFY (emp_name VARCHAR2(200));
SQL> SELECT emp_id,emp_name,hire_date,note FROM employees;
EMP_ID EMP_NAME HIRE_DATE NOTE
---------- --------------- --------- --------------------
1001 John Doe 13-DEC-25 12345
SQL> ALTER TABLE employees MODIFY (emp_name VARCHAR2(200));
Table altered.
SQL> DESC employees
Name Null? Type
----------------------------------------- -------- ----------------------------
EMP_ID NOT NULL NUMBER(5)
EMP_NAME VARCHAR2(200) ★
HIRE_DATE DATE
NOTE VARCHAR2(50)
PHONE_NUMBER VARCHAR2(15)
EMAIL VARCHAR2(100)
DEPARTMENT_ID NUMBER(4)
💰 【PR】Oracleエンジニアの市場価値、調べてみませんか?
Oracleのスキルは需要が高く、特定の資格や経験を持っていると年収が大幅にアップするケースがあります。まずはIT専門のエージェントで非公開求人をチェックしてみませんか?
ケースB:エラーになる場合(データ型の変更)
note 列(現在は VARCHAR2)を NUMBER 型に変更しようとするとどうなるでしょうか?
既にデータ(’12345’)が入っている場合、Oracleはデータの整合性を保証できないため、エラーを返します。
-- 失敗例:データが入っている列の型変更
ALTER TABLE employees MODIFY (note NUMBER(10));
-- 結果: ORA-01439: column to be modified must be empty to change datatype
SQL> DESC employees
Name Null? Type
----------------------------------------- -------- ----------------------------
EMP_ID NOT NULL NUMBER(5)
EMP_NAME VARCHAR2(200) ★
HIRE_DATE DATE
NOTE VARCHAR2(50)
PHONE_NUMBER VARCHAR2(15)
EMAIL VARCHAR2(100)
DEPARTMENT_ID NUMBER(4)
SQL> SELECT emp_id,emp_name,hire_date,note FROM employees;
EMP_ID EMP_NAME HIRE_DATE NOTE
---------- --------------- --------- --------------------
1001 John Doe 13-DEC-25 12345 ★
SQL> ALTER TABLE employees MODIFY (note NUMBER(10));
ALTER TABLE employees MODIFY (note NUMBER(10))
*
ERROR at line 1:
ORA-01439: column to be modified must be empty to change datatype
解説: ORA-01439 は「データ型を変更するには列が空(NULL)である必要があります」という意味です。Oracleは自動的に ‘12345’ という文字を数値に変換してくれません。
【解決策】データ型を変更する正しい手順
データが入っている列の型を変更するには、以下の4ステップを実行します。
- 新しい列 を希望するデータ型で追加する。
- 既存データを変換しながら新しい列へ コピー(UPDATE) する。
- 古い列 を削除する。
- 新しい列を 元の名前に変更 する。
-- 1. 新しい列(一時的な名前)を数値型で追加
ALTER TABLE employees ADD (note_new NUMBER(10));
-- 2. データを変換してコピー(文字から数値へ変換)
UPDATE employees SET note_new = TO_NUMBER(note);
COMMIT; -- データ量が多い場合は適宜コミット
-- 3. 旧列を削除
ALTER TABLE employees DROP COLUMN note;
-- 4. 新列を元の名前にリネーム
ALTER TABLE employees RENAME COLUMN note_new TO note;
これで、データの中身を維持したまま、データ型を VARCHAR2 から NUMBER へ変更できました。
手順3:列の削除 (DROP COLUMN)
不要になった列を削除します。
-- 列の削除
ALTER TABLE employees DROP COLUMN phone_number;
リスク: 列削除は物理的にデータを消去するため、元に戻せません。大規模テーブルでの列削除はシステム負荷が高いため、後述の
SET UNUSEDを検討してください。
3. トラブルシューティング(よくあるエラー)
列操作時によく遭遇するエラーとその対処法です。
| エラーコード | エラーメッセージ | 原因 | 対処法 |
| ORA-01439 | データ型を変更するには列が空である必要があります | データが存在する状態で型変更(文字⇔数値など)を行った。 | 上記「手順2 ケースB」の通り、新列追加→移行→旧列削除の手順を行う。 |
| ORA-01441 | 一部の値にとって列の長さが短すぎます | 桁数を縮小しようとしたが、既存データが長すぎる。 | データの最大長を確認してサイズを決めるか、データを短くUPDATEしてから縮小する。 |
| ORA-00054 | リソース・ビジー、NOWAITが指定… | 他のセッションが表をロック中(更新中など)。 | そのセッションの終了を待つか、メンテナンス時間に実行する。 |
4. 運用・監視・セキュリティ上の注意
本番環境での注意点
- バックアップ: 作業前に必ずバックアップ(Export/Data Pump)を取得してください。特に列削除や型変更はリスクが高い操作です。
- 実行タイミング: DDLは排他ロックを取得するため、アクセスが少ない時間帯に実施してください。
- 無効化されたオブジェクト: 表構造を変えると、その表を参照しているビューやPL/SQLパッケージが「INVALID(無効)」状態になることがあります。作業後に再コンパイルが必要です。
5. FAQ:よくある質問
Q1. 列を追加するとき、列の並び順(位置)を指定できますか?
A. 基本的にできません。
Oracle Databaseでは、新しく追加した列は必ず最後尾に追加されます。「2番目の列として追加したい」といった場合、テーブルを作り直す(CREATE TABLE AS SELECT …)必要があります。
Q2. 複数の列を一度に削除できますか?
A. はい、可能です。
ALTER TABLE employees DROP (email, department_id);
と記述することで、複数の列をまとめて削除できます。
Q3. 列の削除に時間がかかりすぎます。速くする方法は?
A. SET UNUSED を検討してください。
数億行あるテーブルの列削除は非常に重い処理です。まずは論理的に列を使用不可にし、後で物理削除を行う方法が推奨されます。
-- 即座にアクセス不可にする(データは残るが、SELECT等からは見えなくなる)
ALTER TABLE employees SET UNUSED (phone_number);
-- メンテナンス時間などに物理削除を実行
ALTER TABLE employees DROP UNUSED COLUMNS CHECKPOINT 1000;
6. まとめ
Oracleデータベースにおける表の列操作のポイントは以下の通りです。
- 追加 (
ADD): 列は表の最後に追加される。 - 変更 (
MODIFY):- 桁数拡張は簡単。
- 型変更や桁数縮小 は、データが入っているとエラー(ORA-01439/ORA-01441)になる。この場合、「新列作成・移行・旧列削除」 の手順で対応する。
- 削除 (
DROP): データが永久に失われるため、事前のバックアップが必須。 - トランザクション: DDLは即時コミットされるため、ロールバック不可。
まずは開発環境で ORA-01439 エラーを実際に体験し、回避手順を練習しておくことを強くお勧めします。
本記事は Oracle Database 19c を対象に解説します(他バージョンは画面や既定値が異なる場合があります)。
[参考]
Oracle Database SQL言語リファレンス 19c
💰 【PR】Oracleエンジニアの市場価値、調べてみませんか?
Oracleのスキルは需要が高く、特定の資格や経験を持っていると年収が大幅にアップするケースがあります。まずはIT専門のエージェントで非公開求人をチェックしてみませんか?



コメント