Rails报告找不到那里的列

nek*_*une 6 postgresql activerecord ruby-on-rails

我目前正在尝试WHERE使用Rails在表上进行复杂的搜索,麻烦的是我收到错误:

PG::Error: ERROR:  column "email" does not exist
LINE 1: SELECT "bans".* FROM "bans"  WHERE (Email='' AND IP='' AND (...
                                        ^
: SELECT "bans".* FROM "bans"  WHERE (Email='' AND IP='' AND (Username='NULL' ))
Run Code Online (Sandbox Code Playgroud)

而且我知道该列确实存在,并且做了一个rails dbconsole给我以下内容:

Jungle=> select * from bans;
 id | Username | IP | Email | Reason | Length | created_at | updated_at 
----+----------+----+-------+--------+--------+------------+------------
(0 rows)
Run Code Online (Sandbox Code Playgroud)

所以这绝对是在数据库中,有没有人有这方面的经验?

mu *_*ort 12

SQL列名称不区分大小写,除非引用,标准说标识符应该标准化为大写,但PostgreSQL标准化为小写:

引用标识符也会使其区分大小写,而不带引号的名称始终折叠为小写.例如,标识符FOO,foo"foo"被认为通过PostgreSQL的相同,但"Foo""FOO"来自这三个和彼此不同.(在PostgreSQL中将不带引号的名称折叠为小写与SQL标准不兼容,后者表示不带引号的名称应折叠成大写.因此,foo应该等同于"FOO""foo"符合标准.如果要编写便携式应用程序,建议总是引用一个特定的名称或从不引用它.)

Email在SQL中引用了:

SELECT "bans".* FROM "bans"  WHERE (Email='' ...
Run Code Online (Sandbox Code Playgroud)

但PostgreSQL抱怨email:

column "email" does not exist
Run Code Online (Sandbox Code Playgroud)

您的未引用Email被视为email因为PostgreSQL将标识符规范化为小写.听起来像你用双引号创建了大写名称的列:

create table "bans" (
    "Email" varchar(...)
    ...
)
Run Code Online (Sandbox Code Playgroud)

或者通过使用:Email来标识迁移中的列.如果在创建列名时引用它,则它不会标准化为小写(或SQL标准情况下的大写),并且您必须对其进行双引号并永久匹配该案例:

SELECT "bans".* FROM "bans"  WHERE ("Email"='' ...
Run Code Online (Sandbox Code Playgroud)

一旦你解决Email,你就会有同样的问题IP,Username,Reason,和Length:你必须双引号他们都在引用他们的任何SQL.

最佳做法是使用小写列和表名,这样您就不必担心始终引用内容.我建议你修改你的表以使用小写列名.


顺便说一句,你的'NULL'字符串文字:

SELECT "bans".* FROM "bans"  WHERE (Email='' AND IP='' AND (Username='NULL' ))
-- -------------------->------------------>---------->---------------^^^^^^
Run Code Online (Sandbox Code Playgroud)

看起来很奇怪,你确定你不是故意的"Username" is null吗?该'NULL'字符串文字和NULL值是完全不同的事情,你不能使用=!=反对NULL,你必须使用比较事物is null,is not null,is distinct from,或is not distinct from(取决于您的意思)时,NULL值可能在发挥作用.