INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
[INTO] tbl_name
[PARTITION (partition_name [, partition_name] ...)]
[(col_name [, col_name] ...)]
{ {VALUES | VALUE} (value_list) [, (value_list)] ...
|
VALUES row_constructor_list
}
[AS row_alias[(col_alias [, col_alias] ...)]]
[ON DUPLICATE KEY UPDATE assignment_list]
INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
[INTO] tbl_name
[PARTITION (partition_name [, partition_name] ...)]
[AS row_alias[(col_alias [, col_alias] ...)]]
SET assignment_list
[ON DUPLICATE KEY UPDATE assignment_list]
INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
[INTO] tbl_name
[PARTITION (partition_name [, partition_name] ...)]
[(col_name [, col_name] ...)]
[AS row_alias[(col_alias [, col_alias] ...)]]
{SELECT ... | TABLE table_name}
[ON DUPLICATE KEY UPDATE assignment_list]
value:
{expr | DEFAULT}
value_list:
value [, value] ...
row_constructor_list:
ROW(value_list)[, ROW(value_list)][, ...]
assignment:
col_name = [row_alias.]value
assignment_list:
assignment [, assignment] ...
INSERT
は、既存のテーブルに新しい行を挿入します。 INSERT ... VALUES
、INSERT ... VALUES ROW()
および INSERT ... SET
形式のステートメントは、明示的に指定された値に基づいて行を挿入します。 INSERT ... SELECT
形式は、別の 1 つまたは複数のテーブルから選択された行を挿入します。 MySQL 8.0.19 以降で INSERT ... TABLE
を使用して、単一のテーブルから行を挿入することもできます。 INSERT
で ON DUPLICATE KEY UPDATE
句を使用すると、行が挿入されて UNIQUE
インデックスまたは PRIMARY KEY
で値が重複する場合に、既存の行を更新できます。 MySQL 8.0.19 以降では、1 つ以上のオプションのカラムアライスを持つ行エイリアスを ON DUPLICATE KEY UPDATE
で使用して、挿入する行を参照できます。
INSERT ... SELECT
および INSERT ... ON DUPLICATE KEY UPDATE
の詳細は、セクション13.2.6.1「INSERT ... SELECT ステートメント」 および セクション13.2.6.2「INSERT ... ON DUPLICATE KEY UPDATE ステートメント」 を参照してください。
MySQL 8.0 では、DELAYED
キーワードは受け入れられますが、サーバーでは無視されます。 この理由については、セクション13.2.6.3「INSERT DELAYED ステートメント」 を参照してください。
テーブルに挿入するには、そのテーブルに対する INSERT
権限が必要です。 ON DUPLICATE KEY UPDATE
句が使用されていて、重複キーのために代わりに UPDATE
が実行される場合、このステートメントには、更新されるカラムに対する UPDATE
権限が必要です。 読み取られるが、変更されないカラムの場合は、SELECT
権限のみが必要です (ON DUPLICATE KEY UPDATE
句にある col_name
=expr
割り当ての右側でのみ参照されるカラムの場合など)。
パーティションテーブルに挿入する場合、新しい行を受け入れるパーティションおよびサブパーティションを制御できます。 PARTITION
オプションは、テーブルのパーティションまたはサブパーティション (あるいはその両方) のカンマ区切りの名前のリストを取ります。 特定の INSERT
ステートメントによって挿入される行がリストされているいずれかのパーティションに一致しない場合、INSERT
ステートメントはFound a row not matching the given partition setエラーで失敗します。 詳細および例については、セクション24.5「パーティション選択」を参照してください。
tbl_name
は、行が挿入されるテーブルです。 ステートメントが値を提供するカラムを次のように指定します:
テーブル名の後にカンマ区切りのカラム名のカッコ付きリストを指定します。 この場合、各名前付きカラムの値は、
VALUES
リスト、VALUES ROW()
リストまたはSELECT
ステートメントで指定する必要があります。INSERT TABLE
フォームの場合、ソーステーブルのカラム数は挿入されるカラム数と一致する必要があります。INSERT ... VALUES
またはINSERT ... SELECT
のカラム名のリストを指定しない場合は、テーブル内のすべてのカラムの値をVALUES
リスト、SELECT
ステートメントまたはTABLE
ステートメントで指定する必要があります。 テーブル内のカラムの順序がわからない場合は、DESCRIBE
を使用して見つけます。tbl_name
SET
句は、各カラムに割り当てる値とともに、カラムを名前で明示的に指定します。
カラム値は、次のいくつかの方法で指定できます。
-
厳密な SQL モードが有効になっていない場合、値が明示的に指定されていないカラムはデフォルト (明示的または暗黙的) 値に設定されます。 たとえば、テーブル内のすべてのカラムを指定していないカラムリストを指定した場合、指定されていないカラムはそのデフォルト値に設定されます。 デフォルト値の割り当てについては、セクション11.6「データ型デフォルト値」で説明されています。 セクション1.7.3.3「無効なデータに対する制約の施行」も参照してください。
厳密な SQL モードが有効になっている場合、デフォルト値を持たないすべてのカラムに明示的な値が指定されていないと、
INSERT
ステートメントはエラーを生成します。 セクション5.1.11「サーバー SQL モード」を参照してください。 -
カラムリストと
VALUES
リストの両方が空である場合、INSERT
は、各カラムがそのデフォルト値に設定された行を作成します。INSERT INTO tbl_name () VALUES();
厳密モードが有効になっていない場合、MySQL では、デフォルトが明示的に定義されていないカラムに暗黙的なデフォルト値が使用されます。 厳密モードが有効な場合、いずれかのカラムにデフォルト値がないとエラーが発生します。
カラムを明示的にそのデフォルト値に設定するには、キーワード
DEFAULT
を使用します。 これにより、テーブル内の各カラムの値が含まれていない不完全なVALUES
リストを書かなくても済むため、いくつかのカラムを除くすべてのカラムに値を割り当てるINSERT
ステートメントの記述が容易になります。 それ以外の場合は、VALUES
リストの各値に対応するカラム名のリストを指定する必要があります。-
生成されたカラムが明示的ににに挿入される場合、許可される値は
DEFAULT
のみです。 生成されるカラムの詳細は、セクション13.1.20.8「CREATE TABLE および生成されるカラム」 を参照してください。 式では、
DEFAULT(
を使用してカラムcol_name
)col_name
のデフォルト値を生成できます。カラム値を提供する式
expr
の型変換は、式のデータ型がカラムのデータ型と一致しない場合に発生することがあります。 特定の値を変換すると、カラムタイプに応じて異なる値が挿入される可能性があります。 たとえば、文字列'1999.0e-2'
をINT
,FLOAT
,DECIMAL(10,6)
に挿入したり、YEAR
カラムを挿入すると、値1999
,19.9921
,19.992100
または1999
がそれぞれ挿入されます。 文字列から数値への変換では、文字列の初期部分のみが有効な整数または年とみなされる可能性があるため、INT
およびYEAR
カラムに格納される値は1999
です。FLOAT
およびDECIMAL
カラムの場合、文字列から数値への変換では、文字列全体が有効な数値とみなされます。-
式
expr
は、以前に値リスト内に設定された任意のカラムを参照できます。 たとえば、次のステートメントは、col2
の値が、前に割り当てられているcol1
を参照しているため実行可能です。INSERT INTO tbl_name (col1,col2) VALUES(15,col1*2);
ただし、次のステートメントは、
col1
の値が、col1
のあとに割り当てられているcol2
を参照しているため正当ではありません。INSERT INTO tbl_name (col1,col2) VALUES(col2*2,15);
AUTO_INCREMENT
値を含むカラムに対して例外が発生します。AUTO_INCREMENT
値は他の値の割当て後に生成されるため、割当て内のAUTO_INCREMENT
カラムへの参照はすべて0
を返します。
VALUES
構文を使用する INSERT
ステートメントは複数の行を挿入できます。 これを行うには、カンマで区切られたカラム値の複数のリストをカッコで囲み、カンマで区切って含めます。 例:
INSERT INTO tbl_name (a,b,c)
VALUES(1,2,3), (4,5,6), (7,8,9);
各値リストには、行ごとに挿入されるのと同じ数の値が含まれている必要があります。 次のステートメントは、それぞれ 3 つの値のリストではなく、9 つの値のリストが 1 つ含まれているため、無効です:
INSERT INTO tbl_name (a,b,c) VALUES(1,2,3,4,5,6,7,8,9);
このコンテキストでは、VALUE
は VALUES
のシノニムです。 値リストの数やリスト当たりの値の数については何も意味しません。 リストごとの値の数に関係なく、単一の値リストまたは複数のリストのいずれかを使用できます。
VALUES ROW()
構文を使用する INSERT
ステートメントでは、複数の行を挿入することもできます。 この場合、各値リストは、次のように ROW()
(行コンストラクタ) 内に含まれている必要があります:
INSERT INTO tbl_name (a,b,c)
VALUES ROW(1,2,3), ROW(4,5,6), ROW(7,8,9);
INSERT
の影響を受ける行の値は、ROW_COUNT()
SQL 関数または mysql_affected_rows()
C API 関数を使用して取得できます。 セクション12.16「情報関数」およびmysql_affected_rows()を参照してください。
複数の値リスト、INSERT ... SELECT
または INSERT ... TABLE
で INSERT ... VALUES
または INSERT ... VALUES ROW()
を使用する場合、このステートメントは次の形式で情報文字列を返します:
Records: N1 Duplicates: N2 Warnings: N3
C API を使用している場合は、mysql_info()
関数を呼び出すことによって情報文字列を取得できます。 mysql_info()を参照してください。
Records
は、このステートメントによって処理された行数を示します。 (これは、Duplicates
が 0 以外であることがあるため、必ずしも実際に挿入された行数ではありません。) Duplicates
は、何らかの既存の一意のインデックス値を複製しているために挿入できなかった行数を示します。 Warnings
は、何らかの点で問題があったカラム値を挿入するための試行回数を示します。 警告は、次のいずれかの条件で発生する場合があります。
NOT NULL
として宣言されているカラムへのNULL
の挿入。 複数行のINSERT
ステートメントまたはINSERT INTO ... SELECT
ステートメントの場合、このカラムは、そのカラムデータ型の暗黙のデフォルト値に設定されます。 これは、数値型では0
、文字列型では空の文字列 (''
)、および日付と時間型では「0」の値です。 サーバーはSELECT
からの結果セットを検査して、それが単一行を返すかどうかを確認しないため、INSERT INTO ... SELECT
ステートメントは複数行の挿入と同じ方法で処理されます。 (単一行のINSERT
の場合は、NULL
がNOT NULL
カラムに挿入されても警告は発生しません。 代わりに、このステートメントがエラーで失敗します。)数値カラムの、そのカラムの範囲外にある値への設定。 この値は、その範囲のもっとも近い端点にクリップされます。
数値カラムへの
'10.34 a'
などの値の割り当て。 後続の非数値のテキストは取り除かれ、残りの数値部分が挿入されます。 文字列値に先頭の数値部分が含まれていない場合、このカラムは0
に設定されます。文字列カラム (
CHAR
、VARCHAR
、TEXT
、またはBLOB
) への、そのカラムの最大長を超える文字列の挿入。 この値は、そのカラムの最大長に切り捨てられます。日付または時間カラムへの、そのデータ型として不正な値の挿入。 このカラムは、その型の適切な 0 の値に設定されます。
-
AUTO_INCREMENT
のカラム値を含むINSERT
の例は、セクション3.6.9「AUTO_INCREMENT の使用」 を参照してください。INSERT
がAUTO_INCREMENT
カラムを含むテーブルに行を挿入する場合は、LAST_INSERT_ID()
SQL 関数またはmysql_insert_id()
C API 関数を使用して、そのカラムに使用される値を検索できます。注記これらの 2 つの関数が、必ずしも同じ動作を行うとは限りません。
AUTO_INCREMENT
カラムに関連したINSERT
ステートメントの動作については、セクション12.16「情報関数」およびmysql_insert_id()でさらに詳細に説明されています。
INSERT
ステートメントは、次の修飾子をサポートします。
-
LOW_PRIORITY
修飾子を使用すると、ほかのクライアントがテーブルから読み取ることがなくなるまで、INSERT
の実行が遅延されます。 これには、既存のクライアントが読み取っている間や、INSERT LOW_PRIORITY
ステートメントが待機している間に読み取りを開始したほかのクライアントが含まれます。 したがって、INSERT LOW_PRIORITY
ステートメントを発行するクライアントが非常に長い時間待機する可能性があります。LOW_PRIORITY
は、テーブルレベルロック (MyISAM
、MEMORY
、MERGE
など) のみを使用するストレージエンジンにのみ影響します。注記同時挿入が無効になるため、
LOW_PRIORITY
は通常、MyISAM
テーブルでは使用しないでください。 セクション8.11.3「同時挿入」を参照してください。 -
HIGH_PRIORITY
を指定すると、サーバーが--low-priority-updates
オプションで起動されている場合に、その効果がオーバーライドされます。 また、同時挿入も使用されなくなります。 セクション8.11.3「同時挿入」を参照してください。HIGH_PRIORITY
は、テーブルレベルロック (MyISAM
、MEMORY
、MERGE
など) のみを使用するストレージエンジンにのみ影響します。 -
IGNORE
修飾子を使用すると、INSERT
ステートメントの実行中に発生する無視可能なエラーは無視されます。 たとえば、IGNORE
を使用しない場合は、テーブル内の既存のUNIQUE
インデックスまたはPRIMARY KEY
値を複製する行によって重複キーエラーが発生し、このステートメントは中止されます。IGNORE
を指定すると、その行が破棄され、エラーは発生しません。 無視されたエラーでは、かわりに警告が生成されます。IGNORE
には、特定の値に一致するパーティションが見つからないパーティション化されたテーブルへの挿入でも同様の効果があります。IGNORE
がない場合、このようなINSERT
ステートメントはエラーで中断されます。INSERT IGNORE
を使用すると、一致しない値を含む行に対しては挿入操作が暗黙的に失敗しますが、一致する行は挿入されます。 例については、セクション24.2.2「LIST パーティショニング」を参照してください。IGNORE
が指定されていない場合は、エラーをトリガーするデータ変換によってステートメントが中止されます。IGNORE
を指定すると、無効な値はもっとも近い値に調整されて挿入されます。警告は生成されますが、ステートメントは中止されません。mysql_info()
C API 関数を使用すると、テーブルに実際に挿入された行数を確認できます。詳細は、IGNORE がステートメントの実行に与える影響を参照してください。
古い行を上書きするには、
INSERT
の代わりにREPLACE
を使用できます。REPLACE
は、古い行を複製する一意のキー値を含む新しい行の処理におけるINSERT IGNORE
の対応する機能です: 新しい行は、破棄されるのではなく、古い行を置き換えます。 セクション13.2.9「REPLACE ステートメント」を参照してください。 -
ON DUPLICATE KEY UPDATE
を指定し、UNIQUE
インデックスまたはPRIMARY KEY
で値が重複する原因となる行を挿入すると、古い行のUPDATE
が発生します。 行ごとの影響を受けた行の値は、その行が新しい行として挿入された場合は 1、既存の行が更新された場合は 2、既存の行がその現在の値に設定された場合は 0 です。 mysqld への接続時にmysql_real_connect()
C API 関数にCLIENT_FOUND_ROWS
フラグを指定すると、既存の行が現在の値に設定されている場合、影響を受ける行の値は 1 (0 ではなく) になります。 セクション13.2.6.2「INSERT ... ON DUPLICATE KEY UPDATE ステートメント」を参照してください。 -
INSERT DELAYED
は MySQL 5.6 で非推奨となり、最終的な削除がスケジュールされています。 MySQL 8.0 では、DELAYED
修飾子は受け入れられますが無視されます。 代わりにINSERT
(DELAYED
を付けない) を使用してください。 セクション13.2.6.3「INSERT DELAYED ステートメント」を参照してください。