ORA-00947: not enough values は、Oracleで INSERT 文を実行した時に、登録先の列数に対して VALUES 句や SELECT 句の値の数が足りない場合に発生するエラーです。
よくある原因は、列リストを省略したINSERT、列を追加した後に古いINSERT文を使っている、INSERT INTO ... SELECT のSELECT列数が足りない、INSERT ALL の値数が合っていない、DEFAULTやNULLで埋めるべき列を省いている、といったパターンです。
ORA-00947は「入れる列数」と「渡す値数」が合っていないエラーです。まず
INSERT INTO table_name (列1, 列2, ...) の列リストを明示し、VALUES または SELECT の値数と1対1で対応しているか確認します。ORA-00947とは
Oracle公式のエラー説明では、ORA-00947はSQL文で必要な2つの値セットの片方に、十分な値がない時に発生します。代表例は、INSERT文の VALUES 句や SELECT 句に、INSERT先で必要な値が足りないケースです。
INSERT/UPDATE/DELETEの基本は INSERT・UPDATE・DELETE完全ガイド、テーブル定義の確認は CREATE TABLE完全ガイド も参考になります。
最小の再現例
次のテーブルは3列あります。列リストを省略して2つだけ値を渡すと、Oracleは全列に値が必要だと判断し、ORA-00947になります。
CREATE TABLE app_user ( user_id NUMBER, user_name VARCHAR2(100), status VARCHAR2(20) );
INSERT INTO app_user VALUES (1, 'tanaka'); -- ORA-00947: not enough values
列リストを明示して、値の数を合わせます。未指定列をNULLにしたい場合は列リストから外し、値を入れたい場合はVALUESに追加します。
INSERT INTO app_user (user_id, user_name) VALUES (1, 'tanaka'); -- status は省略されるため NULL になる
INSERT INTO app_user (user_id, user_name, status) VALUES (1, 'tanaka', 'ACTIVE');
発生しやすいパターン
列リストを省略している
テーブルの全列に対して値が必要になります。列追加後に古いINSERT文を実行すると起きやすいです。
INSERT列数よりVALUESが少ない
INSERT INTO t (a, b, c) VALUES (1, 2) のように、列数と値数が合っていないケースです。
INSERT INTO SELECTのSELECT列が少ない
INSERT先の列リストが4列なのに、SELECT句が3列しか返していないケースです。
INSERT ALLでINTOごとの値数が足りない
複数表INSERTで、一部のINTO句だけ列数と値数がずれているケースです。
テーブル定義が変わった
列追加・削除・INVISIBLE列・DEFAULT変更などで、既存SQLとテーブル定義がずれているケースです。
テーブル列数を確認するSQL
まず、INSERT先テーブルにどの列があるか確認します。列リストを省略している場合は、ここに表示される列の数と順番が重要になります。
SELECT column_id,
column_name,
data_type,
nullable,
data_default,
hidden_column,
virtual_column,
identity_column
FROM user_tab_cols
WHERE table_name = UPPER('&TABLE_NAME')
ORDER BY column_id;
列リスト省略のINSERTは、テーブル定義変更に弱くなります。実務では
INSERT INTO table_name (col1, col2, ...) の形を基本にすると、ORA-00947だけでなく意図しない列ずれも防げます。INSERT対象列を数えるSQL
列リストを省略しているSQLを調べる時は、通常のINSERTで対象になりうる列を数えると切り分けが速くなります。仮想列や一部の生成列は明示的に値を入れられないため、単純な列数だけで判断しないようにします。
SELECT COUNT(*) AS insert_target_columns
FROM user_tab_cols
WHERE table_name = UPPER('&TABLE_NAME')
AND hidden_column = 'NO'
AND virtual_column = 'NO';
SELECT column_id,
column_name,
nullable,
data_default,
identity_column
FROM user_tab_cols
WHERE table_name = UPPER('&TABLE_NAME')
AND hidden_column = 'NO'
AND virtual_column = 'NO'
ORDER BY column_id;
INSERT INTO SELECTで発生する例
INSERT INTO ... SELECT では、INSERT先の列リストとSELECT句の列数を合わせます。列名ではなく、列の数と順番で対応する点に注意します。
INSERT INTO app_user (user_id, user_name, status)
SELECT employee_id,
employee_name
FROM employees;
-- INSERT先は3列、SELECTは2列なので ORA-00947
INSERT INTO app_user (user_id, user_name, status)
SELECT employee_id,
employee_name,
'ACTIVE' AS status
FROM employees;
DEFAULTやNULLで埋める
値が未定の場合は、列リストから外す、NULL を明示する、DEFAULT を使う、のいずれかを選びます。ただし、NOT NULL列やCHECK制約がある列では、NULLやDEFAULTが許可されるか確認が必要です。
INSERT INTO app_user (user_id, user_name, status) VALUES (1, 'tanaka', DEFAULT); INSERT INTO app_user (user_id, user_name, status) VALUES (2, 'suzuki', NULL);
NULL制約で止まる場合は ORA-01400 完全ガイド も確認してください。日付列のINSERTは INSERTで日付・日時を登録する完全ガイド が参考になります。
INSERT ALLで発生する例
Oracleで複数行をまとめてINSERTする時に INSERT ALL を使う場合、各 INTO 句ごとに列数と値数を合わせます。
INSERT ALL INTO app_user (user_id, user_name, status) VALUES (1, 'tanaka') INTO app_user (user_id, user_name, status) VALUES (2, 'suzuki', 'ACTIVE') SELECT * FROM dual; -- 1つ目のINTO句だけ値が足りない
INSERT ALL INTO app_user (user_id, user_name, status) VALUES (1, 'tanaka', 'ACTIVE') INTO app_user (user_id, user_name, status) VALUES (2, 'suzuki', 'ACTIVE') SELECT * FROM dual;
ビューやINVISIBLE列で起きるケース
ビューにINSERTする場合や、テーブルにINVISIBLE列がある場合も、列リストを明示しないINSERTは分かりにくくなります。ビュー側の列定義や、実テーブルの表示列/非表示列を確認してください。
SELECT column_id,
column_name,
data_type
FROM user_tab_columns
WHERE table_name = UPPER('&VIEW_OR_TABLE_NAME')
ORDER BY column_id;
テーブル定義や列制約の確認は CREATE TABLE完全ガイド も参考になります。
IDENTITY列・仮想列・DEFAULT列の注意点
自動採番のIDENTITY列、仮想列、DEFAULT値を持つ列がある場合は、列リストを明示すると安全です。自動で値を入れたい列は列リストから外し、明示的に入れる列だけを指定します。
CREATE TABLE app_event (
event_id NUMBER GENERATED BY DEFAULT AS IDENTITY,
event_name VARCHAR2(100),
created_at DATE DEFAULT SYSDATE
);
-- event_id と created_at は自動/DEFAULTに任せる
INSERT INTO app_event (event_name)
VALUES ('login');
自動採番列やDEFAULT列を列リストから外すと、値数のズレを避けやすくなります。逆に列リストへ含めるなら、その列に対応する値または DEFAULT を渡します。
列追加後に古いSQLで発生するケース
テーブルに列を追加した後、列リストを省略した古いINSERT文をそのまま実行すると、ORA-00947が発生しやすくなります。アプリ、バッチ、移行SQL、テストデータ作成SQLに列リスト省略のINSERTが残っていないか確認します。
-- もともと2列だったテーブルに status 列を追加した後 ALTER TABLE app_user ADD status VARCHAR2(20) DEFAULT 'ACTIVE' NOT NULL; -- 古いSQL: 列リストなし、値は2つだけ INSERT INTO app_user VALUES (1, 'tanaka'); -- 修正: 列リストを明示する INSERT INTO app_user (user_id, user_name) VALUES (1, 'tanaka');
ORA-00913との違い
ORA-00947
値の個数が足りません。INSERT先の列数に対して、VALUESやSELECTの値が少ない状態です。
ORA-00913
値の個数が多すぎます。INSERT先の列数に対して、VALUESやSELECTの値が多い状態です。詳細は ORA-00913の原因と解決方法 を参照してください。
ORA-00936
式が不足している構文エラーです。カンマの後ろに式がない、SELECT句やWHERE句が壊れている場合などに発生します。詳細は ORA-00936の原因と解決方法 を参照してください。
ORA-00933
SQL文の終わり方や構文がOracleの形式に合っていない場合に発生します。複数行INSERTの書き方違いでも見かけます。詳細は ORA-00933の原因と解決方法 を参照してください。
SQL*LoaderやCSV取込では列対応を確認する
CSVや外部ファイルから投入する場合も、ファイル側の列数とテーブル側の列定義がずれると、値不足や別の取込エラーにつながります。大量データを扱うなら、INSERT文を手生成するよりSQL*Loaderなどを使う方が安全です。
SQL*Loaderの基本は SQL*Loader完全ガイド を参照してください。
修正の流れ
- INSERT先の列リストが明示されているか確認する
- 列リストがある場合は、列数とVALUESの値数を数える
- 列リストがない場合は、テーブル定義の列数・順番を確認する
INSERT INTO ... SELECTなら、SELECT句の列数を確認するINSERT ALLなら、各INTO句の列数と値数を確認する- 未指定でよい列は列リストから外す、または
DEFAULT/NULLを明示する - 列追加後に古いSQLを使っていないか、アプリ・バッチ・移行SQLを確認する
よくある質問
列リストを省略してもよいですか?
動く場合はありますが、実務ではおすすめしません。列追加や順番変更に弱く、ORA-00947や意図しない列ずれの原因になります。
DEFAULT値がある列にも値が必要ですか?
列リストから外せばDEFAULTが使われます。列リストに含めた場合は、値を渡すか DEFAULT を明示します。
IDENTITY列やシーケンス列でORA-00947になりますか?
列リストを省略していると、IDENTITY列を含む全列に対する値が必要になることがあります。自動採番列は列リストから外す形にすると安全です。
まとめ
ORA-00947は、INSERTで必要な値の数が足りない時に発生します。まずINSERT先の列リストと、VALUESまたはSELECTの値数が一致しているか確認してください。
最も安全な対策は、INSERTでは必ず列リストを明示することです。列追加やDEFAULT、NULL、INSERT INTO SELECT、INSERT ALLを使う場合も、列数と値数が1対1で対応しているかを確認すると、原因を素早く特定できます。

