Oracle SQL 列の追加・変更・削除|ALTER TABLE完全ガイド

Oracle Master Silver

「既存のテーブルに新しい列を追加したい」「テキスト型を数値型に変更したい」「不要なカラムを削除したい」。

データベースの運用や開発中、こうした要件は頻繁に発生します。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 TABLEDDL(データ定義言語) です。実行すると即座にオートコミットされ、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ステップを実行します。

  1. 新しい列 を希望するデータ型で追加する。
  2. 既存データを変換しながら新しい列へ コピー(UPDATE) する。
  3. 古い列 を削除する。
  4. 新しい列を 元の名前に変更 する。
-- 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. 運用・監視・セキュリティ上の注意

本番環境での注意点

  1. バックアップ: 作業前に必ずバックアップ(Export/Data Pump)を取得してください。特に列削除や型変更はリスクが高い操作です。
  2. 実行タイミング: DDLは排他ロックを取得するため、アクセスが少ない時間帯に実施してください。
  3. 無効化されたオブジェクト: 表構造を変えると、その表を参照しているビューや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データベースにおける表の列操作のポイントは以下の通りです。

  1. 追加 (ADD): 列は表の最後に追加される。
  2. 変更 (MODIFY):
    • 桁数拡張は簡単。
    • 型変更や桁数縮小 は、データが入っているとエラー(ORA-01439/ORA-01441)になる。この場合、「新列作成・移行・旧列削除」 の手順で対応する。
  3. 削除 (DROP): データが永久に失われるため、事前のバックアップが必須。
  4. トランザクション: DDLは即時コミットされるため、ロールバック不可。

まずは開発環境で ORA-01439 エラーを実際に体験し、回避手順を練習しておくことを強くお勧めします。


本記事は Oracle Database 19c を対象に解説します(他バージョンは画面や既定値が異なる場合があります)。


[参考]
Oracle Database SQL言語リファレンス 19c

💰 【PR】Oracleエンジニアの市場価値、調べてみませんか?

Oracleのスキルは需要が高く、特定の資格や経験を持っていると年収が大幅にアップするケースがあります。まずはIT専門のエージェントで非公開求人をチェックしてみませんか?

コメント

タイトルとURLをコピーしました