単一テーブル構文:
UPDATE [LOW_PRIORITY] [IGNORE] table_reference
SET col_name1={expr1|DEFAULT} [, col_name2={expr2|DEFAULT}] ...
[WHERE where_condition]
[ORDER BY ...]
[LIMIT row_count]
複数テーブル構文:
UPDATE [LOW_PRIORITY] [IGNORE] table_references
SET col_name1={expr1|DEFAULT} [, col_name2={expr2|DEFAULT}] ...
[WHERE where_condition]
単一テーブル構文の場合、UPDATE
ステートメントは、指定されたテーブル内の既存の行のカラムを新しい値に更新します。SET
句は、変更するカラムと、それらのカラムに指定される値を示します。各値は式か、またはカラムを明示的にそのデフォルト値に設定するキーワード DEFAULT
として指定できます。WHERE
句 (指定されている場合) は、どの行を更新するかを識別する条件を指定します。WHERE
句がない場合は、すべての行が更新されます。ORDER BY
句が指定されている場合は、指定されている順序で行が更新されます。LIMIT
句は、更新できる行数に制限を設定します。
複数テーブル構文の場合、UPDATE
は、条件を満たす table_references
で指定されている各テーブル内の行を更新します。一致した各行は、条件に複数回一致した場合でも、1 回更新されます。複数テーブル構文の場合は、ORDER BY
および LIMIT
を使用できません。
パーティション化されたテーブルの場合は、このステートメントの単一テーブルと複数テーブルの両方の形式で、テーブル参照の一部としての PARTITION
オプションの使用がサポートされます。このオプションは、1 つ以上のパーティションまたはサブパーティション (またはその両方) のリストを受け取ります。リストされているパーティション (またはサブパーティション) だけが一致をチェックされ、これらのパーティションまたはサブパーティションのいずれにも存在しない行は、where_condition
を満たすかどうかにかかわらず更新されません。
INSERT
または REPLACE
ステートメントで PARTITION
を使用している場合とは異なり、それ以外は有効な UPDATE ... PARTITION
ステートメントは、リストされているパーティション (またはサブパーティション) 内のどの行も where_condition
に一致しない場合でも成功したと見なされます。
詳細および例については、セクション19.5「パーティション選択」を参照してください。
where_condition
は、更新される各行に対して true に評価される式です。式の構文については、セクション9.5「式の構文」を参照してください。
table_references
と where_condition
は、セクション13.2.9「SELECT 構文」で説明されているように指定されます。
実際に更新された、UPDATE
内で参照されているカラムに対してのみ UPDATE
権限が必要です。読み取られるが、変更されないカラムに対しては、SELECT
権限のみが必要です。
UPDATE
ステートメントは、次の修飾子をサポートします。
LOW_PRIORITY
キーワードを使用すると、UPDATE
の実行は、ほかのどのクライアントもそのテーブルから読み取らなくなるまで遅延されます。これは、テーブルレベルロックのみを使用するストレージエンジン (MyISAM
、MEMORY
、およびMERGE
) にのみ影響を与えます。IGNORE
キーワードを指定すると、更新中にエラーが発生した場合でも、更新ステートメントは中止されません。一意のキー値に関して重複キーの競合が発生した行は更新されません。データ変換エラーの原因になる値に更新された行は、代わりに、もっとも近い有効な値に更新されます。
MySQL 5.6.4 以降では、UPDATE IGNORE
ステートメント (ORDER BY
句が存在するものを含む)、には、ステートメントベースのレプリケーションには安全でないというフラグが付けられます。(これは、どの行が無視されるかが、行が更新される順序によって決定されるためです。)この変更により、このようなステートメントは、ステートメントベースモードを使用しているときはログ内に警告を生成し、MIXED
モードを使用しているときは行ベース形式を使用してログに記録されます。(Bug #11758262、Bug #50439) 詳細は、セクション17.1.2.3「バイナリロギングでの安全および安全でないステートメントの判断」を参照してください。
式で更新されるテーブルのカラムにアクセスする場合、UPDATE
はそのカラムの現在の値を使用します。たとえば、次のステートメントは、col1
をその現在の値より 1 大きい値に設定します。
UPDATE t1 SET col1 = col1 + 1;
次のステートメントの 2 番目の割り当ては、col2
を元の col1
値ではなく、現在の (更新された) col1
値に設定します。この結果、col1
と col2
の値が同じになります。この動作は標準 SQL とは異なります。
UPDATE t1 SET col1 = col1 + 1, col2 = col1;
単一テーブルの UPDATE
の割り当ては一般に、左から右に評価されます。複数テーブルの更新では、割り当てが特定の順序で実行される保証はありません。
カラムをその現在の値に設定した場合は、MySQL がこれに気付き、その更新を行いません。
NOT NULL
として宣言されているカラムを NULL
に設定することによって更新すると、厳密な SQL モードが有効になっている場合は、エラーが発生します。そうでない場合、カラムはそのカラムデータ型の暗黙のデフォルト値に設定され、警告数が 1 増やされます。暗黙のデフォルト値は、数値型では 0
、文字列型では空の文字列 (''
)、および日付と時間型では「0」の値です。セクション11.6「データ型デフォルト値」を参照してください。
UPDATE
は、実際に変更された行数を返します。mysql_info()
C API 関数は、一致して更新された行数と、UPDATE
中に発生した警告の数を返します。
LIMIT
を使用すると、row_count
UPDATE
のスコープを制限できます。LIMIT
句は、一致した行の制限です。このステートメントは、実際に変更されたかどうかにかかわらず、WHERE
句を満たす row_count
行を見つけるとすぐに停止します。
UPDATE
ステートメントに ORDER BY
句が含まれている場合は、この句で指定されている順序で行が更新されます。これは、通常であればエラーが発生する可能性のある特定の状況で役立つ場合があります。テーブル t
に、一意のインデックスを持つカラム id
が含まれているとします。次のステートメントは、行が更新される順序によっては、重複キーエラーで失敗する可能性があります。
UPDATE t SET id = id + 1;
たとえば、このテーブルの id
カラムに 1 と 2 が含まれており、2 が 3 に更新される前に 1 が 2 に更新された場合は、エラーが発生します。この問題を回避するには、大きな id
値を持つ行が小さな値を持つ行の前に更新されるように、ORDER BY
句を追加します。
UPDATE t SET id = id + 1 ORDER BY id DESC;
また、複数のテーブルを範囲に含む UPDATE
操作を実行することもできます。ただし、複数テーブルの UPDATE
では ORDER BY
または LIMIT
を使用できません。table_references
句は、結合に含まれるテーブルをリストします。その構文については、セクション13.2.9.2「JOIN 構文」で説明されています。次に例を示します。
UPDATE items,month SET items.price=month.price
WHERE items.id=month.id;
前の例は、カンマ演算子を使用する内部結合を示していますが、複数テーブルの UPDATE
ステートメントは、SELECT
ステートメント内で許可されている任意の型の結合 (LEFT JOIN
など) を使用できます。
外部キー制約が存在する InnoDB
テーブルを含む、複数テーブルの UPDATE
ステートメントを使用した場合は、MySQL オプティマイザが、それらの親子関係の順序とは異なる順序でテーブルを処理する可能性があります。この場合、このステートメントは失敗し、ロールバックされます。代わりに、1 つのテーブルを更新したあと、InnoDB
が提供する ON UPDATE
機能を使用して、ほかのテーブルがそれに応じて変更されるようにします。セクション14.6.6「InnoDB と FOREIGN KEY 制約」を参照してください。
現在、テーブルを更新し、さらにサブクエリーで同じテーブルから選択することはできません。
MySQL 5.6.6 より前は、テーブルレベルのロックを採用した MyISAM
などのストレージエンジンを使用しているパーティション化されたテーブルに対する UPDATE
によって、そのテーブルのすべてのパーティションがロックされました。これは、UPDATE ... PARTITION
クエリーにも当てはまりました。(これは、行レベルロックを採用した InnoDB
などのストレージエンジンでは発生しておらず、現在も発生しません。)MySQL 5.6.6 以降では、MySQL はパーティションロックプルーニングを使用します。これにより、そのテーブルのいずれかのパーティション化カラムが更新されないかぎり、UPDATE
ステートメントの WHERE
句に一致する行を含むパーティションだけが実際にロックされるようになります。詳細は、セクション19.6.4「パーティショニングとロック」を参照してください。