web-dev-qa-db-fra.com

Demande de mise à jour à l'aide de l'alias de table

Exécuter cette demande:

update table t1 set t1.column = 0 where t1.column2 = 1234

Obtenir cette erreur:

la colonne "t1" de la relation "table" n'existe pas

Cette demande fonctionne correctement dans MySQL.
Pourquoi est-ce que j'obtiens cette erreur dans PostgreSQL?

12
justesting

Je ne sais pas si c'est votre syntaxe souhaitée ou non. Vérifiez votre syntaxe pour UPDATE

Actuellement, c'est

[ WITH [ RECURSIVE ] with_query [, ...] ]
UPDATE [ ONLY ] table_name [ * ] [ [ AS ] alias ]
    SET { column_name = { expression | DEFAULT } |
          ( column_name [, ...] ) = ( { expression | DEFAULT } [, ...] ) |
          ( column_name [, ...] ) = ( sub-SELECT )
        } [, ...]
    [ FROM from_list ]
    [ WHERE condition | WHERE CURRENT OF cursor_name ]
    [ RETURNING * | output_expression [ [ AS ] output_name ] [, ...] ]

Donc, si vous fournissez table t1, il est analysé comme une table nommée table. En fait, pour ce faire, vous devez l'avoir entre guillemets "table" t1 ce que vous faites ou votre bibliothèque fait.

  • En tant que note de conception, ne faites pas cela. En fait, ne nommez rien mots-clés SQL .
  • Mais si vous voulez vous amuser et voir ce qui se passe, nous pouvons jouer ..

Créons des données textuelles,

CREATE TABLE "table" AS
SELECT x AS column, x AS column2
FROM generate_series(1,12345) AS t(x);

Nous pouvons maintenant essayer votre requête d'origine et obtenir votre résultat d'origine,

UPDATE "table" t1 SET t1.column=0 WHERE t1.column2=1234;
ERROR:  column "t1" of relation "table" does not exist
LINE 1: UPDATE "table" t1 SET t1.column=0 WHERE t1.column2=1234;

Et c'est le problème que vous rencontrez. Comme pour le tableau, si vous souhaitez utiliser un mot clé SQL, vous devez le citer. Fait intéressant, ce n'est pas suffisant ici.

UPDATE "table" t1 SET t1."column"=0 WHERE t1.column2=1234;
ERROR:  column "t1" of relation "table" does not exist
LINE 1: UPDATE "table" t1 SET t1."column"=0 WHERE t1.column2=1234;

En plus de cela, il semble que l'alias de table n'est pas pris en charge dans la liste SET , que la colonne soit ou non un mot clé réservé.

UPDATE "table" t1 SET "column"=0 WHERE t1.column2=1234;

Pourquoi c'est actuellement Fonctionne comme prévu

Pourquoi vous ne pouvez pas utiliser d'alias, xocolatl de IRC aide à cela,

<xocolatl> EvanCarroll: la raison pour laquelle vous ne pouvez pas utiliser l'alias à gauche du = est à cause des types composites

<xocolatl> EvanCarroll: donc, ce n'est pas un bug mais WAD

Donc, dans le code pour CREATE une table avec un type composite personnalisé, exécutez un UPDATE dessus.

CREATE TYPE foo AS ( x int, y int );

CREATE TABLE foobar AS
  SELECT v::foo AS mycol
  FROM ( VALUES (1,2), (2,100) ) AS v;

UPDATE foobar SET mycol.x = 9;

Ainsi, la syntaxe qui permet le . est mycol.type-address, ne pas tablealias.col-name.

Résolution du problème de syntaxe ambiguë

Si cela n'avait pas de sens, tout comportement, mais ce comportement vous donnerait une syntaxe ambiguë,

CREATE TYPE foo AS ( mycol int, x int );

CREATE TABLE mytable AS
  SELECT v::foo AS mycol, 1 AS x
  FROM ( VALUES (1,2), (2,100) ) AS v;

UPDATE mytable AS mycol SET mycol.x = 9;

Qu'est-ce que mycol.x y faire référence? Comme c'est pas ambigu, le référencement de table et l'alias de table sont désactivés, donc c'est définitivement 100% du temps un type composite nommé mycol, sur la table mytable.

9
Evan Carroll

C'est une bizarrerie Postgres. Comme indiqué dans la documentation de UPDATE , les noms de table ne doivent pas être utilisés pour les colonnes cibles.

column_name

Le nom d'une colonne du tableau nommé par table_name. Le nom de la colonne peut être qualifié avec un nom de sous-champ ou un indice de tableau, si nécessaire. N'incluez pas le nom de la table dans la spécification d'une colonne cible - par exemple, UPDATE table_name SET table_name.col = 1 n'est pas valide.

Une seule table peut être mise à jour dans une clause UPDATE, il n'y a donc pas de place pour une mauvaise interprétation de l'instruction.

7
ypercubeᵀᴹ