Mises à jour

Mettre à jour directement une ou plusieurs lignes d’une table :

      La syntaxe pour mettre à jour une ou plusieurs lignes en fournissant les valeurs est relativement simple quel que soit le SGBDR :

Connected to: Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production CREATE TABLE t1(c1 INTEGER, c2 CHARACTER VARYING(10)); Table created. INSERT INTO t1(c1, c2) VALUES(1, 'ESSAI'); 1 row created. UPDATE T1 SET c2 = 'TEST' WHERE c1 = 1; 1 row updated. SELECT * FROM t1; C1 C2 ---------- ---------- 1 TEST select version(); version ------------------------------------------------------------- PostgreSQL 9.5.1, compiled by Visual C++ build 1800, 64-bit (1 ligne) CREATE TABLE t1(c1 INTEGER, c2 CHARACTER VARYING(10)); CREATE TABLE INSERT INTO t1(c1, c2) VALUES(1, 'ESSAI'); INSERT 0 1 UPDATE T1 SET c2 = 'TEST' WHERE c1 = 1; UPDATE 1 SELECT * FROM t1; c1 | c2 ----+------ 1 | TEST (1 ligne)

      Avec Oracle comme avec PostgreSQL, il faut simplement indiquer l’ensemble des colonnes pour lesquelles les valeurs seront mises à jour avec une éventuelle clause WHERE permettant de filtrer les lignes concernées.

Mettre à jour les lignes d’une table à partir de celles d’une autre table :

      Supposons que nous devons mettre à jour les lignes d’une table à partir de celles d’une autre table. Les lignes de la table à mettre à jour absentes de l’autre table ne doivent pas être modifiées. Quelle syntaxe peut venir spontanément à l’esprit ?

select version(); version ------------------------------------------------------------- PostgreSQL 9.5.1, compiled by Visual C++ build 1800, 64-bit (1 ligne) create table t1 (c1 integer, c2 character varying(10)); CREATE TABLE insert into t1 values(1, 'A'); INSERT 0 1 insert into t1 values(2, 'B'); INSERT 0 1 create table t2 (c1 integer, c2 character varying(10)); CREATE TABLE insert into t2 values(2, 'C'); INSERT 0 1 update t1 set c2 = (select t2.c2 from t2 where t1.c1 = t2.c1); UPDATE 2 select * from t1; c1 | c2 ----+---- 1 | 2 | C (2 lignes) Connected to: Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production CREATE TABLE t1 (c1 INTEGER, c2 CHARACTER VARYING(10)); Table created. INSERT INTO t1 VALUES(1, 'A'); 1 row created. INSERT INTO t1 VALUES(2, 'B'); 1 row created. CREATE TABLE t2 (c1 INTEGER, c2 CHARACTER VARYING(10)); Table created. INSERT INTO t2 VALUES(2, 'C'); 1 row created. UPDATE t1 SET c2 = (SELECT t2.c2 FROM t2 WHERE t1.c1 = t2.c1); 2 rows updated. SELECT * FROM t1; C1 C2 ---------- ---------- 1 2 C

      Ouille ce n’est pas ce que nous voulions. Pour c1 = 1, c2 est à présent NULL dans t1. Nous avons simplement oublié la clause WHERE permettant de filtrer les lignes de t1 à mettre à jour. La solution est commune à Oracle et PostgreSQL :

Connected to: Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production CREATE TABLE t1 (c1 INTEGER, c2 CHARACTER VARYING(10)); Table created. INSERT INTO t1 VALUES(1, 'A'); 1 row created. INSERT INTO t1 VALUES(2, 'B'); 1 row created. CREATE TABLE t2 (c1 INTEGER, c2 CHARACTER VARYING(10)); Table created. INSERT INTO t2 VALUES(2, 'C'); 1 row created. UPDATE t1 SET c2 = (SELECT t2.c2 FROM t2 WHERE t1.c1 = t2.c1) WHERE EXISTS (SELECT 1 FROM t2 WHERE (t1.c1 = t2.c1)); 1 row updated. SELECT * FROM t1; C1 C2 ---------- ---------- 1 A 2 C select version(); version ------------------------------------------------------------- PostgreSQL 9.5.1, compiled by Visual C++ build 1800, 64-bit (1 ligne) CREATE TABLE t1 (c1 INTEGER, c2 CHARACTER VARYING(10)); CREATE TABLE INSERT INTO t1 VALUES(1, 'A'); INSERT 0 1 INSERT INTO t1 VALUES(2, 'B'); INSERT 0 1 CREATE TABLE t2 (c1 INTEGER, c2 CHARACTER VARYING(10)); CREATE TABLE INSERT INTO t2 VALUES(2, 'C'); INSERT 0 1 UPDATE t1 SET c2 = (SELECT t2.c2 FROM t2 WHERE t1.c1 = t2.c1) WHERE EXISTS (SELECT 1 FROM t2 WHERE (t1.c1 = t2.c1)); UPDATE 1 SELECT * FROM t1; c1 | c2 ----+---- 1 | A 2 | C (2 lignes)

      Il est aussi possible d’utiliser une syntaxe propriétaire avec PostgreSQL pour obtenir le même résultat :

select version(); version ------------------------------------------------------------- PostgreSQL 9.5.1, compiled by Visual C++ build 1800, 64-bit (1 ligne) CREATE TABLE t1 (c1 INTEGER, c2 CHARACTER VARYING(10)); CREATE TABLE INSERT INTO t1 VALUES(1, 'A'); INSERT 0 1 INSERT INTO t1 VALUES(2, 'B'); INSERT 0 1 CREATE TABLE t2 (c1 INTEGER, c2 CHARACTER VARYING(10)); CREATE TABLE INSERT INTO t2 VALUES(2, 'C'); INSERT 0 1 UPDATE t1 SET c2 = t2.c2 FROM t2 WHERE t1.c1 = t2.c1; UPDATE 1 postgres=# SELECT * FROM t1; c1 | c2 ----+---- 1 | A 2 | C (2 lignes)

      Cette syntaxe peut sembler plus simple mais je recommande de ne pas utiliser de syntaxe spécifique à un SGBDR quand une syntaxe commune est disponible.

Mise à jour : 28/08/2016