テーブルにINSERT文でデータを登録した後、登録済みのデータを変更したいと思うことがある。例えば、「超人の身長を間違えて登録してしまった」などである。そんなとき、データを削除して再登録するなどという面倒な方法をとる必要はない。UPDATE文によって、テーブルのデータを変更することが可能。
UPDATE文は、INSERT文やDELETE文と同じくDML文に属する。これを利用することで、テーブルのデータを変更することができる。基本的な構文は以下の通り。
UPDATE <テーブル名> SET <列名> = <式>
更新対象の列と、更新後の値は、SET句に記述する。
それではまず、chojinテーブルのcrated列(登録日)を全行、「2020年2月9日」で統一してみる。
UPDATE chojin SET created = '2020-02-09';
結果
+------+--------------------------------+------------+ | id | name | created | +------+--------------------------------+------------+ | 0001 | キン肉マン | 2020-02-09 | | 0002 | テリーマン | 2020-02-09 | | 0003 | ロビンマスク | 2020-02-09 | | 0004 | ウォーズマン | 2020-02-09 | | 0005 | ラーメンマン | 2020-02-09 | | 0006 | ブロッケンJr | 2020-02-09 | | 0007 | ウルフマン | 2020-02-09 | 以下省略
条件を指定したUPDATE文(探索型UPDATE)
次に、全行更新するのではなく、更新対象の行を制限してみる。行を制限するには、DELETE文のときと同様、WHERE句を使うことで可能。こういう対象行を制限したUPDATE文のことを、「探索型UPDATE」と呼ぶ。構文は次の通り。
UPDATE <テーブル名>
SET <列名> = <式>
WHERE <条件>;
例えば、categoryが「正義超人」の行に限って、超人強度(power)を10倍にするには、以下のように書く。
現状のデータ。
SELECT id, name, power FROM chojin WHERE category = '正義超人';
結果
+------+--------------------------+-------+ | id | name | power | +------+--------------------------+-------+ | 0001 | キン肉マン | 95 | | 0002 | テリーマン | 95 | | 0003 | ロビンマスク | 96 | | 0004 | ウォーズマン | 100 | | 0005 | ラーメンマン | 97 | | 0006 | ブロッケンJr | 90 | | 0007 | ウルフマン | 80 | | 0043 | スペシャルマン | 0 | | 0044 | カナディアンマン | 0 | +------+--------------------------+-------+
UPDATE文を実行。
UPDATE chojin SET power = power * 10 WHERE category = '正義超人';
結果
+------+--------------------------+-------+ | id | name | power | +------+--------------------------+-------+ | 0001 | キン肉マン | 950 | | 0002 | テリーマン | 950 | | 0003 | ロビンマスク | 960 | | 0004 | ウォーズマン | 1000 | | 0005 | ラーメンマン | 970 | | 0006 | ブロッケンJr | 900 | | 0007 | ウルフマン | 800 | | 0043 | スペシャルマン | 0 | | 0044 | カナディアンマン | 0 | +------+--------------------------+-------+
値を元に戻す。
UPDATE chojin SET power = power / 10 WHERE category = '正義超人';
結果
+------+--------------------------+-------+ | id | name | power | +------+--------------------------+-------+ | 0001 | キン肉マン | 95 | | 0002 | テリーマン | 95 | | 0003 | ロビンマスク | 96 | | 0004 | ウォーズマン | 100 | | 0005 | ラーメンマン | 97 | | 0006 | ブロッケンJr | 90 | | 0007 | ウルフマン | 80 | | 0043 | スペシャルマン | 0 | | 0044 | カナディアンマン | 0 | +------+--------------------------+-------+
NULLで更新するには
NULLのデータで更新するため、列「created」のNOT NULL制約を外す。
ALTER TABLE chojin MODIFY COLUMN created DATE;
SHOW COLUMNS FROM chojin;
+-----------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-----------+--------------+------+-----+---------+-------+ | id | char(4) | NO | PRI | NULL | | | name | varchar(100) | NO | | NULL | | | kana | varchar(100) | NO | | NULL | | | category | varchar(100) | NO | | NULL | | | attribute | varchar(100) | YES | | NULL | | | height | int(11) | YES | | NULL | | | weight | int(11) | NO | | NULL | | | power | int(11) | NO | | NULL | | | origin | varchar(100) | NO | | NULL | | | created | date | YES | | NULL | | +-----------+--------------+------+-----+---------+-------+
UPDATEを使うことで、列をNULLで更新することもできる。例えば、idが「0043」のスペシャルマンと「0044」のカナディアンマンの登録日(created)をNULLにしてみる。
UPDATE chojin SET created = NULL WHERE id IN ('0043', '0044');
結果
+------+--------------------------+---------+ | id | name | created | +------+--------------------------+---------+ | 0043 | スペシャルマン | NULL | | 0044 | カナディアンマン | NULL | +------+--------------------------+---------+
複数列の更新
UPDATEのSET句には、複数の列を対象として記述することが可能。上記で正義超人の超人強度を10倍にしたが、同時に身長に50を加える場合どうしたら良いか。
同様に2つのUPDATE文で実行することは可能である。それはそれで正しく更新は行われるが、二度もUPDATE文を実行するのは無駄であるし、SQLの記述量も増える。1つのUPDATE文にまとめて書けば良い。以下、2種類の方法がある。
UPDATE文を1つにまとめる方法①
UPDATE chojin SET power = power * 10, height = height + 50 WHERE category = '正義超人';
UPDATE文を1つにまとめる方法②
UPDATE chojin SET (power, height) = (power * 10, height + 50) WHERE category = '正義超人';
もちろん、SET句は2列だけでなく、3列並べることも可能。
注意が必要なのは、列をカンマで区切って並べる①の方法は、どのDBMSでも利用することが可能な一方、列をリスト化する②の方法は、一部のDBMSでしか利用できないことである。したがって、基本的には①の方法を使うのが確実である。