使用名为“user”的表返回 PostgreSQL 中的行

Jon*_*Jon 8 postgresql

我有一张桌子叫 user

我有一些 SQL select User.* from User

这失败了,因为它User是一个保留字,但是我的印象是 Postgresql 在执行 SQL 时并不关心表的大小写,所以我认为由于保留字而存在冲突。

在数据库中,用户表是小写的,所以如果我运行这个

select * from user

我得到了一个结果,尽管奇怪的是,即使我说显示所有列,我也只返回一列。

如果我运行,select * from "user"我会得到所有列并SELECT "user".* FROM "user"返回所有列。

有人可以解释一下这是怎么回事吗?

谢谢

(使用 PostgreSQL 9.3)

Cra*_*ger 20

user 是伪函数关键字

user是 的别名current_user,一个内置的伪函数。它没有()大多数零参数函数,因为 SQL 标准委员会声明它将用于current_user. 我不知道为什么也user遵循这一点,因为我认为规范不需要它。

函数可以在 FROM 中使用

无论如何,在 PostgreSQL 中指定一个函数是合法的 from,例如

regress=> SELECT * from clock_timestamp();
        clock_timestamp        
-------------------------------
 2014-09-03 17:00:59.191019+08
(1 row)
Run Code Online (Sandbox Code Playgroud)

因为返回单个值的函数也可以在集合返回上下文中使用。

所以当你运行时:

select * from user;
Run Code Online (Sandbox Code Playgroud)

你真的在做:

select current_user;
Run Code Online (Sandbox Code Playgroud)

"quoting" 转义关键字

如果你改写它“有效”的原因"user"引用的标识符总是用户标识符,而不是关键字user是关键字;"user"是一个用户定义的标识符,它是一个合法的表名。

令人困惑,不是吗?

通常"tablename"tablename是相同的(带引号的小写和不带引号的小写),除非 tablename是关键字。

如果我们选择一个不是伪函数的关键字,这可能更有意义,因此它不是合法的语法。说:

regress=> CREATE TABLE "where" (id integer);
CREATE TABLE

regress=> CREATE TABLE where (id integer);
ERROR:  syntax error at or near "where"
LINE 1: CREATE TABLE where (id integer);
                     ^
Run Code Online (Sandbox Code Playgroud)

引用使标识符区分大小写

通常,PostgreSQL 将所有标识符大小写折叠为小写。这是 SQL 规范所要求的,尽管它实际上需要大写。所以当你:

CREATE TABLE MyTable (id integer);
Run Code Online (Sandbox Code Playgroud)

PostgreSQL 实际上创建了一个名为mytable. 但是,如果您使用"double quote"标识符,则此大小写折叠将被禁用- 同样,根据 SQL 标准。

所以原因是:

select * from "User";
Run Code Online (Sandbox Code Playgroud)

失败的是 PostgreSQL,根据 SQL 标准,将引用的标识符视为区分大小写。所以"User""USER""user"都是不同的东西。

如何避免这些问题?

不要以类型名称、函数名称等关键字命名您的表。这通常是合法的,但很少是一个好主意。

如果要使用关键字名称,则应始终 "double quote"它们放在它们出现的任何位置——事实上,养成对所有标识符简单地这样做的习惯,始终,并始终使用一致的大小写。

这里有一个关键字列表