带有换行符的列名

时间:2016-01-20 08:07:41

标签: postgresql

我知道,对于PostgreSQL中的文本字符串,通过在文本前添加符号Ee来统一换行符。

SELECT E'first\nsecond'

结果:

first
second

但PostgreSQL也支持列名中的换行符 - 不确定这种做法为何或如何邪恶,但可以做到以下几点:

CREATE TABLE One("first\nsecond" text);
CREATE TABLE Two("first
second" text);

当你不幸碰到其中一个时,你会发现这些查询有效:

SELECT "first\nsecond" from One;
SELECT "first
second" from Two;

这些不是:

SELECT "first
second" from One;
SELECT "first\nsecond" from Two;

我的问题是:PostgreSQL中是否有一种方法可以统一这些差异,类似于列值的情况?

我尝试将E放在"first\nsecond"列名称前面,但不支持。试图改为放置\r\n(我使用的是Windows)给了我第三种类型的列名,只能查询为:

SELECT "first\r\nsecond" FROM Third

1 个答案:

答案 0 :(得分:4)

列名称是标识符,标识符语法的血淋淋的细节描述于:

http://www.postgresql.org/docs/current/static/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS

TL; DR :使用U&"..."语法通过Unicode代码点将不可打印的字符注入标识符,并且无法将CR,LF与{{1}统一单独。

如何在一行中引用该列

我们被允许在标识符中使用Unicode转义序列,因此根据文档,以下内容确实有效:

LF

如果它只是两个单词之间的换行符。

第一个表上的查询会怎样?

该表创建于:

select U&"first\000asecond" from Two;

由于反斜杠字符在此处没有特殊含义,因此该列不包含任何换行符。 它包含CREATE TABLE One("first\nsecond" text); ,后跟first,后跟\,后跟n。 所以:

second

确实有效,因为它与 SELECT "first\nsecond" from One;

中的内容相同

,而

CREATE TABLE

失败,因为SELECT中有一个换行符,表中的实际列名称后跟一个反斜杠后跟SELECT "first second" from One;

第二个表上的查询会怎样?

这与“一”相反。

n

换行符是逐字记录的,也是专栏的一部分。 所以

CREATE TABLE Two("first
second" text);

有效,因为换行符与CREATE TABLE完全相同, 嵌入式换行符, 而

SELECT "first
second" from Two;

失败,因为之前SELECT "first\nsecond" from Two; 在此上下文中并不代表换行符。

回车后跟Newline或任何奇怪的

正如评论和编辑中所提到的,这可能是回车和换行,在这种情况下,应该做以下事情:

\n

虽然在我的测试中,在Unix和Windows上使用select U&"first\000d\000asecond" from Two; 在列的中间点击Enter具有相同的效果:列名称中有一个换行符。

要检查列名中最终的确切字符,我们可以用十六进制检查它们。

当应用于你的create table示例时,来自Unix下的psql内部:

psql

结果是:

CREATE TABLE Two("first
second" text);

select convert_to(column_name::text,'UTF-8')
 from information_schema.columns 
 where table_schema='public'
   and table_name='two';

对于更复杂的情况(例如,UTF-8中包含多个字节的非ascii字符),对于易于阅读的代码点,更高级的查询可能会有所帮助:

        convert_to         
----------------------------
 \x66697273740a7365636f6e64