Documentation Home
MySQL 5.6 リファレンスマニュアル
Download this Manual
PDF (US Ltr) - 26.8Mb
PDF (A4) - 26.9Mb
HTML Download (TGZ) - 7.2Mb
HTML Download (Zip) - 7.2Mb


13.2.11 UPDATE 構文

単一テーブル構文:

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_referenceswhere_condition は、セクション13.2.9「SELECT 構文」で説明されているように指定されます。

実際に更新された、UPDATE 内で参照されているカラムに対してのみ UPDATE 権限が必要です。読み取られるが、変更されないカラムに対しては、SELECT 権限のみが必要です。

UPDATE ステートメントは、次の修飾子をサポートします。

  • LOW_PRIORITY キーワードを使用すると、UPDATE の実行は、ほかのどのクライアントもそのテーブルから読み取らなくなるまで遅延されます。これは、テーブルレベルロックのみを使用するストレージエンジン (MyISAMMEMORY、および 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 値に設定します。この結果、col1col2 の値が同じになります。この動作は標準 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「パーティショニングとロック」を参照してください。