【Oracle】ORA-00913: 値の個数が多すぎます の原因と解決方法

【Oracle】ORA-00913: 値の個数が多すぎます の原因と解決方法 Oracle

ORA-00913: 値の個数が多すぎます は、SQLで指定した列数より値やSELECT結果の列数が多いときに発生するOracleエラーです。特に INSERTINSERT INTO ... SELECT、サブクエリ、IN 句でよく出ます。

この記事では、ORA-00913の典型原因、すぐ確認するSQL、原因別の修正例、似たエラーとの違い、実務での予防策まで整理します。OracleのDML全体を見直したい場合は、Oracle INSERT・UPDATE・DELETE完全ガイドも参考になります。

先に結論: ORA-00913が出たら、まず INSERT の列リスト数、VALUES の値数、SELECT の列数、サブクエリが返す列数を確認します。列名を省略した INSERT INTO table VALUES (...) は列追加に弱いので、列名を明示するのが安全です。
スポンサーリンク

最短で直すチェックリスト

エラー箇所が長いSQLの中にある場合は、先に次の順で切り分けると原因を見つけやすくなります。

出ているSQL 最初に見る場所 修正方針
INSERT ... VALUES 列リストとVALUESの個数 列名を明示し、値の数を列数に合わせる
INSERT ... SELECT INSERT先列数とSELECT句の列数 SELECT句の余分な列を削る、またはINSERT先列を追加する
WHERE col = (SELECT ...) サブクエリのSELECT列数 1列だけ返す形に直す
IN (SELECT ...) 左辺と右辺の列数 単一列INにするか、タプル形式で列数を揃える
INSERT ALL 各INTO句の列数とVALUES数 INTO句ごとに対応する値を数える

ORA-00913の意味

ORA-00913は、Oracleが「この場所で期待している値の数より、実際に渡された値の数が多い」と判断したときに発生します。代表的には、2列だけ指定しているのに3つの値を渡すケースです。

bad-insert-values.sql
INSERT INTO employees (employee_id, employee_name)
VALUES (1001, 'SATO', 'SALES');

この例では、列リストは employee_idemployee_name の2列ですが、VALUES には3つの値があります。そのためORA-00913になります。

まず確認するポイント

確認箇所 見ること よくある原因
INSERT の列リスト 列数 列は2個なのに値が3個ある
VALUES 値の数 余分な値、カンマ、括弧ミス
INSERT SELECT SELECT句の列数 INSERT先列数よりSELECT列が多い
サブクエリ 返す列数 1列を期待する場所で2列以上返している
IN 左辺と右辺の列数 単一列INに複数列のSELECTを渡している

原因1: INSERTの列数よりVALUESが多い

もっとも多い原因は、INSERT の列リストと VALUES の個数が一致していないケースです。

insert-column-count-bad.sql
-- NG: 2列指定なのに値が3個ある
INSERT INTO employees (employee_id, employee_name)
VALUES (1001, 'SATO', 'SALES');
insert-column-count-good.sql
-- OK: 列数と値の数を合わせる
INSERT INTO employees (employee_id, employee_name, department_name)
VALUES (1001, 'SATO', 'SALES');

逆に値が少ない場合は、別のエラーやNOT NULL制約エラーにつながります。NOT NULL列が絡む場合は、ORA-01400 cannot insert NULL の原因と解決方法もあわせて確認してください。

原因2: 列名を省略したINSERTでテーブル定義と合わない

INSERT INTO table VALUES (...) のように列名を省略すると、テーブルの全列に対して値を渡す扱いになります。列追加や不可視列、定義変更があると、列数の不一致に気づきにくくなります。

insert-without-column-list-bad.sql
-- NG: テーブル定義の列数とVALUESの数が合わない
INSERT INTO employees
VALUES (1001, 'SATO', 'SALES', 'TOKYO');
insert-with-column-list-good.sql
-- OK: 登録する列を明示する
INSERT INTO employees (employee_id, employee_name, department_name)
VALUES (1001, 'SATO', 'SALES');

実務では、列名を明示する書き方を基本にするのがおすすめです。テーブル定義や列制約の考え方は、Oracle CREATE TABLE完全ガイドで詳しく整理しています。

原因3: VALUES句の括弧・カンマのミス

値の数そのものは合っているつもりでも、余分なカンマや括弧の位置ずれで、Oracleが値を多く解釈することがあります。手作業でSQLを組み立てた場合や、プログラムからSQL文字列を連結している場合に起きやすいパターンです。

values-comma-bad.sql
-- NG: 末尾側に余分な値が残っている
INSERT INTO employees (employee_id, employee_name)
VALUES (1001, 'SATO', 'SALES');
values-comma-good.sql
-- OK: 列数とVALUESの値数を同じにする
INSERT INTO employees (employee_id, employee_name)
VALUES (1001, 'SATO');

アプリ側でSQLを生成している場合は、最終的にOracleへ渡しているSQLをログに出し、INSERT の列リストと VALUES の値数を実物で数えるのが確実です。

テーブルの列数を確認するSQL

INSERT先の列を確認するには、USER_TAB_COLUMNSALL_TAB_COLUMNS を使います。

check-table-columns.sql
SELECT column_id,
       column_name,
       data_type,
       nullable
FROM   user_tab_columns
WHERE  table_name = 'EMPLOYEES'
ORDER BY column_id;

列数だけでなく、NOT NULL、デフォルト値、生成列、不可視列の有無も確認します。不可視列がある環境では、Oracle不可視列(Invisible Column)完全ガイドも参考になります。

原因4: INSERT SELECTのSELECT列が多い

INSERT INTO ... SELECT ... では、INSERT先の列数とSELECT句の列数を一致させる必要があります。

insert-select-bad.sql
-- NG: INSERT先は2列、SELECTは3列
INSERT INTO employees_archive (employee_id, employee_name)
SELECT employee_id,
       employee_name,
       department_name
FROM   employees;
insert-select-good.sql
-- OK: INSERT先とSELECT句の列数を合わせる
INSERT INTO employees_archive (employee_id, employee_name, department_name)
SELECT employee_id,
       employee_name,
       department_name
FROM   employees;

INSERT SELECT は便利ですが、SELECT句に列を追加したときにINSERT先の列リストを直し忘れやすいです。基本構文や実務パターンは、SQL INSERT INTO…SELECT完全ガイドも参考になります。

原因5: サブクエリが複数列を返している

1つの値を期待する場所に、複数列を返すサブクエリを書くとORA-00913になることがあります。

scalar-subquery-bad.sql
-- NG: = の右側は1列を期待するが、サブクエリが2列返している
SELECT employee_id,
       employee_name
FROM   employees
WHERE  department_id = (
  SELECT department_id,
         department_name
  FROM   departments
  WHERE  department_name = 'SALES'
);
scalar-subquery-good.sql
-- OK: サブクエリは1列だけ返す
SELECT employee_id,
       employee_name
FROM   employees
WHERE  department_id = (
  SELECT department_id
  FROM   departments
  WHERE  department_name = 'SALES'
);

サブクエリは「何列返すか」と「何行返すか」を分けて確認します。1列でも複数行返る場合は、ORA-01427など別のエラーになることがあります。

原因6: IN句の左辺と右辺の列数が合っていない

単一列の IN に、複数列を返すサブクエリを渡すと列数が合いません。

in-subquery-bad.sql
-- NG: 左辺は1列、右辺は2列
SELECT employee_id,
       employee_name
FROM   employees
WHERE  department_id IN (
  SELECT department_id,
         location_id
  FROM   departments
);
in-subquery-good.sql
-- OK: 1列INならサブクエリも1列にする
SELECT employee_id,
       employee_name
FROM   employees
WHERE  department_id IN (
  SELECT department_id
  FROM   departments
);

複数列で比較したい場合は、タプル形式にします。

multi-column-in-good.sql
-- OK: 左辺も右辺も2列にする
SELECT employee_id,
       employee_name
FROM   employees
WHERE  (department_id, location_id) IN (
  SELECT department_id,
         location_id
  FROM   departments
);

原因7: マルチテーブルINSERTの構文ミス

INSERT ALLINSERT FIRST では、各 INTO 句の列リストと値の数をそれぞれ合わせます。1つの SELECT から複数テーブルに入れるため、列数の対応関係が見えにくくなります。

insert-all-bad.sql
-- NG: sales_summaryは2列指定なのに値が3個ある
INSERT ALL
  INTO sales_summary (order_id, amount)
  VALUES (order_id, amount, order_date)
  INTO sales_log (order_id, amount, order_date)
  VALUES (order_id, amount, order_date)
SELECT order_id,
       amount,
       order_date
FROM   orders;

マルチテーブルINSERTは強力ですが、単純なINSERTより列数チェックが重要です。OracleマルチテーブルINSERT完全ガイドもあわせて確認してください。

ORA-00913と似たエラー

エラー 主な意味 違い
ORA-00913 値の個数が多すぎる 列数より値やサブクエリ列が多い
ORA-00947 値の個数が不足している 列数より値が少ない
ORA-00932 データ型が一致しない 列数ではなく型の不一致
ORA-01400 NULLを挿入できない 必須列にNULLを入れている
ORA-01789 問い合わせブロックの結果列数が正しくない UNIONなど集合演算の列数不一致で出やすい

型の不一致が疑わしい場合は、ORA-00932 データ型不一致の原因と解決方法を確認してください。UNIONの列数や並び順は、Oracle集合演算完全ガイドも参考になります。

切り分け手順

  1. INSERT の列リストを数える
  2. VALUES の値の数を数える
  3. INSERT SELECT の場合はSELECT句の列数を数える
  4. サブクエリが1列だけ返しているか確認する
  5. SELECT * をやめて列名を明示する
  6. テーブル定義を USER_TAB_COLUMNS で確認する

特に SELECT * は、列追加の影響を受けやすい書き方です。本番運用のINSERTでは、列名を明示してSQLの意図を固定するほうが安全です。

予防策

予防策 理由
INSERTでは列名を明示する テーブル定義変更の影響を受けにくい
INSERT SELECTではSELECT列に別名やコメントを付ける 対応関係を追いやすい
SELECT * をINSERT元にしない 列追加で壊れやすい
テーブル定義を確認してから投入する 列数・型・必須列を事前に把握できる
検証SQLを小さく分ける どの句で列数がズレたか分かりやすい

関連ページ

よくある質問

ORA-00913はどんなエラーですか?

SQLで期待される列数より、指定した値やサブクエリの列数が多いときに発生するエラーです。INSERTやサブクエリでよく出ます。

INSERTでORA-00913が出る原因は何ですか?

列リストの数より VALUES の値が多い、または列名を省略したINSERTでテーブル定義と値の数が合っていないことが多いです。

INSERT SELECTでORA-00913が出たら何を見ますか?

INSERT先の列数とSELECT句の列数を比較します。SELECT句に列を追加したのにINSERT先列リストを直していないケースがよくあります。

サブクエリでもORA-00913は出ますか?

出ます。1列だけを期待する場所で、サブクエリが2列以上返している場合に発生します。

UNIONの列数不一致もORA-00913ですか?

UNIONなど集合演算の列数不一致では、ORA-01789が出ることが多いです。ORA-00913と同じく列数の不一致ですが、発生場所が異なります。

ORA-00913を防ぐ書き方はありますか?

INSERT INTO table (col1, col2) のように列名を明示し、SELECT * をINSERT元に使わないことが有効です。

まとめ

ORA-00913「値の個数が多すぎます」は、列数と値の数が合っていないときに発生します。まずは INSERT の列リスト、VALUESINSERT SELECT のSELECT句、サブクエリの返す列数を確認しましょう。

実務では、列名を省略したINSERTや SELECT * が原因になりがちです。列名を明示し、テーブル定義を確認しながらSQLを書くことで、ORA-00913をかなり防げます。