問題は..
ステートメント:
CASE
WHEN column_b = '123' THEN 1
WHEN column_b = '345' THEN 2
END;
.. は次の略です。
CASE
WHEN column_b = '123' THEN 1
WHEN column_b = '345' THEN 2
ELSE NULL
END
つまり、WHERE
句がない場合、UPDATE
ステートメントは単に「試行中」ではなく、実際にテーブル内のすべての行を更新し、そのほとんどをNULL
.
おそらく、NOT NULL
列の制約によりデータの損失が防止されました...
より良い解決策は..
一度に何千もの更新があるので、それらを 1 つのステートメントにまとめたいと思います。
大規模なセットの場合、はるかに高速(および短縮) :
UPDATE foobar f
SET column_a = val.a
FROM (
VALUES
(123, 1)
,(345, 2)
) val(b, a)
WHERE f.column_b = val.b
セットへの参加は、CASE
すべての行のブランチの長いリストを簡単に繰り返すよりも優れていリストが長くなると、その差は急速に拡大します。
また、必ずいずれかの方法でインデックスを作成しcolumn_b
てください。
VALUES
適切な行を生成する任意のテーブル、ビュー、またはサブセレクトで式を置き換えることができます。
注:とは 型であると
想定しています。この場合、質問の前後の一重引用符は役に立ちませんでした。文字列リテラルの代わりに数値リテラルを使用することをお勧めします。(文字列リテラルでも機能しますが。)column_a
column_b
integer
'123'
'123'
タイプのデフォルトのような文字列リテラルunknown
。数字が大きすぎる場合、 デフォルトの- または/
のような数値リテラル。123
integer
bigint
numeric
デフォルト以外のデータ型を扱っている場合は、明示的にキャストする必要があります。次のようになります。
...
FROM (
VALUES
('123'::sometype, '1'::sometype) -- first row defines row type
,('345', '2')
) val(b, a)
...