我正在尝试运行以下PHP脚本来执行简单的数据库查询:

$db_host = "localhost";
$db_name = "showfinder";
$username = "user";
$password = "password";
$dbconn = pg_connect("host=$db_host dbname=$db_name user=$username password=$password")
    or die('Could not connect: ' . pg_last_error());

$query = 'SELECT * FROM sf_bands LIMIT 10';
$result = pg_query($query) or die('Query failed: ' . pg_last_error());


这会产生以下错误:


查询失败:错误:关系“ sf_bands”不存在


在所有示例中,我都能找到有人指出该关系不存在的错误,这是因为他们使用大写字母表名称中的字母。我的表格名称没有大写字母。有没有一种方法可以查询我的表而不包含数据库名称,即showfinder.sf_bands

评论

您确定sf_bands表存在吗? showfinder.sf_bands是否起作用?

showfinder.sf_bands完美运行

也许我应该注意,我的数据库是从MySQL迁移的

你可以尝试pg_query($ dbconn,$ query)吗?隐式连接可能会导致难以调试的问题,也可能会消除它。您还可以尝试使用pg_dbname($ dbconn)来确保它确实连接到showfinder吗?

+1表示大写字母是问题所在。我花了一个小时试图弄清楚为什么我无法从PostgreSQL的单个表中进行选择。多么糟糕的程序。

#1 楼

从我所读的内容来看,此错误表示您未正确引用表名。一个常见的原因是该表是使用大小写混合的拼写定义的,而您正在尝试使用所有小写字母对其进行查询。

换句话说,以下操作失败:

CREATE TABLE "SF_Bands" ( ... );

SELECT * FROM sf_bands;  -- ERROR!


使用双引号分隔标识符,以便在定义表时可以使用特定的大小写混合形式。

SELECT * FROM "SF_Bands";



重新发表评论,您可以将架构添加到“ search_path”,以便在引用表名而不限定其架构时,查询将通过按顺序检查每个架构来匹配该表名。就像外壳中的PATH或PHP中的include_path一样,您可以检查当前的架构搜索路径:

SHOW search_path
  "$user",public


您可以更改架构搜索路径:

SET search_path TO showfinder,public;


另请参见http://www.postgresql.org/docs/8.3/static/ddl-schemas.html

评论


糟糕,请原谅我。我的意思是说我的表名没有大写字母,而不是数据库名。

– Keyslinger
09年3月29日在20:39

看起来,即使您键入SELECT * FROM SF_Bands,这仍然会失败,因为Postgres决定为您小写该表名。奇怪的...

–罗马·斯塔科夫
2011年5月17日15:09

@romkyns:是的,这实际上在RDBMS品牌中非常普遍,未分隔的标识符被宣传为“不区分大小写”。但是它们并不是真正不区分大小写的,因为它们的实现方式是强制小写。仅当在定义表时允许将表名转换为小写时,此表才与表名匹配。如果在创建表时使用双引号定界符,则在查询中引用它时必须使用定界符。

– Bill Karwin
2011年5月17日15:55

如果表名不在引号中,则Postgres自动将其小写吗?真是太愚蠢了...

–安迪
18年1月4日在21:30

还要确保您已连接到正确的数据库。 Keyslinger这样做是正确的,但是还有其他工作流程可能会使人们感到困惑或使他们监督数据库部分。

– Tashows
18/12/6在14:45

#2 楼

我对此有疑问,这就是故事(很遗憾,但确实如此):


如果您的表名都是小写字母,例如:accounts
,则可以使用:select * from AcCounTs及其它
如果表名全为小写,例如:accounts
以下操作将失败:
select * from "AcCounTs"
如果表名是全小写,例如:Accounts
以下内容将失败:
select * from accounts
如果您的表名是大小写混合的,例如:Accounts
以下内容将正常运行:
select * from "Accounts"

我不喜欢记住像这样的无用的东西,但是你必须;)

评论


对于where子句中的列名相同

–罗兰
2014年5月12日15:46

5.混合大小写,如“帐户”,将失败,并从“帐户”中选择*。我发现最奇怪的部分是:大小写不同。

–罗兰
2014年5月12日16:00



一切就这么简单:postgres查询中的所有名称都是小写,除非您使用引号。

– Erndob
17-10-3在15:20

第四个选项对我有用,尽管我没有使用PHP

– Sayari
18年1月1日在20:20

感谢您安排所有互动! :)

– GetHacked
19年8月26日在16:07

#3 楼

Postgres处理查询不同于其他RDMS。将表名这样的模式名放在双引号之前,例如“ SCHEMA_NAME”。“ SF_Bands”

评论


您的答案与之前接受的答案有什么不同,被投票了22次并且有很多细节?

–雅罗斯拉夫
2012年10月10日18:47

#4 楼

将dbname参数放在您的连接字符串中。它对我有用,而其他所有方法都失败。

另外,在执行选择时,请指定your_schemayour_table这样的:

select * from my_schema.your_table


评论


将模式名称放入例如my_schema.my_relation到查询中有帮助。

–JoeTidee
15年2月27日在11:57

非常感谢你!它确实可以帮助我解决问题!但是有办法我可以省略方案名称吗?

–夏洛特
17年11月26日在12:27

#5 楼

我在OSX上遇到了类似的问题,但尝试使用双引号和单引号。对于您的情况,您可以尝试这样的事情

$query = 'SELECT * FROM "sf_bands"'; // NOTE: double quotes on "sf_Bands"


#6 楼

您必须在引用标记中写模式名称和表名称。如下:

select * from "schemaName"."tableName";


#7 楼

这确实有用。

SET search_path TO schema,public;


我进一步研究了此问题,并了解了如何通过默认方式为当前数据库中的新用户设置此“ search_path”。 />
打开“数据库属性”,然后打开“变量”工作表
,只需为您的用户添加具有实际值的变量即可。

现在,您的用户将通过defoult和您可以使用不带schemaName的tableName。

#8 楼

如果表名包含下划线或大写字母,则需要将其用双引号引起来。
SELECT * from "Table_Name";


#9 楼

对我来说,问题是,在初始化Django时,我曾使用过对该特定表的查询。当然,这将引发错误,因为这些表不存在。就我而言,这是admin.py文件中的get_or_create方法,只要软件运行任何类型的操作(在本例中为迁移),该方法便会执行。希望能对某人有所帮助。

#10 楼

最简单的解决方法是,只需将表名和所有列名更改为小写即可解决问题。例如,


Table_Name更改为table_name
ColumnName更改为columnname



#11 楼

您必须先添加架构,例如

SELECT * FROM place.user_place;


如果不想在所有查询中添加该架构,请尝试以下操作:

SET search_path TO place;


现在它将起作用:

SELECT * FROM user_place;