PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Les rapports Rails ne peuvent pas trouver une colonne qui s'y trouve

Les noms de colonnes SQL sont insensibles à la casse à moins d'être cités, la norme indique que les identifiants doivent être normalisés en majuscules mais PostgreSQL normalise en minuscules :

Le fait de citer un identifiant le rend également sensible à la casse, tandis que les noms sans guillemets sont toujours pliés en minuscules. Par exemple, les identifiants FOO , foo , et "foo" sont considérés comme identiques par PostgreSQL, mais "Foo" et "FOO" sont différents de ces trois et les uns des autres. (Le pliage des noms sans guillemets en minuscules dans PostgreSQL est incompatible avec la norme SQL, qui stipule que les noms sans guillemets doivent être pliés en majuscules. Ainsi, foo devrait être équivalent à "FOO" pas "foo" selon la norme. Si vous souhaitez écrire des applications portables, il est conseillé de toujours citer un nom particulier ou de ne jamais le citer.)

Vous faites référence à Email dans votre SQL :

SELECT "bans".* FROM "bans"  WHERE (Email='' ...

mais PostgreSQL se plaint de email :

column "email" does not exist

Votre Email non cité est traité comme email car PostgreSQL normalise les identifiants en minuscules. On dirait que vous avez créé les colonnes avec des noms en majuscules en les mettant entre guillemets :

create table "bans" (
    "Email" varchar(...)
    ...
)

ou en utilisant :Email pour identifier la colonne dans une migration. Si vous mettez un nom de colonne entre guillemets lors de sa création, il n'est pas normalisé en minuscules (ou en majuscules dans le cas standard SQL) et vous devrez le mettre entre guillemets et respecter la casse pour toujours :

SELECT "bans".* FROM "bans"  WHERE ("Email"='' ...

Une fois que vous avez corrigé Email , vous aurez le même problème avec IP , Username , Reason , et Length  :vous devrez tous les mettre entre guillemets dans tout code SQL qui les référence.

La meilleure pratique consiste à utiliser des noms de colonne et de table en minuscules afin que vous n'ayez pas à vous soucier de citer tout le temps. Je vous recommande de corriger votre table pour avoir des noms de colonnes en minuscules.

En aparté, votre 'NULL' littéral de chaîne :

SELECT "bans".* FROM "bans"  WHERE (Email='' AND IP='' AND (Username='NULL' ))
-- -------------------->------------------>---------->---------------^^^^^^

semble étrange, êtes-vous sûr que vous ne voulez pas dire que "Username" is null ? Le 'NULL' le littéral de chaîne et la valeur NULL sont des choses entièrement différentes et vous ne pouvez pas utiliser = ou != pour comparer les choses avec NULL, vous devez utiliser is null , is not null , is distinct from , ou is not distinct from (selon votre intention) lorsque des NULL pourraient être en jeu.