PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Nomi di colonna con interruzioni di riga

I nomi delle colonne sono identificatori e i dettagli cruenti della sintassi per gli identificatori sono descritti in:

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

TL;DR :usa U&"..." sintassi per iniettare caratteri non stampabili negli identificatori tramite i loro codepoint Unicode e non c'è modo di unificare CR,LF con LF da solo.

Come fare riferimento alla colonna in una sola riga

Siamo autorizzati a utilizzare sequenze di escape Unicode negli identificatori, quindi per documentazione, quanto segue funziona:

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

se è solo un carattere di nuova riga tra le due parole.

Cosa succede con le query sulla prima tabella

La tabella viene creata con:

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

Poiché il carattere della barra rovesciata non ha un significato speciale qui, questa colonna non contiene alcuna nuova riga. Contiene first seguito da \ seguito da n seguito da second .Quindi:

 SELECT "first\nsecond" from One;

funziona perché è lo stesso di quello che c'è in CREATE TABLE

mentre

SELECT "first
second" from One;

fallisce perché c'è una nuova riga in quel SELECT in cui il nome effettivo della colonna nella tabella ha una barra rovesciata seguita da un n .

Cosa succede con le query sulla seconda tabella

Questo è l'opposto di "Uno".

CREATE TABLE Two("first
second" text);

La nuova riga viene presa alla lettera e fa parte della colonna. Quindi

SELECT "first
second" from Two;

funziona perché la nuova riga è lì esattamente come in CREATE TABLE, con una nuova riga incorporata, mentre

SELECT "first\nsecond" from Two;

fallisce perché come in precedenza \n in questo contesto non significa una nuova riga.

Ritorno a bordo seguito da Newline, o qualcosa di più strano

Come menzionato nei commenti e nella tua modifica, questo potrebbe essere invece il ritorno a capo e la nuova riga, nel qual caso dovresti fare quanto segue:

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

anche se nel mio test, premendo Invio nel mezzo di una colonna con psql su Unix e Windows ha lo stesso effetto:una sola nuova riga nel nome della colonna.

Per verificare quali caratteri esatti sono finiti nel nome di una colonna, possiamo esaminarli in esadecimale.

Quando applicato al tuo esempio di tabella di creazione, da psql in 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';

Il risultato è:

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

Per casi più complessi (ad es. caratteri non ascii con diversi byte in UTF-8), potrebbe essere utile una query più avanzata, per punti di codice di facile lettura:

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