我目前正在尝试使用Rails对表进行复杂的WHERE
搜索,问题是我收到错误:
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)
所以这绝对是在数据库中,有没有人有这方面的经验?
答案 0 :(得分:12)
除非引用,否则SQL列名称不区分大小写,标准说标识符应该标准化为大写但PostgreSQL normalizes to lower case:
引用标识符也会使其区分大小写,而不带引号的名称始终折叠为小写。例如,PostgreSQL认为标识符
FOO
,foo
和"foo"
是相同的,但"Foo"
和"FOO"
与这三个和其他标识符不同。 (在PostgreSQL中将未加引号的名称折叠为小写与SQL标准不兼容,后者表示不加引号的名称应折叠为大写。因此,foo
应相当于"FOO"
而不是{{1根据标准。如果你想编写便携式应用程序,建议你总是引用一个特定的名称或从不引用它。)
您在SQL中引用"foo"
:
Email
但PostgreSQL抱怨SELECT "bans".* FROM "bans" WHERE (Email='' ...
:
email
您的不带引号的column "email" does not exist
被视为Email
,因为PostgreSQL将标识符规范化为小写。听起来像你用双引号创建了大写名称的列:
email
或使用create table "bans" (
"Email" varchar(...)
...
)
标识迁移中的列。如果在创建列名时引用它,那么它不会标准化为小写(或SQL标准情况下的大写),你必须加倍引用它并永远匹配案例:
:Email
修复SELECT "bans".* FROM "bans" WHERE ("Email"='' ...
后,Email
,IP
,Username
和Reason
会遇到同样的问题:您必须在引用它们的任何SQL中都引用它们。
最佳做法是使用小写列和表名,这样您就不必担心始终引用内容。我建议你修改你的表以使用小写列名。
另外,您的Length
字符串文字:
'NULL'
看起来很奇怪,你确定你不是指SELECT "bans".* FROM "bans" WHERE (Email='' AND IP='' AND (Username='NULL' ))
-- -------------------->------------------>---------->---------------^^^^^^
吗? "Username" is null
字符串文字和NULL值是完全不同的东西,你不能使用'NULL'
或=
来比较NULL,你必须使用is null
, is not null
, is distinct from
, or is not distinct from
(取决于在你的意图)当NULL可能在播放时。
答案 1 :(得分:1)
看起来您的错误不是来自测试数据库,但如果是,请尝试rake db:test:prepare
。
一般情况下,请注意您有3个数据库 - 测试,开发,生产。所以很容易让他们混淆并检查错误的。
答案 2 :(得分: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])
注意到列名称周围的 \" 符号?嗯..虽然很烦人,但是解决了这个问题。