【问题标题】:Cannot simply use PostgreSQL table name ("relation does not exist")不能简单地使用 PostgreSQL 表名(“关系不存在”)
【发布时间】:2010-10-16 06:26:22
【问题描述】:

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

标签: php sql postgresql quoted-identifier


【解决方案1】:

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

换句话说,以下失败:

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 应该有足够的勇气发布更明智、更现代的案例处理作为一项重大变革。
【解决方案2】:

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

  1. 如果你的表名都是小写的,比如:accounts 您可以使用:select * from AcCounTs,它会正常工作

  2. 如果你的表名都是小写的,比如:accounts 以下将失败: select * from "AcCounTs"

  3. 如果您的表名大小写混合,例如:Accounts 以下将失败: select * from accounts

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

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

【讨论】:

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

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

【讨论】:

  • 你的答案对之前接受的答案有什么补充,投票了 22 次,并且有很多细节?
【解决方案4】:

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

同样在进行选择时,指定your_schema.your_table,如下所示:

select * from my_schema.your_table

【讨论】:

  • 将模式名称放入,例如my_schema.my_relation 进入查询有帮助。
  • 非常感谢!它真的可以帮助我解决问题!但是有没有办法可以省略方案名称?
【解决方案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;
      

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

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

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

      【讨论】:

      • 谢谢! ___________
      【解决方案8】:

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

      SELECT * from "Table_Name";
      

      【讨论】:

        【解决方案9】:

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

        【讨论】:

          【解决方案10】:

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

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

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

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

          【讨论】:

            【解决方案11】:

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

            例如:

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

            【讨论】:

              【解决方案12】:

              除了Bill Karwin's答案=>

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

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

              相反,您应该使用single quotes,同时将查询 包围为sav said

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

              【讨论】:

                【解决方案13】:

                您必须先添加架构,例如

                SELECT * FROM place.user_place;
                

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

                SET search_path TO place;
                

                现在它可以工作了:

                SELECT * FROM user_place;
                

                【讨论】:

                  【解决方案14】:

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

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

                  select * from my_schema.my_tbl;
                  

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

                  【讨论】:

                    【解决方案15】:

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

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2011-08-13
                      • 2014-12-25
                      • 1970-01-01
                      相关资源
                      最近更新 更多