3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

MySQLAdvent Calendar 2022

Day 22

MySQLで更新した行を確認する

Last updated at Posted at 2022-12-21

こちらは MySQL Advent Calendar 2022 22 日目の記事です。

昨日は @hmatsu47 さんの RDS for MySQL(8.0.30 以降)で Optimized Writes を試してみた でした


MySQLでupdate文を実行すると以下のようにChangedで更新の有無を教えてくれます

mysql> update category set name = 'Action' where category_id = 1;
Query OK, 0 rows affected (0.00 sec)
Rows matched: 1  Changed: 0  Warnings: 0

mysql> update category set name = 'Haction' where category_id = 1;
Query OK, 1 row affected (0.02 sec)
Rows matched: 1  Changed: 1  Warnings: 0

CSVから更新クエリ生成して実行したときに、実際に更新された行を検知できたら嬉しかったのでその時の対応を記載します

想定しているケース

  • CSVやらなんやらで渡されたデータをもとに更新クエリを作成し実行する
  • 何らかの言語・ライブラリを使ってやるほどではない(差分見てupdated_at更新してくれるの便利)
  • 一行ずつの更新クエリが大量にある(複数行更新ではない)

実装

もとの更新クエリ(update.sql)がこんなシンプルな作りだったとして

update category set name = 'Haction' where category_id = 1;
update category set name = 'Animation' where category_id = 2;

以下のように修正する

update category set name = 'Haction' where category_id = 1;
select 1 where row_count() > 0;
update category set name = 'Animation' where category_id = 2;
select 2 where row_count() > 0;

そして実行 ( -N はヘッダーを出力しないオプション )

bash-4.4# mysql sakila -N < update_with_return.sql > updated_ids
bash-4.4# cat updated_ids 
1

別実装

変数を使ったパターン

  • 変更行のid取得クエリが変わるのが気になる
  • 条件(クエリ生成元)にidがない
set @changed = null; -- ここは一回の宣言で使いまわしておk
update category set name = 'Haction' where name = 'Action' and (select @changed := category_id); 
select @changed where row_count() > 0;
update category set name = 'Animation' where name = 'Animation' and (select @changed := category_id); 
select @changed where row_count() > 0;
bash-4.4# mysql sakila -N < update_with_variable.sql > updated_ids
bash-4.4# cat updated_ids 
1

条件に引っ掛かる行が複数あるときは update文に limit 1 を付けて、リダイレクトを追記モード( >> )で実行、実行後にupdated_idsファイルが増えなくなるまでループするとか
シンプルだけどスマートじゃないのでもっと適切な方法あったら教えてください


明日は @yk0807 さんの MySQLが遅いと思ったときにやること です

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?