【Oracle】ORA-00936の原因と解決方法|missing expression・SELECT/WHERE/INSERTの構文ミスを直す

【Oracle】ORA-00936の原因と解決方法|missing expression・SELECT/WHERE/INSERTの構文ミスを直す Oracle

ORA-00936: missing expression は、SQL文の中で本来必要な式、列名、値、条件、関数引数などが抜けているときに発生するOracleエラーです。日本語環境では「式がありません」と表示されます。

よくある原因は、SELECT FROM のようにSELECT項目がない、WHERE column = のように右辺がない、余分なカンマで式が空になっている、UPDATESET 句で値が抜けている、関数の引数が足りない、CASE 式が途中で終わっている、GROUP BYHAVING の条件が不足している、動的SQLの組み立てに失敗している、といったパターンです。

先に結論
ORA-00936は「SQLのどこかで必要な部品が抜けている」エラーです。まずエラー位置の直前を見て、SELECT句、WHERE条件、カンマ、括弧、関数引数、CASE式、INSERTの列と値を確認します。ORA-00933が「句の終わり方・順序」のエラーになりやすいのに対し、ORA-00936は「式そのものの不足」が中心です。
スポンサーリンク

ORA-00936とは

Oracle公式のエラー説明では、ORA-00936は句や式の必要な部分が省略された場合に発生するとされています。たとえば、SELECT文に列や式の一覧がない場合、または式が途中で終わっている場合です。予約語を式のように誤用した場合にも発生することがあります。

見る場所 よくあるNG 修正方針
SELECT句 SELECT FROM employees 取得する列や式を書く
WHERE句 WHERE employee_id = 比較する値、サブクエリ、条件式を書く
カンマ SELECT employee_id, FROM employees 余分なカンマを消す
関数 NVL(salary) 必要な引数をそろえる
UPDATE句 SET status = 代入する値や式を書く
CASE式 CASE WHEN ... THEN ... END まで書く
GROUP BY / HAVING HAVING COUNT(*) > 集計列、条件の右辺、比較値を書く
動的SQL WHERE AND status = 'A' 空条件を連結しない

ORA-00933との違い

ORA-00933ORA-00936 はどちらもSQL構文エラーですが、見るポイントが少し違います。ORA-00933はSQL文の終わり方、句の順序、Oracleで使えない構文が原因になりやすいです。ORA-00936は、式が入るべき場所に何もない、または途中で途切れている場合に出やすいです。

エラー 主な原因
ORA-00933 句の順序、末尾、他DB構文 LIMITUPDATE JOIN、不適切な ORDER BY
ORA-00936 列、値、条件、引数など式の不足 SELECT FROMWHERE id =、余分なカンマ

句の終わり方が怪しい場合は ORA-00933の原因と解決方法 も確認してください。

ORA-00907との違い

ORA-00907: missing right parenthesis は、括弧の閉じ忘れや括弧の位置が主な原因です。一方、ORA-00936 は、括弧の中や前後に入るべき式そのものが抜けている場合に出やすいです。

エラー 主な見方
ORA-00936 式・値・条件が抜けていないか WHERE employee_id =
ORA-00907 括弧が閉じているか、括弧の位置が正しいか NVL(salary, 0

SELECT句で式が抜けている

もっとも分かりやすい例は、SELECT句に列名や式を書いていないケースです。SELECTFROM の間には、取得したい列、リテラル、関数、計算式などが必要です。

select-missing-expression.sql
-- NG: SELECT句に取得する列や式がない
SELECT
FROM employees;

-- OK: 取得する列を書く
SELECT employee_id, employee_name
FROM employees;

-- OK: 全列を取得するなら*を書く
SELECT *
FROM employees;

SELECT句の余分なカンマ

SELECT句の最後に余分なカンマがあると、Oracleはカンマの後に次の式があるはずだと解釈します。しかし次が FROM だと、式が足りないためORA-00936になります。

select-extra-comma.sql
-- NG: FROMの直前に余分なカンマがある
SELECT
    employee_id,
    employee_name,
FROM employees;

-- OK: 最後のカンマを消す
SELECT
    employee_id,
    employee_name
FROM employees;

* と他の列を一緒に書く場合

* と別の式を組み合わせるとき、書き方によってはORA-00936になることがあります。テーブル別名を付けて e.* のように書くと意図が明確です。

star-with-extra-column.sql
-- NGになりやすい書き方
SELECT 'EMP' AS source_name, *
FROM employees;

-- OK: *にテーブル別名を付ける
SELECT 'EMP' AS source_name, e.*
FROM employees e;

WHERE条件の右辺がない

WHERE 句では、列名だけでなく条件式が必要です。=>INLIKE などを書いたあとに値やサブクエリがないと、式が不足します。

where-missing-right-side.sql
-- NG: = の右辺がない
SELECT *
FROM employees
WHERE employee_id =;

-- OK: 比較する値を書く
SELECT *
FROM employees
WHERE employee_id = 1001;

-- OK: サブクエリで比較する
SELECT *
FROM employees
WHERE department_id IN (
    SELECT department_id
    FROM departments
);

IN 句の使い方は OracleのIN句記事 でも整理しています。空の IN () をアプリ側で作ってしまうと構文エラーになるため、候補値が0件のときは別処理に分けます。

関数の引数が足りない

関数に必要な引数が不足している場合も、式が足りない状態になります。特に NVLSUBSTRDECODETO_DATE などは引数の数と区切りカンマを確認します。

function-arguments.sql
-- NG: NVLは第2引数が必要
SELECT NVL(commission_pct)
FROM employees;

-- OK: NULL時の値を指定する
SELECT NVL(commission_pct, 0)
FROM employees;

-- NG: SUBSTRの引数が途中で途切れている
SELECT SUBSTR(employee_name, )
FROM employees;

-- OK: 開始位置を指定する
SELECT SUBSTR(employee_name, 1, 3)
FROM employees;

INSERTの列と値の書き方ミス

INSERTでは、列リストや VALUES の中に空の式ができるとORA-00936になります。列数と値の数だけでなく、余分なカンマ、空の値、サブクエリ内のカンマも確認します。

insert-missing-expression.sql
-- NG: VALUESの中に空の式がある
INSERT INTO employees (employee_id, employee_name, department_id)
VALUES (1001, 'Sato', );

-- OK: 値を入れる。NULLにしたい場合も明示する
INSERT INTO employees (employee_id, employee_name, department_id)
VALUES (1001, 'Sato', NULL);

-- NG: サブクエリのSELECT句に余分なカンマがある
INSERT INTO employees_archive (employee_id, employee_name)
SELECT employee_id, employee_name,
FROM employees;

INSERT、UPDATE、DELETEの基本は OracleのDML完全ガイド も参考になります。

UPDATEのSET句で値が抜けている

UPDATE文では、SET 列 = 値 の形で代入する式が必要です。= の右側が空になっていたり、複数列更新のカンマの後に式がなかったりすると、ORA-00936の原因になります。

update-set-missing-expression.sql
-- NG: SET句の右辺がない
UPDATE employees
SET status =
WHERE employee_id = 1001;

-- OK: 代入する値を書く
UPDATE employees
SET status = 'ACTIVE'
WHERE employee_id = 1001;

-- NG: 複数列更新でカンマの後に式がない
UPDATE employees
SET status = 'ACTIVE',
WHERE department_id = 10;

-- OK: 2列目の代入式を書く、または余分なカンマを消す
UPDATE employees
SET status = 'ACTIVE',
    updated_at = SYSDATE
WHERE department_id = 10;

動的SQLで更新値が任意入力の場合、空文字や未設定値をそのままSQLへ連結すると SET column = のような形になりがちです。更新する列だけをリスト化し、空の代入式を作らないようにします。

CASE式が途中で終わっている

CASE 式は、WHENTHEN、必要に応じて ELSE、最後に END まで書きます。THEN の後の値がない、END が抜けている、といった場合はORA-00936の原因になります。

case-missing-expression.sql
-- NG: THENの後に返す式がない
SELECT
    CASE
        WHEN salary >= 500000 THEN
        ELSE 'NORMAL'
    END AS salary_rank
FROM employees;

-- OK: THENの後に値を書く
SELECT
    CASE
        WHEN salary >= 500000 THEN 'HIGH'
        ELSE 'NORMAL'
    END AS salary_rank
FROM employees;

CASE式の実務パターンは OracleのCASE式完全ガイド で詳しく扱っています。

GROUP BYやHAVINGで式が抜けている

集計SQLでは、GROUP BY の項目が空になっていたり、HAVING の比較条件が途中で終わっていたりすると、ORA-00936の原因になります。集計関数そのものよりも、カンマの後や比較演算子の右側を確認します。

group-by-having-missing-expression.sql
-- NG: GROUP BYの後に式がない
SELECT department_id, COUNT(*) AS employee_count
FROM employees
GROUP BY;

-- OK: グループ化する列を書く
SELECT department_id, COUNT(*) AS employee_count
FROM employees
GROUP BY department_id;

-- NG: HAVINGの比較値がない
SELECT department_id, COUNT(*) AS employee_count
FROM employees
GROUP BY department_id
HAVING COUNT(*) >;

-- OK: 比較値を書く
SELECT department_id, COUNT(*) AS employee_count
FROM employees
GROUP BY department_id
HAVING COUNT(*) > 5;

予約語や別名の使い方ミス

Oracle公式のORA-00936説明では、予約語を誤用した場合にもこのエラーが出ることがあるとされています。列名や別名に予約語を使っている場合は、名前を変えるか、必要に応じてダブルクォートで囲みます。

reserved-word.sql
-- NGになりやすい例: 予約語をそのまま式のように使う
SELECT table
FROM user_tables;

-- OK: 正しい列名を使う
SELECT table_name
FROM user_tables;

列名ミスや別名の参照ミスでは ORA-00904 になることもあります。識別子側の問題は ORA-00904の原因と解決方法 も確認してください。

動的SQLで空の条件を作っている

アプリやPL/SQLでSQL文字列を組み立てる場合、条件が空のまま連結されるとORA-00936になりやすいです。ログには最終的にDBへ送ったSQLを出し、空のWHERE、余分なAND、空のINリストを確認します。

dynamic-sql-empty-condition.sql
-- NG: 条件を連結した結果、ANDの後に式がない
SELECT *
FROM employees
WHERE department_id = 10
  AND;

-- OK: 条件がある場合だけAND以降を追加する
SELECT *
FROM employees
WHERE department_id = 10
  AND status = 'ACTIVE';

動的SQLでは、文字列結合で無理にSQLを作るより、条件リストを配列で持ち、最後に AND で結合する設計にすると崩れにくいです。

エラー位置の読み方

SQL DeveloperやSQL*Plusでは、エラー行や列が表示されることがあります。ただし、実際に不足している式は、表示位置そのものではなく、その直前にある場合も多いです。たとえば FROM の位置に印が出ている場合、SELECT句末尾のカンマが原因かもしれません。

印が出た場所 疑う場所
FROM SELECT句の最後 余分なカンマ、SELECT項目なし
WHERE の後 条件式 列名だけ、比較演算子だけ
閉じ括弧付近 関数引数、サブクエリ 空の引数、カンマの後に値がない
END 付近 CASE式 THEN の返却値不足

修正チェックリスト

手順 確認すること よくある修正
1 SELECT句に列や式があるか SELECT employee_id FROM ... にする
2 カンマの後に式があるか 末尾カンマを消す
3 WHERE条件が途中で終わっていないか 右辺の値、サブクエリ、条件式を書く
4 関数の引数が足りているか 必要な引数とカンマをそろえる
5 UPDATEのSET句に値があるか SET column = で止まっていないか確認する
6 CASE式が END まで閉じているか THEN の返却値も確認する
7 動的SQLで空条件を連結していないか 条件がある場合だけSQLへ追加する

よくある質問

ORA-00936はなぜ発生しますか?

SQLの中で必要な式、列名、値、条件、関数引数などが抜けているためです。エラー位置の直前を見て、カンマ、演算子、関数、CASE式が途中で終わっていないか確認します。

ORA-00933との違いは何ですか?

ORA-00933は句の順序やSQLの終わり方、他DB構文が原因になりやすいです。ORA-00936は、式が必要な場所に式がない場合に出やすいです。

SELECT * と別の列を一緒に書くときの注意点は?

SELECT 'X', * のような書き方ではなく、テーブル別名を付けて SELECT 'X', e.* FROM employees e のように書くと安全です。

GROUP BYでORA-00936が出る場合は?

GROUP BY の後に列や式があるか、末尾カンマがないか、HAVING の条件が途中で終わっていないかを確認します。集計関数の引数や比較値も見落としやすいです。

UPDATEでORA-00936が出る場合は?

SET column = の右辺が空になっていないか、複数列更新の末尾に余分なカンマがないかを確認します。動的SQLでは、更新値がある列だけをSQLに追加するようにします。

動的SQLでORA-00936を防ぐには?

最終的にDBへ送るSQLをログに出し、空のWHERE、余分なAND、空のINリストを作らないようにします。条件がある場合だけSQLへ追加する実装にすると事故を減らせます。

まとめ

ORA-00936は、SQLに必要な式が不足していることを示すエラーです。SELECT句、WHERE句、関数引数、INSERTの値、UPDATEのSET句、CASE式、GROUP BY/HAVING、動的SQLの条件連結を順番に確認しましょう。

エラー位置だけを見るのではなく、その直前に余分なカンマや途中で終わった式がないかを見るのが近道です。句の順序や他DB構文が怪しい場合はORA-00933、列名や別名が怪しい場合はORA-00904もあわせて確認すると切り分けやすくなります。

参考

ORA-00936 – Oracle Database Error Help

SELECT – Oracle SQL Language Reference

INSERT – Oracle SQL Language Reference

CASE Expressions – Oracle SQL Language Reference