PostgreSQL La base de donnees la plus sophistiquee au monde.

Forums PostgreSQL.fr

Le forum officiel de la communauté francophone de PostgreSQL

Vous n'êtes pas identifié(e).

#1 26/01/2022 18:15:19

lutin11
Membre

Perte de donnée après exécution d'une requête invalide

Bonjour,
j'ai une table

lutin11 a écrit :

\d ps_to_remove
                      Table « pg_temp_3.ps_to_remove »
Colonne |          Type                   | Collationnement | NULL-able | Par défaut
    ---------+-----------------------------+----------------------+---------------+------------
   ps_id   | character varying(255) |                          |                   |
  ps_gs   | character varying(255) |                          |                   |

créée comme ceci

lutin11 a écrit :

CREATE TEMPORARY TABLE ps_to_remove AS (
  SELECT ps.topiaid ps_id, gs.topiaid ps_gs
  FROM practicedsystem ps
  INNER JOIN growingsystem gs ON ps.growingsystem = gs.topiaid
  INNER JOIN growingplan gp ON gp.topiaid = gs.growingplan
  INNER JOIN domain d ON d.topiaid = gp.domain
  LEFT JOIN plot p ON p.growingsystem = gs.topiaid
  LEFT JOIN zone z ON z.plot = p.topiaid
  WHERE d.campaign < 2000 OR d.campaign >= 2025
  AND d.active IS false
  AND ps.active IS false
  GROUP BY ps_id, ps_gs
);

Le requête suivante reourne une erreur:


lutin11 a écrit :

SELECT growingsystem FROM ps_to_remove;
ERROR:  column "growingsystem" does not exist
LIGNE 1 : SELECT growingsystem FROM ps_to_remove;

Normal la colonne 'growingsystem' n'existe pas mais alors pourquoi celle-ci fonctionne ?

lutin11 a écrit :

inra-agrosyst-latest=# SELECT COUNT(*) FROM growingsystem_networks WHERE growingsystem IN (SELECT growingsystem FROM ps_to_remove);
count
-------
29365
(1 ligne)

La bonne requête devrait être:

lutin11 a écrit :

inra-agrosyst-latest=# SELECT COUNT(*) FROM growingsystem_networks WHERE growingsystem IN (SELECT ps_gs FROM ps_to_remove);
count
-------
     7
(1 ligne)

Ça m'a posé un gros problème car

lutin11 a écrit :

DELETE FROM growingsystem_networks WHERE growingsystem IN (
  SELECT growingsystem FROM ps_to_remove
);

vide entièrement la table growingsystem_networks !

Quelqu'un pourrait-il m'expliquer la raison d'un tel fonctionnement ?
Merci

Hors ligne

#2 26/01/2022 22:52:40

gleu
Administrateur

Re : Perte de donnée après exécution d'une requête invalide

La question est posée tellement fréquemment que c'est devenu un élément de la FAQ de PostgreSQL : https://wiki.postgresql.org/wiki/FAQ#Wh … ubquery.3F

Et donc pour les paraphraser :

Cependant, selon la norme SQL - et pour de bonnes raisons de facilité d'utilisation - la référence à growingsystem dans la sous-sélection se trouve dans la portée "référence externe" où growingsystem_networks existe et qui a en effet une colonne growingsystem. Étant donné que l'expression growingsystem = growingsystem va toujours être évaluée à true, la clause where elle-même renverra toujours true - tant que la sous-requête (dans ce cas ps_to_remove) renvoie au moins une ligne (c'est-à-dire que ps_to_remove WHERE false produira un résultat vide).


Guillaume.

Hors ligne

Pied de page des forums