代码之家  ›  专栏  ›  技术社区  ›  Keyslinger

不能只使用PostgreSQL表名(“关系不存在”)。

  •  125
  • Keyslinger  · 技术社区  · 16 年前

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

    7 回复  |  直到 7 年前
        1
  •  223
  •   Bill Karwin    16 年前

    根据我所读的,这个错误意味着您没有正确地引用表名。一个常见的原因是,表是用混合大小写拼写定义的,您试图用所有小写字母查询它。

    换言之,以下失败:

    CREATE TABLE "SF_Bands" ( ... );
    
    SELECT * FROM sf_bands;  -- ERROR!
    

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

    SELECT * FROM "SF_Bands";
    

    作为您的注释,您可以向“search_path”添加一个模式,这样当您引用一个表名而不限定其模式时,查询将通过依次检查每个模式来匹配该表名。就像 PATH 在壳牌或 include_path 在php等中,您可以检查当前的模式搜索路径:

    SHOW search_path
      "$user",public
    

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

    SET search_path TO showfinder,public;
    

    也见 http://www.postgresql.org/docs/8.3/static/ddl-schemas.html

        2
  •  56
  •   Apurv    12 年前

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

    1. 如果表名的大小写都是:accounts 你可以使用: select * from AcCounTs 会很好的

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

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

    4. 如果您的表名是混合大小写,例如: 账户 以下功能正常: select * from "Accounts"

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

        3
  •  13
  •   a_horse_with_no_name    12 年前

    Postgres进程查询不同于其他RDM。将模式名放在表名前面的双引号中,如下所示:“模式名”。“SF带区”

        4
  •  10
  •   Eric Leschinski Mr. Napik    8 年前

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

    同样,在执行选择时,请指定 your_schema . your_table 这样地:

    select * from my_schema.your_table
    
        5
  •  3
  •   e382df99a7950919789725ceeec126    7 年前

    我在OSX上也遇到了类似的问题,但我尝试使用双引号和单引号。对于你的案子,你可以试试这样的方法

    $query = 'SELECT * FROM "sf_bands"'; // NOTE: double quotes on "sf_Bands"
    
        6
  •  0
  •   Özer    9 年前

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

        7
  •  0
  •   Alexander Kuzichkin    7 年前

    这真的很有用

    SET search_path TO schema,public;
    

    我更深入地探讨了这个问题,并发现了如何通过在当前数据库中为一个新用户设置这个“搜索路径”。

    打开数据库属性,然后打开工作表“变量” 只需为您的用户添加这个变量的实际值。

    因此,现在您的用户将通过default获得这个模式名称,您可以使用不带模式名称的tablename。