◀ 4.

Oracle 19cのカラム削除|DROP COLUMN・SET UNUSEDと依存・取消条件

▶

Oracle Database 19cで列を削除する際の案内です。アプリから列を使わなくすること、SET UNUSED、DROP COLUMNは別の操作です。後半のMySQL・PostgreSQL・SQL Server・SQLiteの比較は、対応する製品・版の条件として読んでください。

アプリでの非利用化とOracleのSET UNUSED・列削除は別。UNUSEDは通常のROLLBACKやSET USEDで戻せない
Oracle 19cの通常表での判断を整理した模式図です。瞬時・無停止・復旧成功を表す図ではありません。

表関連の一覧から目的を選べます。列追加はカラムの追加、型や属性の変更はカラムの定義変更、表全体の削除は表の削除を参照してください。

この記事の要点
  • テーブルから列(カラム)を削除するには ALTER TABLE 表名 DROP COLUMN 列名
  • Oracle 19cの単一列はDROP COLUMN 列名、複数列はDROP (列1, 列2)。MySQL/PostgreSQLの省略形と混ぜない
  • 制約・インデックス・外部キー・トリガーが参照している列はそのままでは削除できないことが多い
  • まずアプリでの非利用化と影響確認を行う。OracleのSET UNUSEDは通常のROLLBACKやSET USEDでは戻せないDDLで、可逆な待機段階ではない
  • INSTANTやONLINEは版・対象・操作の制限付き。metadata lock待ちを含むため、名前だけで瞬時・無停止とは判断しない

はじめに

テーブルの列(カラム)が不要になったとき、ALTER TABLE 文の DROP COLUMN 句で削除できます。シンプルに見えますが、外部キーやインデックス、トリガーから参照されていたり、巨大なテーブルだとロック・ダウンタイムの問題が出たりするため、実運用では注意点が多くあります。

基本構文

Oracle 19cの単一列の構文例で、表名/列名は置換する記号です。実行手順ではありません。列DROPは対象列だけでなく、既にUNUSEDにした同じ表の列も除去し得ます。依存と全対象を先に確認してください。

ALTER TABLE 表名 DROP COLUMN 列名;

基本例

保存した独立例です。employees.middle_nameの値と依存する索引/制約を失い、Oracle通常DDLのROLLBACKでは戻せません。既存UNUSED列も同時に除去される点を確認してください。

-- employees テーブルから middle_name 列を削除
ALTER TABLE employees DROP COLUMN middle_name;

DBMS 別の差

DBMS構文備考
OracleALTER TABLE 表 DROP COLUMN 列;DROP (col1, col2)で複数列。SET UNUSEDも列をアクセス不可にする取消不能なDDL。明示DROPは既存UNUSED列も同時に除去
MySQL / MariaDBALTER TABLE 表 DROP COLUMN 列; / ALTER TABLE 表 DROP 列;COLUMN省略可。MySQL 8.0のINSTANT列削除は8.0.29以降で、8.4にも対象制限がある。MariaDBの版/実装へ一律転用しない
PostgreSQLALTER TABLE 表 DROP COLUMN [IF EXISTS] 列 [RESTRICT | CASCADE];PostgreSQL 18のCASCADEは他表の参照制約やビュー等の依存も削除し得る。拒否されたら自動追加せず、失う保護と対象を確認
SQL ServerALTER TABLE 表 DROP COLUMN 列;列への制約/索引等に制限がある。必要な保護を外して削除を通すのではなく、依存を評価し削除中止も判断する
SQLite3.35.0 以降で ALTER TABLE 表 DROP COLUMN 列;DROP COLUMNは3.35.0で導入。主キー・UNIQUE・索引・式/trigger/view等の参照に制限がある。旧版の表再作成は依存・データ移行を伴う別作業

複数カラムを一度に削除

Oracle

Oracle 19cの複数列例を保持しています。列名の重複・対象制限・既存UNUSED列を確認してください。基本例の後へ連続実行する手順ではありません。

ALTER TABLE employees DROP (middle_name, nickname);

MySQL / PostgreSQL

MySQL/PostgreSQLの比較例を保持しています。OracleのDROP (列1, 列2)とは別構文です。製品の版・依存・transaction/ロック条件を確認し、他の例と一括実行しないでください。

ALTER TABLE employees
    DROP COLUMN middle_name,
    DROP COLUMN nickname;

SQL Server

SQL Server Database Engineの複数列比較例です。索引/制約等による制限があり、制約を解除してエラーを通す手順とはしません。実DBでは未実行です。

ALTER TABLE employees
    DROP COLUMN middle_name, nickname;

依存オブジェクトのチェック

Oracle 19cでは表の全列を削除することはできません。partitioning columnやドメイン索引がある列、索引構成表の主キー列等にも制限があります。CASCADE CONSTRAINTSを付ければあらゆる対象を削除できるという意味ではありません。通常表以外や圧縮形式ごとの条件も確認してください。

依存の扱いは製品と対象で異なります。Oracle 19cの列DROPでは対象列の索引・制約も失われ、他の列や表に関係する制約があるとCASCADE CONSTRAINTSなしでは拒否される場合があります。拒否は保護の確認点であり、CASCADEや制約解除を自動追加する合図ではありません。

依存挙動
NOT NULL / UNIQUE / CHECK 制約Oracleでは対象列に関係する制約も除去される。残す列も含むCHECK等は拒否/CASCADE CONSTRAINTSの条件を確認
主キー主キー列・参照FK・表の構成を確認。主キーを一律に先行解除しない。Oracleの索引構成表の主キー列はCASCADE CONSTRAINTSでもDROP不可
外部キー(自テーブル側)列と整合性保護の両方を失う可能性を確認。制約の先行解除を標準の対処にしない
外部キー(他テーブルから参照されている)参照している列・制約を調べ、削除しない選択も含めて計画。OracleのCASCADE CONSTRAINTSは参照制約の削除で、子表を安全に消す指定ではない
インデックスOracleは対象列に定義された索引も除去。関数/ドメイン索引等の対象制限と残るSQLの計画を確認する
ビュー・マテビューOracleの依存先の有効性と修正を確認。他製品は拒否/CASCADEによる削除等があり、全DB共通の無効化とはしない
トリガー・関数参照箇所・無効化/再コンパイル・実行時影響を確認。動的SQLやアプリの参照までDBの依存一覧だけで網羅できるとは限らない

論理削除 → 物理削除のステップ

この節の「論理削除」はまずアプリでの非利用化・運用上の記録として考えます。SET UNUSEDを可逆な論理削除と呼び替えないでください。次は確認の順序であり、固定の期間を待てば安全になる実行手順ではありません。

  1. アプリから書き込み停止: INSERT/UPDATE で当該列を使うコードを外す
  2. 読み取りも停止: SELECT * を含めて参照箇所を排除
  3. 論理削除フェーズ: アプリで使わない状態・所有者・残すデータを記録する。コメントだけではSQLの参照を止められない。OracleのSET UNUSEDは別途承認する不可逆DDLで、単なる記録と同じ段階に置かない
  4. 本番待機期間: 定期処理・別アプリ・過去の実行周期を含めて観察する。1〜2リリース待った事実だけでは非利用や復旧可能性を確定しない
  5. 物理削除: 対象・依存・既存UNUSED列・取消境界・復元方法と実行枠を確認して初めて判断する。Oracleでは列DROPと同時に既存UNUSED列も除去されるため、名指しした列だけの変更と思わない

大規模テーブルの注意

DBMSヒント
MySQL 8MySQL 8.0.29以降のInnoDBと8.4で対応条件を確認。INSTANT非対応の表/操作があり、metadata lock待ちもある。無条件の瞬時完了は保証しない
PostgreSQLPostgreSQL 18は列をSQLから不可視にし、既存行の更新等により領域が順次再利用される。直後のファイル縮小や通常VACUUMによる一括回収を保証しない。原則ACCESS EXCLUSIVEロックが必要で、全表rewriteは別の高負荷作業
OracleOracle 19cのSET UNUSEDは通常のROLLBACK不可。内部heap表では値を各行から直ちに除かないがアクセス不可になる。DROP UNUSED COLUMNSは表の全UNUSED列が対象。外部表ではSET UNUSEDがDROP COLUMNへ変換される
SQL ServerSQL Server Database EngineのALTER TABLEはSch-Mロックを取得する。競合transaction、対象の列型/表形態・ログや行変更を確認し、DROP自体が常に速いと保証しない

Oracle 特有: SET UNUSED

保存例の「論理削除(即時)」は可逆性や所要時間を保証する表現ではありません。Oracle 19cのSET UNUSEDは列をアクセス不可にし、通常のROLLBACK/SET USEDでは戻せません。続くDROP UNUSED COLUMNSはこの表の全UNUSED列を除去します。2文を安全な連続演習と扱わないでください。

-- 論理削除(即時、内部的には未使用フラグを立てる)
ALTER TABLE employees SET UNUSED (middle_name);

-- 後でまとめて物理削除
ALTER TABLE employees DROP UNUSED COLUMNS;

内部heap表のSET UNUSEDは列データの物理除去を後へ分けますが、列へのアクセスを失う時点はSET UNUSED時です。同じ名前の列を追加しても元の値が戻るわけではありません。ONLINEもDML許容の指定で、無待機や時間保証ではなく、DEFERRABLE制約がある列ではONLINE指定に制限があります。下の読取例でUNUSED件数を確認できても、元の列名・値の復元にはなりません。

削除前に列の状態を読み取る

次のOracle 19c向け例は、接続ユーザーが所有するEMPLOYEESの列一覧とUNUSED列の件数を読むだけです。通常の引用なし識別子を想定して大文字名で絞っています。別スキーマ・引用付きの名前・接続先が違うと結果も変わるため、所有者と実名を先に確認します。USER_TAB_COLUMNSは表だけでなくビュー等も対象とし、system-generated hidden columnsを除きます。これだけで対象が通常表か、全依存がないかを判定できません。

-- Oracle Database 19c: read-only examples for an unquoted EMPLOYEES name.
-- USER_* views describe objects owned by the current user, not every schema.
SELECT table_name, column_id, column_name, data_type, nullable
FROM user_tab_columns
WHERE table_name = 'EMPLOYEES'
ORDER BY column_id, column_name;

-- A table-level count, not the names or values of unused columns.
SELECT table_name, "COUNT" AS unused_columns
FROM user_unused_col_tabs
WHERE table_name = 'EMPLOYEES'
ORDER BY table_name;

USER_UNUSED_COL_TABSはUNUSED列を含む所有表の行と件数を示し、元の列名や値を復元するビューではありません。DATA_TYPEだけで長さ・精度・既定値等の全定義を取得した意味にもなりません。0件でも、対象名・接続ユーザーの取り違えや他の依存がないとは言えません。出力を根拠にそのままDROPせず、制約・索引・参照SQL・権限・既存UNUSED列を合わせて確認してください。この追加SQLは公式列定義との照合であり、Oracle実機では未実行です。

ロールバック性

取消可否は製品・対象・transactionをCOMMIT済みかで分けます。Oracle 19c通常DDLは構文上有効なDDLの実行前と成功後に暗黙COMMITがあり、DDLが失敗しても先行DMLが戻るとは限りません。SET UNUSED/列DROPを利用者のROLLBACKで戻せません。バックアップ取得だけでなく、対象の列・時点を復元する手段・権限・復元試験・所要時間を先に確認します。

DBMSDDL トランザクション
PostgreSQLPostgreSQL 18の通常表の列DROPは未COMMITのtransaction内ならROLLBACKで取消可能。COMMIT後の復元とは別
SQL ServerSQL Server Database Engineの対象とtransaction条件を確認。未COMMITでの取消と、COMMIT後にバックアップから戻す作業は別
MySQL(InnoDB)MySQL 8.4の通常ALTER TABLEは暗黙COMMIT。InnoDBのatomic DDLと利用者ROLLBACKを混同しない
OracleOracle 19cの通常DDLは実行前/成功後の暗黙COMMIT。SET UNUSEDも通常のROLLBACKでは戻せない

よくあるトラブル

症状原因 / 対処
外部キー違反で削除できない操作を止めて参照関係と保持すべき整合性を確認。先行DROPやCASCADEでエラーを通すのを自動対処にしない
「列が見つかりません」接続先・schema・実名・大文字小文字/引用を照合。PostgreSQLのIF EXISTSは不存在エラーの抑制であり、意図した対象を確認する診断の代わりではない
長時間ロック待機transaction・要求ロック・対象/版/操作を先に調査。INSTANT/SET UNUSEDへ変えるだけで待機を解消できるとは限らず、後者はアクセス不可になる不可逆DDL
アプリから 500 エラー削除前に SELECT * や INSERT で当該列を使っているコードを完全に排除
容量が減らないDB内で再利用する領域とOSへ返す空き容量を区別。OPTIMIZE TABLE/VACUUM FULL/ALTER TABLE ... MOVE等は書込み・再構築やロックを伴う別作業であり、容量表示だけを理由に自動実行しない

関連

  • 表関連 — 親カテゴリ
  • 表の作成 — CREATE TABLE
  • ALTER TABLE ADD COLUMN — 列追加
  • ALTER TABLE MODIFY / RENAME COLUMN — 列変更
  • DROP TABLE — テーブルごと削除

公式資料と確認範囲

確認対象はOracle Database 19cの列削除を中心とした構文・依存・取消境界です。保存した旧例は独立した教材として残しています。Oracle・PostgreSQL・SQL Serverの実機、利用者のDBやアプリの互換性、処理時間・ロック時間・復旧成功は実証していません。次のSQLite検証だけは合成表による限定的な実測です。

限定的な比較検証:2026-10-27、ローカルSQLite 3.49.1の新しいメモリ内合成表で、明示transaction内の列DROPをROLLBACKすると列と値が戻ること、COMMIT後のROLLBACKでは戻らないこと、索引・UNIQUE・trigger・viewが列を参照する4例ではDROPが拒否され元の定義と行が残ることを確認しました。6検体・45確認項目の結果はそのSQLiteと専用データに限り、Oracle・PostgreSQL・SQL Serverや保存した旧SQL、新Oracle読取例の実行証明ではありません。本番/既存DBには接続していません。

子ページ

子ページはありません

同階層のページ
  1. 表の作成
  2. カラムの追加
  3. カラムの定義変更
  4. カラムの削除
  5. 表の削除
  6. TRUNCATE文

最近更新/作成されたページ