54

我有这样的查询(在函数中):

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_4param_5NULL,则只更新前三列并为和保留旧column_4column_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;

有没有更好的办法?

4

3 回答 3

105

去掉 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;
于 2012-11-09T11:29:10.317 回答
17

巧妙的技巧,感谢 Przemek、Frank 和 Erwin!

我建议对 Erwin 的回答稍作修改,以避免空更新。如果任何参数为空(意思是:“使用旧值”),则每次都会更新该行,即使行值没有改变(在第一次更新之后)。

通过添加“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
     ...
 );
于 2012-12-19T00:38:39.920 回答
15

此外,为避免更新:

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 的扩展版本

于 2012-11-09T20:11:05.140 回答