【SQL】UPDATE文でNULLに更新する方法完全ガイド|NOT NULL制約・CASE文・サブクエリ・UPDATE JOIN・RDBMS別構文・実務パターンまで

【SQL】UPDATE文でNULLに更新する方法(SET NULL構文と注意点) SQL
OracleでテーブルをLIKE検索し、一致するテーブルに対してDROP TABLE文を一括生成する方法を解説。USER_TABLES検索、文字列連結、PL/SQLでの動的実行、安全な運用パターンまで網羅。

SQLで特定のカラムを NULL に更新するには、UPDATE テーブル名 SET カラム名 = NULL を使います。

この記事では、基本構文から、NOT NULL制約でエラーになるケースの対処CASE文での条件付きNULL更新UPDATE JOINによる参照更新RDBMS別(Oracle/MySQL/PostgreSQL/SQL Server)の注意点まで、実務で使えるパターンを網羅します。

この記事でわかること
UPDATE SET カラム = NULL の基本構文
・複数カラムを一括でNULLに更新する方法
・NOT NULL制約エラー(ORA-01407・ERROR 1048等)の原因と対処法
・CASE文で条件付きにNULLに更新する方法
・UPDATE JOINで別テーブルの条件を参照してNULLに更新する方法
・RDBMS別(Oracle・MySQL・PostgreSQL・SQL Server)の注意点
・個人情報削除・テストデータリセット等の実務パターン
スポンサーリンク

UPDATE文でNULLに更新する基本構文

カラムの値を NULL(値なし)にするには、SET カラム名 = NULL と記述します。

UPDATE テーブル名
SET カラム名 = NULL
WHERE 条件;

実行例

-- 更新前の確認
SELECT id, name, email FROM users WHERE id = 1;
-- id | name | email
-- 1  | 田中 | tanaka@example.com

-- NULLに更新
UPDATE users
SET email = NULL
WHERE id = 1;

-- 更新後の確認
SELECT id, name, email FROM users WHERE id = 1;
-- id | name | email
-- 1  | 田中 | NULL
‘NULL’(文字列)と NULL(値なし)は全くの別物
SET email = NULL は「値なし」に更新します。
SET email = 'NULL' は「NULLという4文字の文字列」に更新します。
クォーテーションで囲まないのが正しい書き方です。

複数カラムを同時にNULLに更新する

カンマ区切りで複数のカラムをまとめて NULL にできます。1回の UPDATE 文で処理できるため、複数回に分けるよりも効率的です。

UPDATE users
SET email = NULL,
    phone = NULL,
    address = NULL
WHERE id = 1;

WHERE句なしのUPDATEは全行更新になるので注意

WHERE 句を省略すると、テーブル内の全行が更新されます。本番環境で誤実行すると取り返しがつきません。

-- ⚠ 全行の email が NULL になる!
UPDATE users
SET email = NULL;
安全な実行手順
1. まず SELECT で対象行数を確認する
2. WHERE 句を必ず付ける
3. トランザクション内で実行し、確認してからCOMMITする
-- 安全な手順(トランザクション使用)
BEGIN;

-- ① 対象を確認
SELECT id, email FROM users WHERE id = 1;

-- ② 更新を実行
UPDATE users SET email = NULL WHERE id = 1;

-- ③ 結果を確認してからコミット
SELECT id, email FROM users WHERE id = 1;
COMMIT;  -- 問題なければ確定
-- ROLLBACK; -- 問題があれば取り消し

NULLに更新できないケース:NOT NULL制約エラー

カラムに NOT NULL 制約が設定されている場合、NULLへの更新はエラーになります。

-- NOT NULL制約があるカラムへの更新
UPDATE users
SET name = NULL
WHERE id = 1;

RDBMS別のエラーメッセージ

RDBMS エラーメッセージ エラーコード
Oracle ORA-01407: cannot update ("SCHEMA"."TABLE"."COLUMN") to NULL ORA-01407
MySQL ERROR 1048 (23000): Column 'column' cannot be null 1048
PostgreSQL ERROR: null value in column "column" violates not-null constraint 23502
SQL Server Cannot insert the value NULL into column 'column' 515

NOT NULL制約を確認する方法

-- MySQL
DESC テーブル名;

-- Oracle
SELECT column_name, nullable
FROM user_tab_columns
WHERE table_name = 'テーブル名';

-- PostgreSQL
SELECT column_name, is_nullable
FROM information_schema.columns
WHERE table_name = 'テーブル名';

-- SQL Server
SELECT COLUMN_NAME, IS_NULLABLE
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'テーブル名';

NOT NULL制約を一時的に外す(ALTER TABLE)

-- MySQL
ALTER TABLE users MODIFY COLUMN email VARCHAR(255) NULL;

-- PostgreSQL
ALTER TABLE users ALTER COLUMN email DROP NOT NULL;

-- Oracle
ALTER TABLE users MODIFY (email NULL);

-- SQL Server
ALTER TABLE users ALTER COLUMN email VARCHAR(255) NULL;
本番DBでのALTER TABLEは慎重に
NOT NULL制約はデータ整合性を守るために存在します。外す前に「本当にNULLを許容してよいか」を設計レベルで確認してください。テスト環境で動作を確認してから本番に適用しましょう。

条件付きでNULLに更新する(CASE文)

特定の条件に一致する行だけ NULL にし、それ以外はそのままにしたい場合は CASE 文を使います。

-- ステータスが「退会」の場合だけ email を NULL にする
UPDATE users
SET email = CASE
    WHEN status = '退会' THEN NULL
    ELSE email
END;

複数カラム・複数条件での振り分け

-- 部署異動データの整理
UPDATE employees
SET department = CASE
        WHEN resignation_date IS NOT NULL THEN NULL
        WHEN transfer_date IS NOT NULL    THEN '異動先未定'
        ELSE department
    END,
    manager_id = CASE
        WHEN resignation_date IS NOT NULL THEN NULL
        ELSE manager_id
    END;
CASE文を使ったUPDATEの詳細は【SQL】CASE文を使用した複数条件でのデータ更新方法を参照。

UPDATE JOINで別テーブルの条件を参照してNULLに更新する

別テーブルの情報を参照してNULLに更新するパターンです。RDBMS によって構文が異なります。

MySQL / MariaDB

-- 退会テーブルに存在するユーザーの個人情報をNULLに
UPDATE users u
JOIN withdrawals w ON u.id = w.user_id
SET u.email   = NULL,
    u.phone   = NULL,
    u.address = NULL
WHERE w.withdrawal_date IS NOT NULL;

PostgreSQL

-- PostgreSQLはFROM句を使う
UPDATE users u
SET email   = NULL,
    phone   = NULL,
    address = NULL
FROM withdrawals w
WHERE u.id = w.user_id
  AND w.withdrawal_date IS NOT NULL;

Oracle / SQL Server

-- Oracle / SQL Server はサブクエリを使う
UPDATE users
SET email   = NULL,
    phone   = NULL,
    address = NULL
WHERE id IN (
    SELECT user_id
    FROM withdrawals
    WHERE withdrawal_date IS NOT NULL
);
サブクエリを使ったUPDATEの詳細は【SQL】副問合せを使用して取得した値で更新する方法を参照。

NULLと空文字(”)の違い

NULL と空文字('')はまったく別の値です。混同するとバグの原因になります。

NULL 空文字(”)
意味 値が存在しない(未設定) 長さ0の文字列(値はある)
判定方法 IS NULL = ''
= NULL で判定 不可(常にFALSE)
LENGTH() NULL 0
COALESCE(値, ‘代替’) ‘代替’ が返る 空文字がそのまま返る
Oracle の空文字 NULLとして扱う NULLとして格納される(Oracle特有)
-- NULLに更新(値なし)
UPDATE users SET email = NULL WHERE id = 1;

-- 空文字に更新(空の文字列)
UPDATE users SET email = '' WHERE id = 1;

-- 確認: NULLはIS NULLで検索、空文字は = ''で検索
SELECT * FROM users WHERE email IS NULL;    -- NULL行
SELECT * FROM users WHERE email = '';       -- 空文字行
Oracleのみ空文字=NULLの特例あり
Oracleでは ''(空文字)を挿入・更新すると NULL として格納されます。MySQL・PostgreSQL・SQL Serverでは空文字とNULLは区別されます。Oracleから他DBへ移行する際はこの差異に注意してください。

NULLに更新した値の確認方法

NULL の検索には = NULL ではなく IS NULL を使います。NULL は「不明な値」であり =(等価比較)が成立しないためです。

-- NG: = NULL では検索できない(結果は常に0件)
SELECT * FROM users WHERE email = NULL;

-- OK: IS NULL を使う
SELECT * FROM users WHERE email IS NULL;

-- NULLではないことを確認
SELECT * FROM users WHERE email IS NOT NULL;

NULL伝搬:NULLを含む計算・文字列結合の注意点

カラムをNULLに更新した後、そのカラムを使った計算や文字列結合が NULL になる(NULL伝搬)ことに注意が必要です。

-- 例: price か discount がNULLだと final_price もNULLになる
UPDATE orders
SET final_price = price * (1 - discount)
WHERE id = 1;
-- price = 1000, discount = NULL の場合
-- 1000 * (1 - NULL) = NULL

-- 対策: COALESCE でNULLを0に置換
UPDATE orders
SET final_price = price * (1 - COALESCE(discount, 0))
WHERE id = 1;
-- 文字列結合でもNULL伝搬
-- first_name = 'John', last_name = NULL の場合
-- first_name || ' ' || last_name = NULL(NULLが伝搬)

-- 対策: COALESCE で空文字に変換
SELECT COALESCE(first_name, '') || ' ' || COALESCE(last_name, '') AS full_name
FROM users;

NULLの代わりにデフォルト値に戻す

NULL ではなく、カラムに設定されたデフォルト値に戻したい場合は DEFAULT キーワードを使います(全RDBMS対応)。

-- デフォルト値に戻す
UPDATE users
SET status = DEFAULT
WHERE id = 1;
デフォルト値が設定されていないカラムに DEFAULT を使うとエラーになるRDBMSがあります(MySQL等)。事前にテーブル定義を確認してください。

RDBMS別:UPDATE SET NULL の注意点まとめ

RDBMS NOT NULL制約エラー 空文字とNULL UPDATE JOIN構文 MERGE文対応
Oracle ORA-01407 同じ(空文字→NULL格納) サブクエリ方式 あり
MySQL ERROR 1048 区別あり JOIN 直接指定可 なし(代替あり)
PostgreSQL エラーコード 23502 区別あり FROM 句方式 あり
SQL Server エラーコード 515 区別あり FROM JOIN 方式 あり(MERGE)

実務での活用パターン

個人情報の削除(退会処理・GDPR対応)

-- 退会ユーザーの個人情報をNULLに(論理削除の一種)
UPDATE users
SET email      = NULL,
    phone      = NULL,
    address    = NULL,
    birth_date = NULL
WHERE status = '退会'
  AND deleted_at IS NOT NULL;

テストデータのリセット

-- テスト環境のフラグ・日付をリセット
UPDATE orders
SET shipped_date    = NULL,
    tracking_number = NULL,
    completed_at    = NULL
WHERE order_date >= '2026-01-01';

マスタ変更時の関連データクリア

-- 廃止された部署コードをNULLにする
UPDATE employees
SET department_id = NULL
WHERE department_id IN (
    SELECT id FROM departments WHERE is_active = 0
);

期限切れデータのクリア

-- 有効期限が切れたトークンをNULLに
UPDATE user_sessions
SET token      = NULL,
    expires_at = NULL
WHERE expires_at < NOW();

大量データを分割してNULLに更新(タイムアウト対策)

-- 一度に全件更新するとロック・タイムアウトが発生する場合
-- MySQL: LIMIT で分割更新
UPDATE users
SET email = NULL
WHERE status = '退会'
LIMIT 1000;
-- → これを完了するまで繰り返す

-- Oracle: ROWNUMで分割
UPDATE users
SET email = NULL
WHERE status = '退会'
  AND ROWNUM <= 1000;

よくあるトラブルと解決法

ケース1:NULLに更新したのにIS NULLで検索できない

-- 原因: OracleでVARCHAR2カラムに空文字を入れると NULLに変換される
-- しかし、NULLの見え方が環境によって違う場合も

-- 確認: 実際の値を確認する
SELECT id, email, LENGTH(email), email IS NULL AS is_null_flag
FROM users
WHERE id = 1;

ケース2:UPDATEは成功したが件数が0件

-- 原因: WHERE条件に一致する行がない
-- 確認: SELECT で件数を先に確認する
SELECT COUNT(*) FROM users WHERE id = 999;
-- 0件 → UPDATE してもROWCOUNT=0

-- MySQL: ROW_COUNT() で確認
SELECT ROW_COUNT();

-- Oracle: SQL%ROWCOUNT (PL/SQL) で確認

ケース3:ORA-01407 エラーが出る

-- ORA-01407: cannot update to NULL
-- 原因: NOT NULL制約があるカラムへの更新

-- NOT NULL制約を確認
SELECT column_name, nullable, data_type
FROM user_tab_columns
WHERE table_name = 'USERS'
  AND column_name = 'NAME';
-- NULLABLE = N → NOT NULL制約あり

-- 制約を外す(本当に必要な場合のみ)
ALTER TABLE users MODIFY (name NULL);

ケース4:WHERE条件にNULLが含まれていて期待通りに動かない

-- NG: NULLとの比較に = を使う(常にFALSE)
UPDATE users SET status = 'active' WHERE email = NULL;

-- OK: IS NULL を使う
UPDATE users SET status = 'active' WHERE email IS NULL;

ケース5:MySQLで strict mode のエラー

-- MySQL の sql_mode が STRICT_ALL_TABLES の場合
-- NOT NULL カラムへのNULL更新がエラーになる
SHOW VARIABLES LIKE 'sql_mode';

-- 一時的に無効化(非推奨・テスト目的のみ)
SET SESSION sql_mode = '';

よくある質問

UPDATE SET NULL は WHERE なしでも動きますか?
動きます。ただし WHERE を省略するとテーブルの全行が更新されます。意図せず全行をNULLにしてしまう事故が起きやすいため、必ずトランザクション内で実行し、SELECT で件数を確認してから実行しましょう。
Oracle で空文字 ” を UPDATE したら NULL になってしまった
Oracle の仕様です。Oracle ではVARCHAR2型に空文字を格納するとNULLとして扱われます。MySQL・PostgreSQL・SQL Serverでは空文字とNULLは区別されます。Oracle以外のDBへ移行する際や複数DBに接続するアプリでは注意が必要です。
NULLに更新した後に元の値に戻せますか?
COMMITする前であれば ROLLBACK で戻せます。COMMITした後は、バックアップや別テーブルへの履歴保存がない限り元の値には戻せません。重要なデータの更新はトランザクションを使い、バックアップを事前に取ることを推奨します。
NULL と 0 はどちらを使うべきですか?
意味が異なります。NULL は「値が存在しない・未入力・不明」、0 は「値が確定していてゼロ」です。例:売上金額が0円(確定)なら0、売上がまだない・未集計なら NULL が適切です。設計段階でどちらを使うか統一しておくことが重要です。
大量データをNULLに更新するとタイムアウト・ロックが発生する
一度に全件更新するとテーブルロックが長時間発生します。LIMIT(MySQL)や ROWNUM(Oracle)を使って1,000〜10,000件ずつに分割してコミットするか、メンテナンス時間帯に実行することを推奨します。

まとめ

やりたいこと SQL 注意点
1カラムをNULLに UPDATE t SET col = NULL WHERE 条件 WHERE必須
複数カラムを一括NULL UPDATE t SET c1 = NULL, c2 = NULL WHERE 条件 1回のUPDATEで可
条件付きでNULLに UPDATE t SET col = CASE WHEN ... THEN NULL ELSE col END CASE文を使う
別テーブル参照でNULL MySQL: JOIN / PG: FROM / Oracle: サブクエリ RDBMS別に構文が違う
NULLになったか確認 SELECT * FROM t WHERE col IS NULL = NULLは不可
デフォルト値に戻す UPDATE t SET col = DEFAULT WHERE 条件 DEFAULT未設定はエラー
ポイントまとめ
WHERE 句を忘れると全行が更新される → 必ずトランザクション内で実行
NOT NULL 制約があるカラムは更新できない(ALTER TABLE で解除可)
NULL と空文字 '' は別物(Oracleは例外)
・NULLの検索は = NULL ではなく IS NULL を使う
・NULLを含む計算・文字列結合は結果がNULLになる(NULL伝搬)に注意

あわせて読みたい