6

我目前正在尝试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' ))

而且我知道该列确实存在,并且这样做rails dbconsole会给我以下信息:

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

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

4

3 回答 3

12

SQL 列名不区分大小写,除非引用,标准规定标识符应规范化为大写,但PostgreSQL 规范化为小写

引用标识符也使其区分大小写,而未引用的名称总是折叠为小写。例如,标识符FOOfoo"foo"被 PostgreSQL 认为是相同的,但"Foo""FOO"与这三个和彼此不同。(PostgreSQL 中将不带引号的名称折叠为小写与 SQL 标准不兼容,SQL 标准说不带引号的名称应该折叠为大写。因此,foo应该相当于"FOO""foo"按照标准。如果你想编写可移植的应用程序,你建议始终引用特定名称或从不引用它。)

Email在 SQL 中引用:

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

但 PostgreSQL 抱怨email

column "email" does not exist

您的未加引号Email被视为email因为 PostgreSQL 将标识符规范化为小写。听起来您通过双引号创建了具有大写名称的列:

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

或通过使用:Email来标识迁移中的列。如果您在创建列名时引用它,那么它不会被规范化为小写(或 SQL 标准大小写中的大写),您必须将其双引号并永远匹配大小写:

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

一旦你修复了, ,和Email, 你就会遇到同样的问题:你必须在任何引用它们的 SQL 中将它们全部双引号。IPUsernameReasonLength

最佳实践是使用小写的列名和表名,这样您就不必一直担心引用内容。我建议您将表修复为使用小写的列名。


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

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

看起来很奇怪,你确定你不是这个意思"Username" is null吗?'NULL'字符串文字和 NULL 值是完全不同的东西,您不能使用=或将其!=与 NULL 进行比较,当 NULL 可能在起作用时,您必须使用is null, is not null, is distinct from, oris not distinct from(取决于您的意图)。

于 2012-05-17T02:23:31.383 回答
1

看起来您的错误不是来自测试数据库,但如果是这样,请尝试rake db:test:prepare.

通常,请注意您有 3 个数据库 - 测试、开发、生产。因此很容易将它们混淆并检查错误的。

于 2012-05-17T02:10:03.070 回答
1

我在这里遇到了同样的问题,

mu-is-too-short如前所述,可以告诉 PostgreSql 搜索列名时区分大小写。

因此,通过实现此代码,我设法绕过了您面临的相同错误:

Transaction.find(:all,:conditions => ["(date between ?  and ?) AND \"Membership_id\" = ?", Time.now.at_beginning_of_month,  Time.now.end_of_month,membership.id])

注意到列名周围的\"符号了吗?嗯.. 尽管它很烦人,但这就是解决这个问题的方法。

于 2015-04-15T16:24:01.913 回答