導入
データベースに新しい行(レコード)を入れる基本操作が oracle insert です。本記事では insert oracle の正しい使い方を、やさしい言葉と“そのまま動く実行例”で解説します。ユーザー作成 → 表(テーブル)作成 → INSERT → 確認 → エラー対処まで。
テーブルの作成についてはコチラ。
💰 【PR】Oracleエンジニアの市場価値、調べてみませんか?
Oracleのスキルは需要が高く、特定の資格や経験を持っていると年収が大幅にアップするケースがあります。まずはIT専門のエージェントで非公開求人をチェックしてみませんか?
このページのゴール(3分で把握)
- INSERT文の安全な書き方(列名を明示)を理解する。
- 日付・時刻・数値の入れ方をミスなく書ける。
- IDENTITY と SEQUENCE の違い・使い分けを説明できる。
- 代表的なエラー原因と直し方を自分で判断できる。
基本からスタート:insert oracle の考え方
INSERT 文は「どの表に」「どの列へ」「どんな値を入れるか」を指定して書きます。将来の変更に強くするため、列(カラム)名は必ず明示しましょう。
例:基本の書き方
-- 推奨:列名を明示(安全・読みやすい)
INSERT INTO 表名 (列1, 列2, ...) VALUES (値1, 値2, ...);
-- 非推奨:全列に順番通り(将来、列が増えると壊れやすい)
INSERT INTO 表名 VALUES (値1, 値2, ...);
ポイント
- 省略した列には DEFAULT の値が入る(設定がなければ NULL)。
NOT NULLの列を省略するとエラー(ORA-01400)。- 日付・時刻は
TO_DATE/TO_TIMESTAMPで書式を明示すると安心。
補足:列名の省略と NULL の指定
- すべての列に値を入れる場合は、列名リストを省略して書けます(ただし将来の列追加に弱いため、実務では列名の明示を推奨)。
- 値を入れない列に NULL を入れたい場合は、
VALUES内で NULL を書きます(列を省略した場合は DEFAULT が適用され、DEFAULT がなければ NULL が入ります)。
-- 列名省略(全列に値を入れる)※テーブル定義の列順に合わせる
INSERT INTO customers
VALUES (DEFAULT, 'Foo', 'foo@example.com', SYSDATE, 'A');
-- 値を入れない列に NULL を明示(joined_on と email を NULL にする例)
INSERT INTO customers (name, email, joined_on, status)
VALUES ('Bar', NULL, NULL, 'A');
テキスト図:INSERT のながれ
┌──── クライアント(SQL*Plus / SQLcl / アプリ) ────┐
│ INSERT INTO T(colA,colB) VALUES(:A,:B); │
└───────────────────↓────────────────────┘
┌────────── Oracleサーバ ──────────┐ ┌── テーブル領域 ──┐
│ ①文法チェック ②制約チェック(NOT NULL/一意/外部キー)│→│ 行を書き込む │
│ ③必要なら索引も更新 │ │ 索引も更新 │
└──────────────────────────────┘ └──────────────┘
データ型ごとの安全な書き方(暗黙変換を避ける)
Oracle が自動で型を変える「暗黙変換」は思わぬミスの原因です。狙った型で入れましょう。
-- 文字列(シングルクォートで囲む)
INSERT INTO t(c_vc2) VALUES ('山田太郎');
-- 日付(書式を明示)
INSERT INTO t(c_date) VALUES (TO_DATE('2025-08-01','YYYY-MM-DD'));
-- タイムスタンプ(ミリ秒まで)
INSERT INTO t(c_ts) VALUES (
TO_TIMESTAMP('2025-08-01 10:20:30.123','YYYY-MM-DD HH24:MI:SS.FF3')
);
-- 数値(クォート不要)
INSERT INTO t(c_num) VALUES (12345);
自動採番は2つ:IDENTITY と SEQUENCE の使い分け
「主キーを自動で増やしたい」——そんなときは IDENTITY 列 か SEQUENCE を使います。どちらも“番号を発行する”仕組みですが、設計や運用で向き不向きがあります。
まず結論(選び方の早見表)
┌─────────────┬──────────────────────────────┐
│ やりたいこと │ おすすめ │
├─────────────┼──────────────────────────────┤
│ いちばん簡単に自動採番 │ IDENTITY 列(テーブルの列定義に付ける) │
│ 細かく挙動を調整したい │ SEQUENCE(開始値/間隔/キャッシュ等を個別設定) │
│ 既存アプリでNEXTVAL使用│ SEQUENCE │
└─────────────┴──────────────────────────────┘
IDENTITY 列(シンプルで学習向き)
何か? テーブルの列に「自動で番号をふる」性質をつける機能。内部的にはシーケンスに近い仕組みを使います。
主な指定
GENERATED ALWAYS AS IDENTITY… 常にDBが採番(手動で値を入れるとエラー)GENERATED BY DEFAULT AS IDENTITY… ふだんはDBが採番。必要なら手動指定も可能- (応用)
BY DEFAULT ON NULL… 値がNULLのときだけDBが採番
基本例
CREATE TABLE demo_customers (
id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
name VARCHAR2(50) NOT NULL,
email VARCHAR2(255) UNIQUE,
joined_on DATE DEFAULT SYSDATE,
status CHAR(1) DEFAULT 'A' CHECK (status IN ('A','I'))
);
-- id はDBが自動採番
INSERT INTO demo_customers (name, email)
VALUES ('Sato Ichiro','s.ichiro@example.com');
コマンド実行例
SQL> CREATE TABLE demo_customers (
2 id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
3 name VARCHAR2(50) NOT NULL,
4 email VARCHAR2(255) UNIQUE,
5 joined_on DATE DEFAULT SYSDATE,
6 status CHAR(1) DEFAULT 'A' CHECK (status IN ('A','I'))
7 );
Table created.
SQL> INSERT INTO demo_customers (name, email)
2 VALUES ('Sato Ichiro','s.ichiro@example.com');
1 row created.
SQL> set lin 1000
SQL> col name for a15
SQL> col email for a25
SQL> select * from demo_customers;
ID NAME EMAIL JOINED_ON S
---------- --------------- ------------------------- --------- -
1 Sato Ichiro s.ichiro@example.com 23-AUG-25 A
よくあるQ&A
- Q: 間違えて入れたので ROLLBACK したら番号は戻る? → 戻りません。 採番は消費され、番号には“飛び番(欠番)”が出ます。
- Q: 次回の採番開始値を変えたい? → 列を変更します。
ALTER TABLE demo_customers MODIFY
(id GENERATED BY DEFAULT AS IDENTITY START WITH 1000);
- Q: 手動で値を入れたい? →
BY DEFAULTを使っているときだけ可能です。
メリット/注意
- 追加のオブジェクト管理が不要でシンプル。
- ただし 欠番が出る ことは普通(トランザクション取り消し/同時実行/障害時など)。
SEQUENCE(自由度が高いプロ向け)
何か? 独立した「番号発行機」オブジェクト。NEXTVAL で次の番号、CURRVAL で今の番号を取得します。
作成と利用の基本
-- 作成
CREATE SEQUENCE demo_customers_seq START WITH 1 INCREMENT BY 1 CACHE 20 NOCYCLE;
-- シーケンスを使う表
CREATE TABLE demo_customers_seqver (
id NUMBER PRIMARY KEY,
name VARCHAR2(50) NOT NULL,
created_at DATE DEFAULT SYSDATE
);
-- 挿入時にNEXTVALを使う
INSERT INTO demo_customers_seqver (id, name)
VALUES (demo_customers_seq.NEXTVAL, 'Tanaka Hanako');
-- 同じセッションなら直後にCURRVALで最後の番号を参照
SELECT demo_customers_seq.CURRVAL FROM dual;
コマンド実行例
SQL> CREATE SEQUENCE demo_customers_seq START WITH 1 INCREMENT BY 1 CACHE 20 NOCYCLE;
Sequence created.
SQL> CREATE TABLE demo_customers_seqver (
2 id NUMBER PRIMARY KEY,
3 name VARCHAR2(50) NOT NULL,
4 created_at DATE DEFAULT SYSDATE
5 );
Table created.
SQL> INSERT INTO demo_customers_seqver (id, name)
2 VALUES (demo_customers_seq.NEXTVAL, 'Tanaka Hanako');
1 row created.
SQL> select * from demo_customers_seqver;
ID NAME CREATED_A
---------- --------------- ---------
1 Tanaka Hanako 23-AUG-25
SQL> SELECT demo_customers_seq.CURRVAL FROM dual;
CURRVAL
----------
1
主なオプション(よく使うもの)
START WITH n:初期値INCREMENT BY n:増分CACHE n / NOCACHE:番号をメモリにキャッシュ(高速化。ただし障害時は欠番が出やすい)CYCLE / NOCYCLE:最大値まで行ったら最小値に戻るか
メリット/注意
- 振る舞いを細かく調整でき、複数テーブルでも使い回せる。
CURRVALは同じセッションでNEXTVALを一度実行してからでないと参照できません。- こちらも 欠番は普通 に発生します(キャッシュ/ロールバック/並列挿入等)。
💰 【PR】Oracleエンジニアの市場価値、調べてみませんか?
Oracleのスキルは需要が高く、特定の資格や経験を持っていると年収が大幅にアップするケースがあります。まずはIT専門のエージェントで非公開求人をチェックしてみませんか?
IDENTITY と SEQUENCE の違い(かんたん図)
┌────────────┬───────────────────────────┐
│ IDENTITY 列 │ 列に“自動採番”の性質を付与。表の一部。 │
├────────────┼───────────────────────────┤
│ SEQUENCE │ 独立オブジェクト。NEXTVAL/ CURRVALで取得。│
├────────────┼───────────────────────────┤
│ 初期設定の容易さ │ ◎(作成が簡単) │
│ 調整の自由度 │ △(限定的) │
│ │ ◎(開始値/間隔/キャッシュ等を調整可) │
└────────────┴───────────────────────────┘
すぐに採番値を受け取る:RETURNING 句
RETURNING ... INTO は、INSERT/UPDATE/DELETE 直後に、その行の列値をプログラム側に返す文法です。単一行の操作でよく使います。
何が便利?
- 新しく入った行の ID(主キー) をすぐ受け取れる。
- デフォルト値(
SYSDATEなど)や 生成列 の値も一度で取得。
注意(SQL*Plus):
VARIABLEコマンドは DATE 型をサポートしません。日時を受け取るときはVARCHAR2変数を用意し、RETURNING側でTO_CHARで文字列化して受け取ります。
使い方(SQL*Plus/SQLcl の例)
VARIABLE v_new_id NUMBER
VARIABLE v_when VARCHAR2(32)
INSERT INTO demo_customers (name, email)
VALUES ('Yamada Taro','yamada.taro@example.com')
RETURNING id, TO_CHAR(joined_on,'YYYY-MM-DD HH24:MI:SS')
INTO :v_new_id, :v_when;
PRINT v_new_id
PRINT v_when
コマンド実行例
SQL> VARIABLE v_new_id NUMBER
SQL> VARIABLE v_when VARCHAR2(32)
SQL> INSERT INTO demo_customers (name, email)
2 VALUES ('Yamada Taro','yamada.taro@example.com')
3 RETURNING id, TO_CHAR(joined_on,'YYYY-MM-DD HH24:MI:SS')
4 INTO :v_new_id, :v_when;
1 row created.
SQL> select * from demo_customers;
ID NAME EMAIL JOINED_ON S
---------- --------------- ------------------------- --------- -
1 Sato Ichiro s.ichiro@example.com 23-AUG-25 A
1000 Yamada Taro yamada.taro@example.com 23-AUG-25 A
SQL> PRINT v_new_id
V_NEW_ID
----------
1000
SQL> PRINT v_when
V_WHEN
---------------------------------
2025-08-23 00:59:52
もし joined_on が TIMESTAMP 列なら
RETURNING id, TO_CHAR(joined_on,'YYYY-MM-DD HH24:MI:SS.FF3')
INTO :v_new_id, :v_when;
よくあるパターン
- IDENTITY と組み合わせて、発行された
idを受け取る。 - SEQUENCE を使う場合、
NEXTVALでID自体は分かりますが、RETURNINGで同時に他の列(SYSDATEなど)も受け取ると便利。
UPDATE/DELETE でも使える(参考)
-- UPDATE で変わった行の主キーを受け取る
VARIABLE v_id NUMBER
UPDATE demo_customers SET status='I' WHERE email='s.ichiro@example.com'
RETURNING id INTO :v_id;
-- DELETE で消した行の主キーを受け取る
VARIABLE v_del NUMBER
DELETE FROM demo_customers WHERE id=1
RETURNING id INTO :v_del;
コマンド実行例
SQL> VARIABLE v_id NUMBER
SQL> UPDATE demo_customers SET status='I' WHERE email='s.ichiro@example.com'
2 RETURNING id INTO :v_id;
1 row updated.
SQL> select * from demo_customers;
ID NAME EMAIL JOINED_ON S
---------- --------------- ------------------------- --------- -
1 Sato Ichiro s.ichiro@example.com 23-AUG-25 I
1000 Yamada Taro yamada.taro@example.com 23-AUG-25 A
SQL> PRINT v_id
V_ID
----------
1
SQL> VARIABLE v_del NUMBER
SQL> DELETE FROM demo_customers WHERE id=1
2 RETURNING id INTO :v_del;
1 row deleted.
SQL> select * from demo_customers;
ID NAME EMAIL JOINED_ON S
---------- --------------- ------------------------- --------- -
1000 Yamada Taro yamada.taro@example.com 23-AUG-25 A
SQL> PRINT v_del
V_DEL
----------
1
メモ
- 基本は1行対象のDMLで使います。複数行を一度に処理する場合は、PL/SQL の
RETURNING BULK COLLECT INTO(上級)などを検討します。 - アプリ(JDBC 等)では SQL 文の
RETURNINGを使わず、getGeneratedKeys などで受け取る方法もあります。
代表的なエラーと直し方(ミニ逆引き)
-- 一意制約違反(同じメールを入れた 等)
ORA-00001: 一意制約(string.string)に反しています
→ 入力前に重複チェック。ユニーク制約+索引で防ぐ。
-- NOT NULL違反(必須列がNULL)
ORA-01400: (string)にはNULLは挿入できません。
→ DEFAULT 設定/アプリ側の入力チェック/列リストの見直し。
-- 外部キー違反(親がないのに子を入れた)
ORA-02291: 整合性制約(string.string)に違反しました - 親キーがありません
→ 先に親レコードを入れる/順番を直す。
トランザクションの基本(確定=COMMIT/取り消し=ROLLBACK)
INSERT はCOMMIT するまで確定しません。やり直したいときは ROLLBACK を使います。
SAVEPOINT sv1; -- 途中の目印
INSERT INTO demo_customers (name) VALUES ('Temp User');
ROLLBACK TO sv1; -- その目印まで戻す
COMMIT; -- ここで確定
トランザクションについてはコチラ。
実行手順(19c/Oracle Linux 7.9 で確認済み)
以下は実機で動く最小手順です。表領域やパスワード規則は環境に合わせて調整してください。
1) ユーザー(スキーマ)を作る(SYSDBA)
-- CDB なら対象 PDB へ切り替えてから
-- sqlplus / as sysdba で接続
CREATE USER appuser IDENTIFIED BY "Str0ng#Pass"
DEFAULT TABLESPACE users QUOTA UNLIMITED ON users;
GRANT CREATE SESSION, CREATE TABLE, CREATE SEQUENCE TO appuser;
2) ログインして表を作る(APPUSER)
-- sqlplus appuser/Str0ng#Pass
CREATE TABLE customers (
id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
name VARCHAR2(50) NOT NULL,
email VARCHAR2(255) UNIQUE,
joined_on DATE DEFAULT SYSDATE,
status CHAR(1) DEFAULT 'A' CHECK (status IN ('A','I'))
);
3) 1行入れてみる(列名を明示)
INSERT INTO customers (name, email, status)
VALUES ('Suzuki Jiro','suzuki.jiro@example.com','A');
-- 省略した列は DEFAULT(joined_on = SYSDATE)
INSERT INTO customers (name, email)
VALUES ('Kato Miki','kato.miki@example.com');
4) 日付や時刻を安全に入れる
INSERT INTO customers (name, email, joined_on)
VALUES (
'Shimizu Kana',
'shimizu.kana@example.com',
TO_DATE('2025-08-23','YYYY-MM-DD')
);
5) 新しい ID をその場で受け取る
VARIABLE new_id NUMBER
INSERT INTO customers (name) VALUES ('Nagasawa Mei')
RETURNING id INTO :new_id;
PRINT :new_id;
COMMIT; -- 確定
6) 動作確認用の SQL
-- 件数を確認
SELECT COUNT(*) FROM customers;
-- 直近の行を確認
SELECT * FROM customers ORDER BY id DESC FETCH FIRST 5 ROWS ONLY;
-- メールの一意索引(UNIQUE)を確認
SELECT index_name, uniqueness
FROM user_indexes
WHERE table_name = 'CUSTOMERS';
実務で気をつけること(要点)
- 列名は必ず書く:
INSERT INTO T VALUES(...)は将来の列追加で壊れやすい。 - DEFAULT と NULL は別:集計や監査で意味が変わることがある。
- 日付/時刻は書式を明示:
TO_DATE/TO_TIMESTAMPを使う。 - 採番方法の混在は最小限:手動 ID と IDENTITY/SEQUENCE の併用は避ける。
- コミット間隔を設計:大量 INSERT で入れすぎても少なすぎても NG。
INSERT ... SELECT は別記事で詳しく
- 片方の表からもう片方へまとめて取り込むときに使う文です。
- データ量が多いときは 実行計画・索引・ロック が重要。実機例は別記事で扱います。
まとめ
- 列名を明示して安全に INSERT する。
- IDENTITY は簡単、SEQUENCE は自由度。要件で選ぶ。
RETURNINGで新 ID をすぐ取得できる。- 日付/時刻は書式を明示して暗黙変換を避ける。
- COMMIT/ROLLBACK で確実にコントロールする。
本記事は Oracle Database 19c を対象に解説します(他バージョンは画面や既定値が異なる場合があります)。
[参考]
INSERT




コメント