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

时间:2009-03-29 20:16:22

标签: php sql postgresql quoted-identifier

我正在尝试运行以下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

14 个答案:

答案 0 :(得分:243)

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

换句话说,以下失败:

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

答案 1 :(得分:59)

我遇到了这个问题,这就是故事(悲伤却是真的):

  1. 如果您的表名全是小写,例如:accounts 您可以使用:select * from AcCounTs并且它可以正常工作

  2. 如果您的表名全是小写,例如:accounts 以下将失败: select * from "AcCounTs"

  3. 如果您的表格名称是混合的,例如:Accounts 以下将失败: select * from accounts

  4. 如果您的表格名称是混合的,例如:Accounts 以下将正常工作: select * from "Accounts"

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

答案 2 :(得分:13)

Postgres进程查询与其他RDMS不同。在您的表名之前将模式名称放在双引号中,例如“SCHEMA_NAME”。“SF_Bands”

答案 3 :(得分:12)

将dbname参数放在连接字符串中。当其他一切都失败时,它适用于我。

在进行选择时,请指定your_schemayour_table,如下所示:

select * from my_schema.your_table

答案 4 :(得分:3)

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

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

答案 5 :(得分:3)

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

SELECT * from "Table_Name";

答案 6 :(得分:2)

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

例如:

  • Table_Name更改为table_name
  • ColumnName更改为columnname

答案 7 :(得分:1)

这真的很有帮助

SET search_path TO schema,public;

我更多地解决了这个问题,并找到了如何通过defoult为当前数据库中的新用户设置此“search_path”。

打开DataBase Properties然后打开Sheet“Variables” 只需为您的用户添加具有实际值的变量。

现在,您的用户将通过defoult获取此schema_name,并且您可以使用不带schemaName的tableName。

答案 8 :(得分:1)

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

select * from "schemaName"."tableName";

答案 9 :(得分:1)

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

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

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

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

答案 10 :(得分:0)

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

答案 11 :(得分:0)

您必须先添加架构,例如

gtk::Label

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

SELECT * FROM place.user_place;

现在它将起作用:

SET search_path TO place;

答案 12 :(得分:0)

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

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

select * from my_schema.my_tbl;

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

答案 13 :(得分:0)

除了Bill Karwin's答案=>

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

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

相反,您应该在将 query 包围的同时使用 single quotes 作为 sav said

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