sql >> Base de Datos >  >> RDS >> PostgreSQL

Nombres de columna con saltos de línea

Los nombres de las columnas son identificadores, y los detalles sangrientos de la sintaxis de los identificadores se describen en:

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

TL;RD :utilice la U&"..." sintaxis para inyectar caracteres no imprimibles en identificadores a través de sus puntos de código Unicode, y no hay forma de unificar CR,LF con LF solo.

Cómo hacer referencia a la columna en una sola línea

Se nos permite usar secuencias de escape Unicode en identificadores, por lo que según la documentación, lo siguiente funciona:

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

si es solo un carácter de nueva línea entre las dos palabras.

Qué sucede con las consultas en la primera tabla

La tabla se crea con:

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

Como el carácter de barra invertida no tiene un significado especial aquí, esta columna no contiene ninguna nueva línea. Contiene first seguido de \ seguido de n seguido de second .Entonces:

 SELECT "first\nsecond" from One;

funciona porque es lo mismo que lo que está en CREATE TABLE

mientras que

SELECT "first
second" from One;

falla porque hay una nueva línea en ese SELECT donde el nombre real de la columna en la tabla tiene una barra invertida seguida de un n .

Qué sucede con las consultas en la segunda tabla

Esto es lo opuesto a "Uno".

CREATE TABLE Two("first
second" text);

La nueva línea se toma literalmente y es parte de la columna. Entonces

SELECT "first
second" from Two;

funciona porque la nueva línea está allí exactamente como en CREATE TABLE, con una nueva línea incrustada, mientras que

SELECT "first\nsecond" from Two;

falla porque como anteriormente \n en este contexto no significa una nueva línea.

Retorno de carro seguido de Nueva línea, o algo más extraño

Como se mencionó en los comentarios y su edición, esto podría ser un retorno de carro y una nueva línea, en cuyo caso debería funcionar lo siguiente:

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

aunque en mi prueba, presione Entrar en medio de una columna con psql en Unix y Windows tiene el mismo efecto:una sola línea nueva en el nombre de la columna.

Para verificar qué caracteres exactos terminaron en un nombre de columna, podemos inspeccionarlos en hexadecimal.

Cuando se aplica a su ejemplo de creación de tabla, desde dentro de psql en 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';

El resultado es:

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

Para casos más complejos (por ejemplo, caracteres que no son ascii con varios bytes en UTF-8), una consulta más avanzada podría ayudar, para puntos de código fáciles de leer:

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