概要
TypeORMで多くのデータをまとめて更新しようとしたときに、大量のクエリが発行されてしまい困ったので、対処方法をまとめました。
やりたかったこととしては、以下の2つです。
- 特定のカラムを特定値に更新
- 特定のカラムを条件に応じた値に更新
1. 特定のカラムを特定値に更新
あるテーブルtable
に対して、column1
をvalue1
に更新する場合を考えます。
これは公式ドキュメントにもある通り、QueryBuilderを利用することで以下のように記述が可能です。
sample_code_1
await getConnection()
.createQueryBuilder()
.update(table)
.set({ column1: "value1" })
.execute();
実際に実行されるSQLは以下のようになります。
executed_sql_1
UPDATE "table"
SET "column1" = "value1"
大抵はwhere
句と一緒に利用されるものと思います。
2. 特定のカラムを条件に応じた値に更新
あるテーブルtable
に対して、以下のように条件分岐するように更新する場合を考えます。
-
column1
がcase1
の場合に、column1
をvalue1-1
に更新 -
column1
がcase2
の場合に、column1
をvalue1-2
に更新 -
column1
がcase3
の場合に、column1
をvalue1-3
に更新 - 上記以外の場合は更新しない
これはCASE文で場合分けして更新するようにします。
sample_code_2
await getConnection()
.createQueryBuilder()
.update(table)
.set({
column1: () => (
'CASE WHEN column1 = "case1" THEN "value1-1"' +
'CASE WHEN column1 = "case2" THEN "value1-2"' +
'CASE WHEN column1 = "case3" THEN "value1-3"' +
'ELSE table.column1 END'
)
})
.execute();
実際に実行されるSQLは以下のようになります。
executed_sql_2
UPDATE "table"
SET "column1" = CASE
WHEN "column1" = "case1" THEN "value1-1"
WHEN "column1" = "case2" THEN "value1-2"
WHEN "column1" = "case3" THEN "value1-3"
ELSE table.column1 END
更新対象のデータが少ない場合であれば1件ずつ更新する方法でも問題ありませんが、多くなってきた場合は上記のように一括更新する方法も検討してみると良いと思います。