Documentation Home
MySQL 5.6 リファレンスマニュアル
Download this Manual
PDF (US Ltr) - 26.8Mb
PDF (A4) - 26.9Mb
HTML Download (TGZ) - 7.1Mb
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「パーティショニングとロック」を参照してください。


User Comments
User comments in this section are, as the name implies, provided by MySQL users. The MySQL documentation team is not responsible for, nor do they endorse, any of the information provided here.
  Posted by Misha B on April 21, 2011
Change values between two and more columns. In result, ufter update, columns will have values from after columns
column1 = column2, column2 = column1

UPDATE
table1
SET
column1 = (@v := column1), column1 = column2, column2 = @v;
  Posted by Ajmer Phull on February 2, 2012
Hopefully this will be useful to someone else, like it was for me when I had to perform data cleansing and enhancing badly designed databases. This can also be helpful for replacing data in fields with ID's when normalising databases.

The following will update a field (field9 which is empty) in TABLE1 with data from a field (field9) in TABLE3 using joins with TABLE2 and TABLE3. I have made up the WHERE & AND conditions to show this example.

UPDATE table1 t1
JOIN table2 t2 ON t1.field1 = t2.field1
JOIN table3 t3 ON (t3.field1=t2.field2 AND t3.field3 IS NOT NULL)
SET t1.field9=t3.field9
WHERE t1.field5=1
AND t1.field9 IS NULL

Sign Up Login You must be logged in to post a comment.