PostgreSQL错误:42P01:关系“[表名]”不存在。

28

我使用 PostgreSQL 9.3 创建了一些带引号的表,现在遇到一个奇怪的问题。例如,如果我使用引号创建一个表:

create table "TEST" ("Col1" bigint);

表格已经正确创建,当我在pgAdminIII的SQL面板中查看时,可以看到引号被保留。但是当我查询数据库以查找所有可用表格的列表(使用以下查询),我发现结果中不包含表格名称周围的引号。

select table_schema, table_name from information_schema.tables where not table_schema='pg_catalog' and not table_schema='information_schema';

由于这个表格是使用引号创建的,所以我不能直接使用上面查询返回的未引用的表格名称,否则会导致标题中报错。

我可以尝试在所有查询中将表格名称用引号括起来,但我不确定它是否总是有效。我正在寻找一种方法来获取结果中带引号的表格名称列表。

对于列名,我也遇到了同样的问题,但我希望如果我可以找到解决表格名称问题的方法,类似的解决方案也适用于列名。

5个回答

50

你有两个选择: - 不使用引号: 这样一切都会自动转换为小写并且不区分大小写 - 使用引号: 从现在开始一切都是大小写敏感的。

我强烈建议不使用引号,并使PostgreSQL不区分大小写,这会让生活变得更加容易。一旦你开始使用引号,就必须在任何地方都使用它,因为PostgreSQL将开始非常精确。

以下是一些示例:

   TEST = test       <-- non case sensitive
   "Test" <> Test    <-- first is precise, second one is turned to lower case
   "Test" = "Test"   <-- will work
   "test" = TEST     <-- should work; but you are just lucky.

尽量避免使用这种诡计。在对象名称中请使用7位ASCII编码。


1
同意在PostgreSQL中不使用引号可以使生活更轻松,但在我的情况下并非总是可行,因为我的应用程序不创建数据库。它应该能够从第三方PostgreSQL数据库读取数据,而我无法控制其他人如何创建表。无论如何,令人惊讶的是,PostgreSQL没有告诉我某个表是用引号创建的,但当我在查询中使用未带引号的表名时,它却不允许这样做。 - Rahul Vijay Dawda
2
它自动知道引号的使用,只要有一个非小写字母存在即可。因此,如果一个表被列为Test之类的单词,那么这意味着你必须区分大小写。 - Hans-Jürgen Schönig
1
我认为这是最后的选择,因为在添加引号之前实施检查以查看至少一个字符是否为大写字母将是一种过度设计,如果PostgreSQL本身可以告诉我表格是否包含引号,则更好。 - Rahul Vijay Dawda

9
使用npg包作为数据存储ORM时,您期望ORM框架(在我们的情况下为Entity Framework)生成SQL语句。如果遇到PostgreSQL异常,即关系“表名”不存在,则可能是因为表未创建或生成的SQL语句缺少某些内容。尝试使用Visual Studio进行调试,您会发现模式名称没有引导表名称。
SELECT "ID", "Name", "CreatedBy", "CreatedDate" 
FROM "TestTable"; 

当PostgreSQL需要模式名称时,需要进行翻译。解决方法是在DBContext类中覆盖OnModelCreating方法并添加modelBuilder.HasDefaultSchema("SchemaName");,然后执行基本构造函数,它应该像以下这样

protected override void OnModelCreating(ModelBuilder modelBuilder)   {             
  modelBuilder.HasDefaultSchema("PartyDataManager");                  
  base.OnModelCreating(modelBuilder);         
}

7

在我的情况下,数据库中的表必须是小写的...更改名称dataTable为datatable。帮助


5
请在您的回答中添加更多细节。请参考https://stackoverflow.com/help/how-to-answer获取更多详细信息。 - Rishabh Kumar

5
保持表名小写即可解决此问题。

2
一个用于在SQL语句字符串中适当引用标识符的字符串函数是quote_ident(),它引用一个不错的例子(与相关的quote_literal()一起使用)。
要使用您的示例,并混合其他结果:
select
   quote_ident(table_schema) as table_schema,
   quote_ident(table_name) as table_name
...

 table_schema |    table_name
--------------+------------------
 ...
 public       | good_name
 public       | "table"
 public       | some_table
 public       | "something else"
 public       | "Tom's work"
 public       | "TEST"
 ...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接