魔术列“名称”从何而来?


11

我是偶然得到的:

db=> select name from site;
ERROR:  column "name" does not exist
LINE 1: select name from site;
               ^
db=> select site.name from site;
     name
---------------
 (1,mysitename)
(1 row)

第二个查询返回一个包含整行的元组。使用Postgres 9.0.1。

编辑:按要求定义站点。我并不重要,这个怪癖适用于任何桌子。

db=> \d site
                         Table "public.site"
 Column |  Type   |                     Modifiers
--------+---------+---------------------------------------------------
 id     | integer | not null default nextval('site_id_seq'::regclass)
 title  | text    | not null

这将有助于显示的定义site
Peter Eisentraut 2011年

〜这问题,因为现在我们可以看到,有没有“名”的site开始。为什么要查询不存在的列?
jcolebrand

1
试试select site from site-这将帮助您更详细地了解盖乌斯的答案
杰克说请尝试topanswers.xyz 2011年

Answers:


11

NAME实际上是一个功能。Postgres的一个怪癖是带有一个参数的函数function(arg)也可以称为arg.function。从文档:

功能符号和属性符号之间的等效关系使得可以使用复合类型上的函数来模拟“计算字段”。

NAME对象名称内部类型,此函数将其参数强制转换为该类型并返回它。


谢谢,我不知道。如果在任何地方都记录了此特定功能“名称”,那令我困扰吗?
hegemon

更新了我的答案
Gaius

2
更确切地说,row类型被强制转换text为函数的输入类型namename然后,该函数将输入字符串转换(而不强制转换)为类型name(这也会产生截断为64个字节的副作用)
杰克说,请尝试topanswers.xyz 2011年

3

另请注意,在PostgreSQL 8.3中删除了隐式转换为name的操作,这意味着此行为不再起作用。在PostgreSQL 8.3及更高版本中,几乎不可能意外地获得此行为,因为元组不会自动转换为文本。

因此在9.1中:

or_examples=# select c.name from comp_table_test c;
ERROR:  column c.name does not exist
LINE 1: select c.name from comp_table_test c;

但是要获得这种行为,我们必须:

or_examples=# select name(c::text) from comp_table_test c;

或者,我们可以定义自己的名称函数,输入comp_table_test类型并返回我们想要的任何内容。


我不明白这个答案。您是说,上面提出的问题在8.3或更高版本上应该不再是问题了?但是问题是大约9.0
Colin't Hart 2014年

0

“名称”是保留的关键字。因此,您应该“引用”关键字以使用它:

SELECT "name" FROM site;

过去,这已经为我解决了其中一些问题,尽管您发布的代码也可以不加引用地工作。另一方面

select site.name from site;

之所以说这个字,是因为您明确地使用该模式来解析列的名称


1
可以使用很多保留字,在这种情况下,引用无济于事。这是因为如果site.name不作为一列存在,那么在8.3之前的版本中,您将开始寻找使用站点数据类型从站点隐式转换的类型的名称函数。由于site可以隐式转换为文本,因此将使用name(text)。因此,select site.name from site可能会隐式转换成select name(site::text) from site魔术来自何处。
克里斯·特拉弗斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.