このページは機械翻訳したものです。
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_nameSET句は、各カラムに割り当てる値とともに、カラムを名前で明示的に指定します。
カラム値は、次のいくつかの方法で指定できます。
-
厳密な 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 ステートメント」を参照してください。