SQL INSERTステートメントは 、リレーショナル データベース内の任意の単一テーブルに 1 つ以上のレコードを追加します。
基本フォーム
挿入ステートメントの形式は次のとおりです。
テーブルにINSERT INTO (列1 [,列2 ,列3 ... ]) VALUES (値1 [,値2 ,値3 ... ])
列の数と値の数は同じである必要があります。列が指定されていない場合は、列のデフォルト値が使用されます。INSERT ステートメントによって指定される (または暗黙的に指定される) 値は、適用可能なすべての制約 (主キー、CHECK制約、NOT NULL制約など) を満たす必要があります。構文エラーが発生した場合、または制約に違反した場合、新しい行はテーブルに追加されず、代わりにエラーが返されます。
例:
phone_book (名前、番号)にVALUES ( 'John Doe' 、'555-1212' )を挿入します。
テーブル作成時の列の順序を利用して、ショートカットを使用することもできます。テーブル内のすべての列を指定する必要はありません。他の列はデフォルト値を取得するか、nullのままになります。
テーブルに INSERT INTO VALUES ( value1 , [ value2 , ... ])
phone_book テーブルの 2 つの列にデータを挿入し、テーブルの最初の 2 つの列の後にある他の列を無視する例。
電話帳に値( 'John Doe' 、'555-1212' ) を挿入します。
高度なフォーム
複数行の挿入
SQL 機能 ( SQL-92以降) は、行値コンストラクターを使用して、単一の SQL ステートメントで一度に複数の行を挿入することです。
INSERT INTO tablename (列- a 、[列- b 、...]) VALUES ( '値-1a' 、[ '値-1b' 、...])、( '値-2a' 、[ '値-2b' 、...])、...
この機能は、 IBM Db2、SQL Server(バージョン 10.0 以降、つまり 2008)、PostgreSQL(バージョン 8.2 以降)、MySQL、SQLite(バージョン 3.7.11 以降)、およびH2でサポートされています。
例 (「phone_book」テーブルには「name」と「number」の列のみがあると仮定):
phone_bookにVALUES ( 'John Doe' 、'555-1212' )、( 'Peter Doe' 、'555-2323' )を挿入します。
これは、次の2つの文を簡潔に表したものとみなすことができる。
電話帳に値( 'John Doe' 、'555-1212' )を挿入します。電話帳に値( ' Peter Doe' 、'555-2323' )を挿入します。
2 つの個別のステートメントはセマンティクスが異なる場合があり (特にステートメントトリガーに関して)、単一の複数行挿入と同じパフォーマンスが得られない可能性があることに注意してください。
MS SQL に複数の行を挿入するには、次のような構造を使用できます。
phone_bookにINSERT INTO SELECT 'John Doe' , '555-1212' UNION ALL SELECT 'Peter Doe' , '555-2323' ;
サブセレクト句が不完全なため、 これは SQL 標準 ( SQL:2003 ) に準拠した有効な SQL ステートメントではないことに注意してください。
Oracle で同じことを実行するには、常に 1 行のみで構成される DUAL テーブルを使用します。
電話帳にINSERT INTO 'John Doe' , '555-1212' FROM DUAL UNION ALL ' Peter Doe' , '555-2323' FROM DUAL を選択
このロジックの標準準拠の実装は、次の例、または上記のようになります。
電話帳にINSERT INTO 'John Doe' , '555-1212' FROM LATERAL ( VALUES ( 1 ) ) AS t ( c ) UNION ALL 'Peter Doe' , '555-2323' FROM LATERAL ( VALUES ( 1 ) ) AS t ( c )を選択
Oracle PL/SQLはINSERT ALL文をサポートしており、複数の挿入文はSELECTで終了する: [1]
すべてを電話帳に挿入します。VALUES ( 'John Doe' , '555-1212' )を電話帳に挿入します。VALUES ( 'Peter Doe' , '555-2323' )をDUALから*に選択します。
Firebirdでは、複数の行を挿入するには次のようにします。
電話帳にINSERT INTO (名前、番号) SELECT 'John Doe' , '555-1212' FROM RDB$DATABASE UNION ALL SELECT 'Peter Doe' , '555-2323' FROM RDB$DATABASE ;
ただし、Firebird では、単一のクエリで使用できるコンテキストの数に制限があるため、この方法で挿入できる行数が制限されます。
他のテーブルから行をコピーする
INSERTステートメントは、他のテーブルからデータを取得し、必要に応じて変更して、テーブルに直接挿入するためにも使用できます。これらすべては、クライアント アプリケーションでの中間処理を伴わない単一の SQL ステートメントで実行されます。VALUES 句の代わりにサブセレクトが使用されます。サブセレクトには結合、関数呼び出しを含めることができ、データが挿入される同じテーブルをクエリすることもできます。論理的には、実際の挿入操作が開始される前にセレクトが評価されます。以下に例を示します。
phone_book2にINSERT INTO SELECT * FROM phone_book WHERE name IN ( 'John Doe' , 'Peter Doe' )
ソース テーブルのデータの一部が新しいテーブルに挿入されるが、レコード全体が挿入されるわけではない場合は、バリエーションが必要です。(または、テーブルのスキーマが同じでない場合に必要です。)
phone_book2にINSERT INTO ( name , number ) name , number FROM phone_book WHERE name IN ( 'John Doe' , 'Peter Doe' )を指定します。
SELECTステートメントは(一時的な) テーブルを生成し、その一時テーブルのスキーマは、データが挿入されるテーブルのスキーマと一致する必要があります。
デフォルト値
すべての列にデフォルト値を使用して、データを指定せずに新しい行を挿入することができます。ただし、Microsoft SQL Server など、一部のデータベースでは、データが指定されていない場合にステートメントが拒否されるため、この場合はDEFAULTキーワードを使用できます。
電話帳の値に挿入(デフォルト)
データベースによっては、このための代替構文をサポートしている場合もあります。たとえば、MySQL ではDEFAULTキーワードを省略でき、T-SQL ではVALUES(DEFAULT)の代わりにDEFAULT VALUESを使用できます。DEFAULTキーワードは、通常の挿入でも使用でき、その列のデフォルト値を使用して列を明示的に埋めることができます。
電話帳に値を挿入します(デフォルト、'555-1212' )
列にデフォルト値が指定されていない場合に何が起こるかは、データベースによって異なります。たとえば、MySQL と SQLite では空白の値が入力されますが (厳密モードの場合を除く)、他の多くのデータベースではステートメントが拒否されます。
キーの取得
すべてのテーブルの主キーとして代理キーを使用するデータベース設計者は、他の SQL ステートメントで使用するために、SQL INSERTステートメントからデータベース生成の主キーを自動的に取得する必要があるシナリオに時々遭遇します。ほとんどのシステムでは、SQL INSERTステートメントで行データを返すことはできません。したがって、このようなシナリオでは回避策を実装する必要があります。一般的な実装は次のとおりです。
- 代理キーを生成し、INSERT操作を実行し、最後に生成されたキーを返すデータベース固有のストアド プロシージャを使用します。たとえば、Microsoft SQL Server では、キーはSCOPE_IDENTITY()特殊関数を介して取得されますが、SQLite では関数の名前はlast_insert_rowid()です。
- 最後に挿入された行を含む一時テーブルで
データベース固有のSELECTステートメントを使用します。Db2 は、この機能を次のように実装します。
SELECT * FROM NEW TABLE ( INSERT INTO phone_book VALUES ( 'Peter Doe' , '555-2323' ) ) AS t
- Db2 for z/OS は、この機能を次のように実装します。
最終テーブルからEMPNO 、HIRETYPE 、HIREDATE を選択し( EMPSAMP ( NAME 、SALARY 、DEPTNO 、LEVEL )にINSERT INTO EMPSAMP ( NAME、SALARY、 DEPTNO 、LEVEL ) VALUES ( 'Mary Smith' 、35000 . 00、11 、' Associate' ) )、
- 最後に挿入された行に対して生成された主キーを返すデータベース固有の関数を使用して、 INSERTステートメントの後にSELECTステートメントを使用します。たとえば、 MySQLのLAST_INSERT_ID()などです。
- 後続のSELECTステートメントで、元の SQL INSERTの要素の一意の組み合わせを使用します。
- SQL INSERTステートメントでGUID を使用し、SELECTステートメントでそれを取得します。
- MS-SQL Server 2005 および MS-SQL Server 2008 のSQL INSERTステートメントでOUTPUT句を使用する。
- OracleのRETURNING句を指定したINSERTステートメントを使用します。
phone_bookに値( 'Peter Doe' 、'555-2323' )を挿入し、 phone_book_id をv_pb_idに返します。
- PostgreSQL (8.2 以降)のRETURNING句を含むINSERTステートメントを使用します。返されるリストはINSERTの結果と同一です。
- Firebirdはデータ変更言語ステートメント(DSQL)で同じ構文を持ち、ステートメントは最大1行を追加できます。[2]ストアドプロシージャ、トリガー、実行ブロック(PSQL)では、前述のOracle構文が使用されます。[3]
phone_bookにVALUES ( 'Peter Doe' , '555-2323' )を挿入し、 phone_book_idを返す
- Firebirdはデータ変更言語ステートメント(DSQL)で同じ構文を持ち、ステートメントは最大1行を追加できます。[2]ストアドプロシージャ、トリガー、実行ブロック(PSQL)では、前述のOracle構文が使用されます。[3]
- H2でIDENTITY()関数を使用すると、最後に挿入された ID が返されます。
IDENTITY () を選択;
トリガー
INSERTステートメントが実行されるテーブルにトリガーが定義されている場合、それらのトリガーは操作のコンテキストで評価されます。BEFORE INSERTトリガーを使用すると、テーブルに挿入される値を変更できます。AFTER INSERTトリガーはデータを変更できなくなりますが、監査メカニズムを実装するなど、他のテーブルでアクションを開始するために使用できます。
参考文献
- ^ 「Oracle PL/SQL: INSERT ALL」。psoug.org。2010年9月16日時点のオリジナルよりアーカイブ。2010年9月2日閲覧。
- ^ 「Firebird 2.5 言語リファレンス アップデート」 。2011年 10 月 24 日閲覧。
- ^ 「Firebird SQL言語辞書」。
外部リンク
- Oracle SQL INSERT 文 (oracle.com の Oracle Database SQL 言語リファレンス、11g リリース 2 (11.2))
- Microsoft Access 追加クエリの例と SQL INSERT クエリ構文
- MySQL INSERT ステートメント (MySQL 5.5 リファレンス マニュアル)
