次のようなクエリがあります(関数内):
UPDATE some_table SET
column_1 = param_1,
column_2 = param_2,
column_3 = param_3,
column_4 = param_4,
column_5 = param_5
WHERE id = some_id;
ここで、param_x
は関数のパラメーターです。パラメータがNULL
である列を更新しない方法はありますか?たとえば、param_4
とparam_5
がNULL
の場合、最初の3つの列のみを更新し、column_4
とcolumn_5
には古い値を残します。
私が今やっている方法は:
SELECT * INTO temp_row FROM some_table WHERE id = some_id;
UPDATE some_table SET
column_1 = COALESCE(param_1, temp_row.column_1),
column_2 = COALESCE(param_2, temp_row.column_2),
column_3 = COALESCE(param_3, temp_row.column_3),
column_4 = COALESCE(param_4, temp_row.column_4),
column_5 = COALESCE(param_5, temp_row.column_5)
WHERE id = some_id;
もっと良い方法はありますか?
SELECTステートメントを削除します。必要はありません。現在の値を使用してください。
UPDATE some_table SET
column_1 = COALESCE(param_1, column_1),
column_2 = COALESCE(param_2, column_2),
column_3 = COALESCE(param_3, column_3),
column_4 = COALESCE(param_4, column_4),
column_5 = COALESCE(param_5, column_5)
WHERE id = some_id;
きちんとしたトリック、Przemek、Frank&Erwinに感謝!
空の更新を避けるために、Erwinの回答を少し編集することをお勧めします。パラメータがnullの場合(つまり、「古い値を使用する」)、行の値が変更されていなくても(最初の更新後)、行は毎回更新されました。
「param_x IS NOT NULL」を追加することにより、空の更新を回避します。
UPDATE some_table SET
column_1 = COALESCE(param_1, column_1),
column_2 = COALESCE(param_2, column_2),
...
WHERE id = some_id
AND (param_1 IS NOT NULL AND param_1 IS DISTINCT FROM column_1 OR
param_2 IS NOT NULL AND param_2 IS DISTINCT FROM column_2 OR
...
);
さらに、empty更新を回避するには:
UPDATE some_table SET
column_1 = COALESCE(param_1, column_1),
column_2 = COALESCE(param_2, column_2)
...
WHERE id = some_id;
AND (param_1 IS DISTINCT FROM column_1 OR
param_2 IS DISTINCT FROM column_2 OR
...
);
これは、ターゲット列が定義されていることを前提としていますNOT NULL
。それ以外の場合は、 Geirの拡張バージョン を参照してください。