PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Nomes de colunas com quebras de linha


Os nomes das colunas são identificadores, e os detalhes sangrentos da sintaxe para identificadores são descritos em:

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

TL;DR :use o U&"..." sintaxe para injetar caracteres não imprimíveis em identificadores por meio de seus codepoints Unicode e não há como unificar CR,LF com LF sozinho.

Como fazer referência à coluna em uma única linha


Temos permissão para usar sequências de escape Unicode em identificadores, portanto, de acordo com a documentação, o seguinte funciona:
select U&"first\000asecond" from Two;

se for apenas um caractere de nova linha entre as duas palavras.

O que acontece com as consultas na primeira tabela


A tabela é criada com:
CREATE TABLE One("first\nsecond" text);

Como o caractere de barra invertida não tem significado especial aqui, esta coluna não contém nenhuma nova linha. Ela contém first seguido por \ seguido por n seguido por second .Então:
 SELECT "first\nsecond" from One;

funciona porque é o mesmo que está no CREATE TABLE

enquanto
SELECT "first
second" from One;

falha porque há uma nova linha nesse SELECT onde o nome da coluna real na tabela tem uma barra invertida seguida por um n .

O que acontece com as consultas na segunda tabela


Este é o oposto de "Um".
CREATE TABLE Two("first
second" text);

A nova linha é tomada literalmente e faz parte da coluna.
SELECT "first
second" from Two;

funciona porque a nova linha está lá exatamente como no CREATE TABLE, com uma nova linha incorporada, enquanto
SELECT "first\nsecond" from Two;

falha porque como anteriormente \n neste contexto não significa uma nova linha.

Carriage Return seguido por Newline, ou algo mais estranho


Conforme mencionado nos comentários e na sua edição, isso pode ser retorno de carro e nova linha, caso em que o seguinte deve ser feito:
select U&"first\000d\000asecond" from Two;

embora no meu teste, pressione Enter no meio de uma coluna com psql no Unix e no Windows tem o mesmo efeito:uma única nova linha no nome da coluna.

Para verificar quais caracteres exatos acabaram em um nome de coluna, podemos inspecioná-los em hexadecimal.

Quando aplicado ao seu exemplo de criação de tabela, de dentro do psql no Unix:
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';

O resultado é:
        convert_to         
----------------------------
 \x66697273740a7365636f6e64

Para casos mais complexos (por exemplo, caracteres não ASCII com vários bytes em UTF-8), uma consulta mais avançada pode ajudar, para codepoints fáceis de ler:
select c,lpad(to_hex(ascii(c)),4,'0') from (
  select regexp_split_to_table(column_name::text,'')  as c
    from  information_schema.columns
    where table_schema='public'
    and table_name='two'
  ) as g;

 c | lpad 
---+------
 f | 0066
 i | 0069
 r | 0072
 s | 0073
 t | 0074
  +| 000a
   | 
 s | 0073
 e | 0065
 c | 0063
 o | 006f
 n | 006e
 d | 0064