ChatGPT解决这个技术问题 Extra ChatGPT

不能简单地使用 PostgreSQL 表名(“关系不存在”)

我正在尝试运行以下 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 中的单个表中进行选择。多么可怕的程序。

B
Bill Karwin

根据我的阅读,此错误意味着您没有正确引用表名。一个常见的原因是该表是用混合大小写的拼写定义的,而您尝试使用全部小写来查询它。

换句话说,以下失败:

CREATE TABLE "SF_Bands" ( ... );

SELECT * FROM sf_bands;  -- ERROR!

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

SELECT * FROM "SF_Bands";

关于您的评论,您可以将架构添加到“search_path”,这样当您引用表名而不限定其架构时,查询将通过按顺序检查每个架构来匹配该表名。就像 shell 中的 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


看来即使您键入 SELECT * FROM SF_Bands 这仍然会失败,因为 Postgres 决定为您小写该表名。诡异的...
@romkyns:是的,这实际上在 RDBMS 品牌中很常见,未分隔的标识符被宣传为“不区分大小写”。但他们并不是真正不区分大小写,因为他们实现的方式是强制小写。仅当您在定义表时允许表名小写时,这才匹配表名。如果在 CREATE TABLE 时使用双引号分隔符,则在查询中引用它时必须使用分隔符。
如果它们不在引号中,Postgres 会自动将表名小写?真是太牛逼了……
@Andy,当您编写自己的 SQL 数据库时,请随意以其他方式实现不区分大小写的标识符。 :)
@BillKarwin 真的,Postgres 应该有足够的勇气发布更明智、更现代的案例处理作为一项重大改变。
A
Apurv

我对此有疑问,这就是故事(可悲但真实):

如果您的表名都是小写,例如:您可以使用的帐户:select * from AcCounTs 它将正常工作 如果您的表名都是小写,例如:accounts 以下将失败:select * from "AcCounTs"大小写混合,例如:帐户以下将失败:从帐户中选择 * 如果您的表名是混合大小写,例如:帐户以下将正常工作:从“帐户”中选择 *

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


与 where 子句中的列名相同
5. 混合大小写,如 Accounts,会因 select * from Accounts; 而失败 我发现最奇怪的部分:相同大小写不完全相同。
就是这样:postgres 查询中的所有名称都是小写的,除非你使用引号。
第四个选项对我有用,虽然我没有使用 PHP
感谢您布置所有互动! :)
a
a_horse_with_no_name

Postgres 处理与其他 RDMS 不同的查询。将架构名称放在表名之前的双引号中,如下所示,“SCHEMA_NAME”。“SF_Bands”


您的答案对先前接受的答案增加了什么,被投票了 22 次并且有很多细节?
E
Eric Leschinski

将 dbname 参数放在连接字符串中。它对我有用,而其他一切都失败了。

此外,在进行选择时,请像这样指定 your_schema.your_table

select * from my_schema.your_table

将模式名称(例如 my_schema.my_relation)放入查询中会有所帮助。
非常感谢!它真的可以帮助我解决问题!但是有没有办法可以省略方案名称?
e
e382df99a7950919789725ceeec126

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

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

S
Steve Shipway

如果表名包含下划线或大写,则需要用双引号将其括起来。

SELECT * from "Table_Name";

k
kira

您必须在引号中写入模式名称和表名称。如下:

select * from "schemaName"."tableName";

A
Alexander Kuzichkin

这真的很有帮助

SET search_path TO schema,public;

我更深入地挖掘了这个问题,并了解了如何通过默认设置为当前数据库中的新用户设置这个“search_path”。

打开数据库属性,然后打开工作表“变量”并简单地为您的用户添加这个具有实际值的变量。

因此,现在您的用户将通过默认获取此 schema_name,您可以使用不带 schemaName 的 tableName。


Ö
Özer

对我来说,问题是,我在初始化 Django 时使用了对该特定表的查询。当然它会抛出一个错误,因为那些表不存在。在我的例子中,它是 admin.py 文件中的 get_or_create 方法,每当软件运行任何类型的操作(在本例中为迁移)时都会执行该方法。希望对某人有所帮助。


A
Ashutosh Kumar

我遇到了与上面相同的问题,我使用的是 PostgreSQL 10.5。我尝试了上述所有方法,但似乎没有任何效果。

然后我关闭了 pgadmin 并为 PSQL 终端打开了一个会话。登录到 PSQL 并分别连接到数据库和模式:

\c <DATABASE_NAME>;
set search_path to <SCHEMA_NAME>;

然后,重新启动 pgadmin 控制台,然后我可以在 pagadmin 的查询工具中正常工作。


S
Sirius Bey

除了Bill Karwin's答案=>

是的,您应该用 double quotes 将表名括起来。但是,请注意,很可能 php 不允许您只需简单地编写:

$query = "SELECT * FROM "SF_Bands"";

相反,您应该使用 single quotes 而将 query 包围为 sav said

$query = 'SELECT * FROM "SF_Bands"';

m
marc_s

最简单的解决方法是将表名和所有列名更改为小写,您的问题将得到解决。

例如:

将 Table_Name 更改为 table_name 和

将列名更改为列名


A
Alexis Gamarra

您必须先添加架构,例如

SELECT * FROM place.user_place;

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

SET search_path TO place;

现在它将起作用:

SELECT * FROM user_place;

I
Indrajeet Gour

对少数人来说这可能很愚蠢,但在我的情况下 - 一旦我创建了表,我就可以在同一个会话中查询表,但如果我使用新会话 table does not exits 重新登录。

然后我在创建表后使用 commit,现在我也可以在新会话中查找和查询表。像这样:

select * from my_schema.my_tbl;

希望这会对一些人有所帮助。


M
Mohamad Alnatsha

确保表名不包含任何尾随空格

https://i.stack.imgur.com/1dRpA.png


S
Siwei

我尝试了每一个好的答案(upvote > 10)但不起作用。

我在 pgAdmin4 中遇到了这个问题。

所以我的解决方案很简单:

找到目标表/方案。鼠标右键单击,然后在这个新的查询工具窗口中单击:查询工具,您可以在不指定 set search_path 为 的情况下运行您的 SQL;你可以看到结果: