web-dev-qa-db-fra.com

Ne pas mettre à jour la colonne si la valeur de mise à jour est nulle

J'ai une requête comme celle-ci (dans une fonction):

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 est un paramètre de ma fonction. Existe-t-il un moyen de NE PAS mettre à jour ces colonnes, pour lesquelles le paramètre est NULL? Par exemple - si param_4 et param_5 sont NULL, puis mettez à jour uniquement les trois premières colonnes et laissez les anciennes valeurs pour column_4 et column_5.

La façon dont je le fais maintenant est la suivante:

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;

Y a-t-il une meilleure façon?

42
Przemek

Supprimez l'instruction SELECT, ce n'est pas nécessaire, utilisez simplement la valeur actuelle:

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;
69
Frank Heikens

Truc sympa, merci Przemek, Frank & Erwin!

Je suggère une modification mineure à la réponse d'Erwin pour éviter les mises à jour vides. Si des paramètres étaient nuls (ce qui signifie: "utilisez l'ancienne valeur"), la ligne a été mise à jour à chaque fois même si les valeurs de ligne n'ont pas changé (après la première mise à jour).

En ajoutant "param_x IS NOT NULL", nous évitons les mises à jour vides:

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
     ...
 );
15
Geir Bostad

De plus, pour éviter les mises à jour vides :

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
      ...
     );

Cela suppose que les colonnes cibles soient définies NOT NULL. Sinon, voir version étendue de Geir .

14