UPDATE — mettre à jour les lignes d'une table
[ WITH [ RECURSIVE ] requête_with [, ...] ] UPDATE [ ONLY ] nom_table [ * ] [ [ AS ] alias ] SET { nom_colonne = { expression | DEFAULT } | ( nom_colonne [, ...] ) = ( { expression | DEFAULT } [, ...] ) } [, ...] [ FROM liste_from ] [ WHERE condition | WHERE CURRENT OF nom_curseur ] [ RETURNING * | expression_sortie [ [ AS ] nom_sortie ] [, ...] ]
UPDATE modifie les valeurs des colonnes spécifiées pour toutes les lignes qui satisfont la condition. Seules les colonnes à modifier doivent être mentionnées dans la clause SET ; les autres colonnes conservent leur valeur.
Il existe deux façons de modifier le contenu d'une table à partir d'informations contenues dans d'autres tables de la base de données : à l'aide de sous-requêtes ou en spécifiant des tables supplémentaires dans la clause FROM. Le contexte permet de décider de la technique la plus appropriée.
La clause RETURNING optionnelle fait que UPDATE calcule et renvoie le(s) valeur(s) basée(s) sur chaque ligne en cours de mise à jour. Toute expression utilisant les colonnes de la table et/ou les colonnes d'autres tables mentionnées dans FROM peut être calculée. La syntaxe de la liste RETURNING est identique à celle de la commande SELECT.
L'utilisateur doit posséder le droit UPDATE sur la table, ou au moins sur les colonnes listées pour la mise à jour. Vous devez aussi avoir le droit SELECT sur toutes les colonnes dont les valeurs sont lues dans les expressions ou condition.
La clause WITH vous permet de spécifier une ou plusieurs sous-requêtes qui peuvent être référencées par nom dans la requêteUPDATE. Voir Section 7.8, « Requêtes WITH (Common Table Expressions) » et SELECT(7) pour les détails.
Le nom de la table à mettre à jour (éventuellement qualifié du nom du schéma). Si ONLY est indiqué avant le nom de la table, les lignes modifiées ne concernent que la table nommée. Si ONLY n'est pas indiquée, les lignes modifiées font partie de la table nommée et de ses tables filles. En option, * peut être ajouté après le nom de la table pour indiquer explicitement que les tables filles doivent être inclues.
Un nom de substitution pour la table cible. Quand un alias est fourni, il cache complètement le nom réel de la table. Par exemple, avec UPDATE foo AS f, le reste de l'instruction UPDATE doit référencer la table avec f et non plus foo.
Le nom d'une colonne dans nom_table. Le nom de la colonne peut être qualifié avec un nom de sous-champ ou un indice de tableau, si nécessaire. Ne pas inclure le nom de la table dans la spécification d'une colonne cible -- par exemple, UPDATE tab SET tab.col = 1 est invalide.
Une expression à affecter à la colonne. L'expression peut utiliser les anciennes valeurs de cette colonne et d'autres colonnes de la table.
Réinitialise la colonne à sa valeur par défaut (qui vaut NULL si aucune expression par défaut ne lui a été affectée).
Une liste d'expressions de tables, qui permet aux colonnes des autres tables d'apparaître dans la condition WHERE et dans les expressions de mise à jour. Cela est similaire à la liste de tables pouvant être spécifiée dans la section intitulée « Clause FROM » d'une instruction SELECT. La table cible ne doit pas apparaître dans liste_from, sauf en cas d'auto-jointure (auquel cas elle doit apparaître avec un alias dans liste_from).
Une expression qui renvoie une valeur de type boolean. Seules les lignes pour lesquelles cette expression renvoie true sont mises à jour.
Le nom du curseur à utiliser dans une condition WHERE CURRENT OF. La ligne à mettre à jour est la dernière récupérée à partir de ce curseur. Le curseur doit être une requête sans regroupement sur la table cible de l'UPDATE. Notez que WHERE CURRENT OF ne peut pas être spécifié avec une condition booléenne. Voir DECLARE(7) pour plus d'informations sur l'utilisation des curseurs avec WHERE CURRENT OF.
Une expression à calculer et renvoyée par la commande UPDATE après chaque mise à jour de ligne. L'expression peut utiliser tout nom de colonne de la table nommée nom_table ou des tables listées dans le FROM. Indiquez * pour que toutes les colonnes soient renvoyées.
Un nom à utiliser pour une colonne renvoyée.
En cas de succès, une commande UPDATE renvoie un message de la forme
UPDATE total
total est le nombre de lignes mises à jour, en incluant les lignes qui correspondent au filtre mais dont la valeur des colonnes ne change pas. Notez que le nombre peut être inférieur au nombre de lignes filtrées par la condition quand certaines mises à jour sont supprimées par un trigger BEFORE UPDATE. S'il vaut 0, aucune ligne n'a été mise à jour par cette requête (ce qui n'est pas considéré comme une erreur).
Lorsqu'une clause FROM est précisée, la table cible est jointe aux tables mentionnées dans liste_from, et chaque ligne en sortie de la jointure représente une opération de mise à jour pour la table cible. Lors de l'utilisation de FROM, il faut s'assurer que la jointure produit au plus une ligne en sortie par ligne à modifier. En d'autres termes, une ligne cible ne doit pas être jointe à plus d'une ligne des autres tables. Le cas échéant, seule une ligne de jointure est utilisée pour mettre à jour la ligne cible, mais il n'est pas possible de prédire laquelle.
À cause de ce manque de déterminisme, il est plus sûr de ne référencer les autres tables qu'à l'intérieur de sous-requêtes. Même si c'est plus difficile à lire et souvent plus lent que l'utilisation d'une jointure.
Si la commande UPDATE contient une clause RETURNING, le résultat sera similaire à celui d'une instruction SELECT contenant les colonnes et les valeurs définies dans la liste RETURNING, à partir de la liste des lignes mises à jour par la commande, comme la possibilité d'utiliser la clause WITH avec la commande UPDATE.
Changer le mot Drame en Dramatique dans la colonne genre de la table films :
UPDATE films SET genre = 'Dramatique' WHERE genre = 'Drame';
Ajuster les entrées de température et réinitialiser la précipitation à sa valeur par défaut dans une ligne de la table temps :
UPDATE temps SET temp_basse = temp_basse+1, temp_haute = temp_basse+15, prcp = DEFAULT WHERE ville = 'San Francisco' AND date = '2005-07-03';
Réaliser la même opération et renvoyer les lignes mises à jour :
UPDATE temps SET temp_basse = temp_basse+1, temp_haute = temp_basse+15, prcp = DEFAULT WHERE ville = 'San Francisco' AND date = '2003-07-03' RETURNING temp_basse, temp_haute, prcp;
Utiliser une autre syntaxe pour faire la même mise à jour :
UPDATE temps SET (temp_basse, temp_haute, prcp) = (temp_basse+1, temp_basse+15, DEFAULT) WHERE ville = 'San Francisco' AND date = '2003-07-03';
Incrémenter le total des ventes de la personne qui gère le compte d'Acme Corporation, à l'aide de la clause FROM :
UPDATE employes SET total_ventes = total_ventes + 1 FROM comptes WHERE compte.nom = 'Acme Corporation' AND employes.id = compte.vendeur;
Réaliser la même opération en utilisant une sous-requête dans la clause WHERE :
UPDATE employes SET total_ventes = total_ventes + 1 WHERE id = (SELECT vendeur FROM comptes WHERE nom = 'Acme Corporation');
Tenter d'insérer un nouvel élément dans le stock avec sa quantité. Si l'élément existe déjà, mettre à jour le total du stock de l'élément. Les points de sauvegarde sont utilisés pour ne pas avoir à annuler l'intégralité de la transaction en cas d'erreur :
BEGIN; -- autres opérations SAVEPOINT sp1; INSERT INTO vins VALUES('Chateau Lafite 2003', '24'); -- A supposer que l'instruction ci-dessus échoue du fait d'une violation de clé -- unique, les commandes suivantes sont exécutées : ROLLBACK TO sp1; UPDATE vins SET stock = stock + 24 WHERE nomvin = 'Chateau Lafite 2003'; -- continuer avec les autres opérations, et finir COMMIT;
Modifier la colonne genre de la table films dans la ligne où le curseur c_films est actuellement positionné :
UPDATE films SET genre = 'Dramatic' WHERE CURRENT OF c_films;
Cette commande est conforme au standard SQL, à l'exception des clauses FROM et RETURNING qui sont des extensions PostgreSQL™.
D'après le standard, la syntaxe de la liste de colonnes permet qu'une liste de colonnes soit affectée à une expression de ligne comme une sous-sélection :
UPDATE comptes SET (nom_contact, prenom_contact) = (SELECT nom, prenom FROM commerciaux WHERE commerciaux.id = comptes.vendeur_id);
Ceci n'est pas encore implémenté -- la source doit être une liste d'expressions indépendantes.
D'autres systèmes de bases de données offrent l'option FROM dans laquelle la table cible est supposée être à nouveau indiquée dans le FROM. PostgreSQL™ n'interprète pas la clause FROM ainsi. Il est important d'en tenir compte lors du portage d'applications qui utilisent cette extension.