INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
[INTO] tbl_name
[PARTITION (partition_name,...)]
[(col_name,...)]
{VALUES | VALUE} ({expr | DEFAULT},...),(...),...
[ ON DUPLICATE KEY UPDATE
col_name=expr
[, col_name=expr] ... ]
または:
INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
[INTO] tbl_name
[PARTITION (partition_name,...)]
SET col_name={expr | DEFAULT}, ...
[ ON DUPLICATE KEY UPDATE
col_name=expr
[, col_name=expr] ... ]
または:
INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
[INTO] tbl_name
[PARTITION (partition_name,...)]
[(col_name,...)]
SELECT ...
[ ON DUPLICATE KEY UPDATE
col_name=expr
[, col_name=expr] ... ]
INSERT
は、既存のテーブルに新しい行を挿入します。このステートメントの INSERT ... VALUES
および INSERT ... SET
形式は、明示的に指定された値に基づいて行を挿入します。INSERT ... SELECT
形式は、別の 1 つまたは複数のテーブルから選択された行を挿入します。INSERT ... SELECT
については、セクション13.2.5.1「INSERT ... SELECT 構文」でさらに詳細に説明されています。
MySQL 5.6.2 以降では、パーティション化されたテーブルに挿入する場合、どのパーティションおよびサブパーティションが新しい行を受け入れるかを制御できます。PARTITION
オプションは、テーブルの 1 つ以上のパーティションまたはサブパーティション (またはその両方) の名前のカンマ区切りリストを受け取ります。特定の INSERT
ステートメントによって挿入される行がリストされているいずれかのパーティションに一致しない場合、INSERT
ステートメントは Found a row not matching the given partition set エラーで失敗します。詳細および例については、セクション19.5「パーティション選択」を参照してください。
古い行を上書きするには、INSERT
の代わりに REPLACE
を使用できます。REPLACE
は、古い行を複製する一意のキー値を含む新しい行の処理において INSERT IGNORE
に相当するものです。新しい行は、破棄されるのではなく、古い行を置き換えるために使用されます。セクション13.2.8「REPLACE 構文」を参照してください。
tbl_name
は、行が挿入されるテーブルです。このステートメントによって値が提供されるカラムは、次のように指定できます。
テーブル名のあとにカラム名のカンマ区切りリストを指定できます。この場合は、指定された各カラムの値を
VALUES
リストまたはSELECT
ステートメントで指定する必要があります。INSERT ... VALUES
またはINSERT ... SELECT
にカラム名のリストを指定しない場合は、テーブル内のすべてのカラムの値をVALUES
リストまたはSELECT
ステートメントで指定する必要があります。テーブル内のカラムの順序がわからない場合は、DESCRIBE
を使用して見つけます。tbl_name
SET
句は、カラム名を明示的に示します。
カラム値は、次のいくつかの方法で指定できます。
-
厳密な SQL モードで実行していない場合、値が明示的に指定されていないカラムはすべて、デフォルトの (明示的または暗黙的な) 値に設定されます。たとえば、テーブル内のすべてのカラムを指定していないカラムリストを指定した場合、指定されていないカラムはそのデフォルト値に設定されます。デフォルト値の割り当てについては、セクション11.6「データ型デフォルト値」で説明されています。セクション1.7.3.3「無効データの制約」も参照してください。
デフォルト値が含まれていないすべてのカラムの値を明示的に指定しないかぎり、
INSERT
ステートメントでエラーが生成されるようにする場合は、厳密モードを使用するようにしてください。セクション5.1.7「サーバー SQL モード」を参照してください。 -
カラムを明示的にそのデフォルト値に設定するには、キーワード
DEFAULT
を使用します。これにより、テーブル内の各カラムの値が含まれていない不完全なVALUES
リストを書かなくても済むため、いくつかのカラムを除くすべてのカラムに値を割り当てるINSERT
ステートメントの記述が容易になります。そうでない場合は、VALUES
リスト内の各値に対応するカラム名のリストを書き出す必要があります。また、特定のカラムのデフォルト値を生成する式で使用できるより一般的な形式として
DEFAULT(
を使用することもできます。col_name
) -
カラムリストと
VALUES
リストの両方が空である場合、INSERT
は、各カラムがそのデフォルト値に設定された行を作成します。INSERT INTO tbl_name () VALUES();
厳密モードでは、いずれかのカラムにデフォルト値が含まれていない場合、エラーが発生します。それ以外の場合、MySQL は、明示的に定義されたデフォルト値が含まれていないすべてのカラムに対して暗黙のデフォルト値を使用します。
-
式
expr
を指定して、カラム値を指定できます。これには、式の型がカラムの型に一致しない場合は型変換が行われる可能性があり、特定の値の変換によって、データ型に応じて異なる値が挿入されることがあります。たとえば、文字列'1999.0e-2'
をINT
、FLOAT
、DECIMAL(10,6)
、またはYEAR
カラムに挿入すると、それぞれ、値1999
、19.9921
、19.992100
、および1999
が挿入されます。INT
およびYEAR
カラムに格納される値が1999
である理由は、文字列から整数への変換では、その文字列の最初の、有効な整数または年と見なすことができる部分だけが調べられるためです。浮動小数点および固定小数点数カラムの場合、文字列から浮動小数点への変換では、文字列全体を有効な浮動小数点値と見なします。式
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);
1 つの例外として、
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);
各行の値リストは、括弧で囲まれている必要があります。次のステートメントは、リスト内の値の数がカラム名の数に一致しないため不正です。
INSERT INTO tbl_name (a,b,c) VALUES(1,2,3,4,5,6,7,8,9);
このコンテキストでは、VALUE
は VALUES
のシノニムです。どちらも、値リストの数については何も示しておらず、値リストが 1 つの場合でも複数の場合でも使用できます。
INSERT
に関して影響を受けた行の値は、ROW_COUNT()
関数 (セクション12.14「情報関数」を参照してください) または mysql_affected_rows()
C API 関数 (セクション23.7.7.1「mysql_affected_rows()」を参照してください) を使用して取得できます。
INSERT ... VALUES
ステートメントを複数の値リストまたは INSERT ... SELECT
とともに使用した場合、このステートメントは、次の形式の情報文字列を返します。
Records: 100 Duplicates: 0 Warnings: 0
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 の値に設定されます。
C API を使用している場合は、mysql_info()
関数を呼び出すことによって情報文字列を取得できます。セクション23.7.7.35「mysql_info()」を参照してください。
INSERT
で AUTO_INCREMENT
カラムを含むテーブルに行を挿入した場合、そのカラムに使用された値は SQL の LAST_INSERT_ID()
関数を使用して検索できます。C API 内からは、mysql_insert_id()
関数を使用します。
これらの 2 つの関数が、必ずしも同じ動作を行うとは限りません。AUTO_INCREMENT
カラムに関連した INSERT
ステートメントの動作については、セクション12.14「情報関数」およびセクション23.7.7.37「mysql_insert_id()」でさらに詳細に説明されています。
INSERT
ステートメントは、次の修飾子をサポートします。
-
DELAYED
キーワードを使用した場合は、挿入される 1 つまたは複数の行をサーバーがバッファーに配置するため、INSERT DELAYED
ステートメントを発行しているクライアントはただちに続行できます。そのテーブルが使用中である場合、サーバーはそれらの行を保持します。そのテーブルが未使用である場合、サーバーは行の挿入を開始する一方、そのテーブルに対する新しい読み取り要求が存在するかどうかを定期的にチェックします。存在する場合は、そのテーブルがふたたび未使用になるまで、遅延された行のキューは中断されます。セクション13.2.5.2「INSERT DELAYED 構文」を参照してください。DELAYED
は、INSERT ... SELECT
またはINSERT ... ON DUPLICATE KEY UPDATE
では無視されます。DELAYED
はまた、テーブルやトリガーにアクセスする関数を使用しているか、または関数やトリガーから呼び出されたINSERT
でも無視されます。注記MySQL 5.6.6 現在、
INSERT DELAYED
は非推奨であり、将来のリリースで削除されます。代わりにINSERT
(DELAYED
を付けない) を使用してください。 -
LOW_PRIORITY
キーワードを使用した場合、INSERT
の実行は、ほかのどのクライアントもそのテーブルから読み取らなくなるまで遅延されます。これには、既存のクライアントが読み取っている間や、INSERT LOW_PRIORITY
ステートメントが待機している間に読み取りを開始したほかのクライアントが含まれます。そのため、読み取り負荷の高い環境では、INSERT LOW_PRIORITY
ステートメントを発行したクライアントが非常に長い時間 (場合によっては無期限に) 待機することになるおそれがあります。(これは、クライアントをただちに続行できるようにするINSERT DELAYED
とは対照的です。)MyISAM
テーブルでLOW_PRIORITY
を使用すると、並列挿入が無効になるため、通常はこれを行わないようにしてください。セクション8.10.3「同時挿入」を参照してください。HIGH_PRIORITY
を指定すると、サーバーが--low-priority-updates
オプションで起動されている場合に、その効果がオーバーライドされます。また、同時挿入も使用されなくなります。セクション8.10.3「同時挿入」を参照してください。LOW_PRIORITY
とHIGH_PRIORITY
は、テーブルレベルのロックのみを使用するストレージエンジン (MyISAM
、MEMORY
、MERGE
など) にのみ影響を与えます。 -
IGNORE
キーワードを使用した場合、INSERT
ステートメントの実行中に発生したエラーは無視されます。たとえば、IGNORE
を使用しない場合は、テーブル内の既存のUNIQUE
インデックスまたはPRIMARY KEY
値を複製する行によって重複キーエラーが発生し、このステートメントは中止されます。IGNORE
を指定すると、その行が破棄され、エラーは発生しません。代わりに、無視されたエラーが警告を生成する可能性がありますが、重複キーエラーは生成しません。IGNORE
には、特定の値に一致するパーティションが見つからないパーティション化されたテーブルへの挿入でも同様の効果があります。IGNORE
を指定しない場合、このようなINSERT
ステートメントはエラーで中止されます。ただし、INSERT IGNORE
が使用されている場合は、一致しない値を含む行に対する挿入操作が暗黙のうちに失敗しますが、一致した行はすべて挿入されます。例については、セクション19.2.2「LIST パーティショニング」を参照してください。IGNORE
が指定されていない場合は、エラーをトリガーするデータ変換によってステートメントが中止されます。IGNORE
を指定すると、無効な値はもっとも近い値に調整されて挿入されます。警告は生成されますが、ステートメントは中止されません。mysql_info()
C API 関数を使用すると、テーブルに実際に挿入された行数を確認できます。 ON DUPLICATE KEY UPDATE
を指定したとき、UNIQUE
インデックスまたはPRIMARY KEY
に重複した値を発生させる行が挿入された場合は、古い行のUPDATE
が実行されます。行ごとの影響を受けた行の値は、その行が新しい行として挿入された場合は 1、既存の行が更新された場合は 2、既存の行がその現在の値に設定された場合は 0 です。mysqld への接続時にCLIENT_FOUND_ROWS
フラグをmysql_real_connect()
に指定すると、既存の行がその現在の値に設定された場合の影響を受けた行の値は (0 ではなく) 1 になります。セクション13.2.5.3「INSERT ... ON DUPLICATE KEY UPDATE 構文」を参照してください。
テーブルに挿入するには、そのテーブルに対する INSERT
権限が必要です。ON DUPLICATE KEY UPDATE
句が使用されていて、重複キーのために代わりに UPDATE
が実行される場合、このステートメントには、更新されるカラムに対する UPDATE
権限が必要です。読み取られるが、変更されないカラムの場合は、SELECT
権限のみが必要です (ON DUPLICATE KEY UPDATE
句にある col_name
=expr
割り当ての右側でのみ参照されるカラムの場合など)。
MySQL 5.6.6 より前は、テーブルレベルのロックを採用した MyISAM
などのストレージエンジンを使用しているパーティション化されたテーブルに影響を与える INSERT
によって、そのテーブルのすべてのパーティションがロックされました。これは、INSERT ... PARTITION
ステートメントにも当てはまりました。(これは、行レベルロックを採用した InnoDB
などのストレージエンジンでは発生しておらず、現在も発生しません。)MySQL 5.6.6 以降では、MySQL はパーティションロックプルーニングを使用します。これにより、行が挿入されるパーティションだけが実際にロックされるようになります。詳細は、セクション19.6.4「パーティショニングとロック」を参照してください。