Valori letterali stringa e caratteri di escape in postgresql


113

Il tentativo di inserire un carattere di escape in una tabella genera un avviso.

Per esempio:

create table EscapeTest (text varchar(50));

insert into EscapeTest (text) values ('This is the first part \n And this is the second');

Produce l'avvertenza:

WARNING:  nonstandard use of escape in a string literal

( Utilizzando PSQL 8.2 )

Qualcuno sa come aggirare questo?

Risposte:


131

Parzialmente. Il testo viene inserito, ma l'avviso viene comunque generato.

Ho trovato una discussione che indicava che il testo doveva essere preceduto da "E", in quanto tale:

insert into EscapeTest (text) values (E'This is the first part \n And this is the second');

Ciò ha soppresso l'avviso, ma il testo non veniva ancora restituito correttamente. Quando ho aggiunto la barra aggiuntiva come suggerito da Michael, ha funzionato.

Come tale:

insert into EscapeTest (text) values (E'This is the first part \\n And this is the second');

5
Nota che su PostgreSQL 9.0 E'testing \\ x20double-slash 'sarà valutato come' testing \\ x20double-slash ', quindi solo l'approccio a barra singola funziona per i letterali in stile E'string'
Alexander

2
Per PostgreSQL 9.2 vedere: postgresql.org/docs/9.2/interactive/…
Pitt

psql \copynota: ho scoperto che è E'\n'stato scritto su file come '\n'anziché come una nuova riga quando l'ho usato nell'argomento query del meta-comando `\ copy 'di psql.
Stufato

40

Freddo.

Ho anche trovato la documentazione relativa alla E:

http://www.postgresql.org/docs/8.3/interactive/sql-syntax-lexical.html#SQL-SYNTAX-STRINGS

PostgreSQL accetta anche costanti di stringa "escape", che sono un'estensione dello standard SQL. Una costante stringa di escape viene specificata scrivendo la lettera E (maiuscola o minuscola) appena prima dell'apice singolo di apertura, ad esempio E'foo '. (Quando si continua una stringa di escape costante tra le righe, scrivere E solo prima della prima virgoletta di apertura.) All'interno di una stringa di escape, un carattere backslash (\) inizia una sequenza di escape backslash simile a C, in cui la combinazione di backslash e carattere successivo ( s) rappresenta un valore di byte speciale. \ b è un backspace, \ f è un avanzamento modulo, \ n è una nuova riga, \ r è un ritorno a capo, \ t è una tabulazione. Sono inoltre supportati \ digits, dove digit rappresenta un valore di byte ottale, e \ xhexdigits, dove hexdigits rappresenta un valore di byte esadecimale. (È tua responsabilità che le sequenze di byte che crei siano caratteri validi nella codifica del set di caratteri del server.) Qualsiasi altro carattere che segue una barra rovesciata viene preso letteralmente. Quindi, per includere un carattere di barra rovesciata, scrivere due barre rovesciate (\\). Inoltre, una singola virgoletta può essere inclusa in una stringa di escape scrivendo \ ', oltre al normale modo di' '.


6

L'avviso viene emesso poiché stai utilizzando i backslash nelle stringhe. Se vuoi evitare il messaggio, digita questo comando "set standard_conforming_strings = on;". Quindi usa "E" prima della tua stringa includendo i backslash che vuoi che postgresql interpreti.


1
Non proprio. Se ho standard_conforming_strings = on ed eseguo il comando \copy xxxxxxxxxxx FROM /support01/db/data/xxxxxxxxx_7F.txt DELIMITER AS E'\x7f', ottengo parse error at "'\x7f'". Se ho standard_conforming_strings = off; e utilizzare lo stesso comando sopra senza la E e le virgolette ... (DELIMITER AS \ x7f) Ricevo il messaggio di avviso, ma i dati vengono caricati correttamente. Quindi la tua affermazione potrebbe essere corretta ma non in questo caso.

Mi riferivo alle stringhe nelle istruzioni SQL, mentre ora stai usando un comando psql. Ottieni lo stesso errore usando il comando COPY invece di \ copy?
eppesuig

1
Questa è la risposta esatta. Le versioni moderne di PG ora lo hanno per impostazione predefinita.
jpmc26

3

Trovo altamente improbabile che Postgres tronchi i tuoi dati in input: li rifiuta o li archivia così come sono.

milen@dev:~$ psql
Welcome to psql 8.2.7, the PostgreSQL interactive terminal.

Type:  \copyright for distribution terms
       \h for help with SQL commands
       \? for help with psql commands
       \g or terminate with semicolon to execute query
       \q to quit

milen=> create table EscapeTest (text varchar(50));
CREATE TABLE
milen=> insert into EscapeTest (text) values ('This will be inserted \n This will not be');
WARNING:  nonstandard use of escape in a string literal
LINE 1: insert into EscapeTest (text) values ('This will be inserted...
                                              ^
HINT:  Use the escape string syntax for escapes, e.g., E'\r\n'.
INSERT 0 1
milen=> select * from EscapeTest;
          text
------------------------
 This will be inserted
  This will not be
(1 row)

milen=>

Per favore prova il caso di prova che ho fornito e lo vedrai di persona.
rjohnston

Interessante, sembra che il problema fosse nel driver JDBC allora, perché il testo in uscita dal database veniva decisamente troncato ...
rjohnston

3
Postgres fa dati troncamenti sull'ingresso in alcune situazioni particolari. Ad esempio, una character varying(4)colonna data l'input "test" (due spazi dopo la parola, 6 caratteri) troncerà gli spazi e memorizzerà il valore "test". Come regola generale, tuttavia, puoi presumere che Postgres restituirà un errore anziché troncare i tuoi dati.
Bryson

0

Domanda davvero stupida: sei sicuro che la stringa venga troncata e non solo interrotta all'interruzione di riga specificata (e che forse non venga visualizzata nella tua interfaccia)? Cioè, ti aspetti che il campo mostri come

Questo verrà inserito \ n Non lo sarà

o

Questo verrà inserito

Questo non sarà

Inoltre, quale interfaccia stai usando? È possibile che qualcosa lungo la strada stia mangiando le tue barre rovesciate?


1
questo è successo a me. Il testo veniva inserito in una casella di testo, visto la fonte e, abbastanza sicuro, c'era una citazione e l'intero testo era presente, ma non visibile
roberthuttinger
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.