Literały tekstowe i znaki ucieczki w postgresql

113

Próba wstawienia znaku zmiany znaczenia do tabeli powoduje wyświetlenie ostrzeżenia.

Na przykład:

create table EscapeTest (text varchar(50));

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

Powoduje ostrzeżenie:

WARNING:  nonstandard use of escape in a string literal

( Przy użyciu PSQL 8.2 )

Czy ktoś wie, jak to obejść?

rjohnston
źródło

Odpowiedzi:

131

Częściowo. Tekst został wstawiony, ale ostrzeżenie jest nadal generowane.

Znalazłem dyskusję, w której wskazano, że tekst powinien być poprzedzony literą „E”, jako taki:

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

To pomijało ostrzeżenie, ale tekst nadal nie był zwracany poprawnie. Kiedy dodałem dodatkowy ukośnik zgodnie z sugestią Michaela, zadziałało.

Takie jak:

insert into EscapeTest (text) values (E'This is the first part \\n And this is the second');
rjohnston
źródło
5
Zauważ, że w PostgreSQL 9.0 E'testing \\ x20double-slash 'zostanie ocenione jako' testing \\ x20double-slash ', więc tylko podejście z pojedynczym ukośnikiem działa dla literałów w stylu E'string
Alexander
2
Dla PostgreSQL 9.2 zobacz: postgresql.org/docs/9.2/interactive/…
Pitt
psql \copyuwaga: stwierdziłem, że E'\n'zostało to zapisane w pliku '\n'zamiast jako nowa linia, kiedy użyłem go w argumencie zapytania do meta-polecenia psql `\ copy '.
Gulasz
40

Chłodny.

Znalazłem też dokumentację dotyczącą E:

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

PostgreSQL akceptuje również stałe łańcuchowe „escape”, które są rozszerzeniem standardu SQL. Stała łańcuchowa zmiany znaczenia jest określana przez wpisanie litery E (duża lub mała litera) tuż przed otwierającym pojedynczym cudzysłowem, np. E'foo '. (Kontynuując ciąg znaków zmiany znaczenia w wierszach, napisz E tylko przed pierwszym cudzysłowem otwierającym.) W ciągu znaków sterujących odwrotnym ukośnikiem (\) rozpoczyna sekwencję ucieczki odwrotnego ukośnika podobną do litery C, w której kombinacja ukośnika odwrotnego i następującego po nim znaku ( s) reprezentuje specjalną wartość bajtu. \ b to cofnięcie, \ f to wysuw strony, \ n to nowa linia, \ r to powrót karetki, \ t to tabulator. Obsługiwane są również \ cyfry, gdzie cyfry reprezentują ósemkową wartość bajtu, oraz \ xhexdigits, gdzie cyfry szesnastkowe reprezentują szesnastkową wartość bajtu. (Twoim obowiązkiem jest, aby utworzone sekwencje bajtów były poprawnymi znakami w kodowaniu zestawu znaków serwera). Każdy inny znak następujący po odwrotnym ukośniku jest traktowany dosłownie. Dlatego, aby dołączyć znak ukośnika odwrotnego, napisz dwa ukośniki odwrotne (\\). Ponadto pojedynczy cudzysłów można zawrzeć w ciągu znaków sterujących, pisząc \ ', oprócz zwykłego znaku' '.

Michael Stum
źródło
6

Ostrzeżenie jest generowane, ponieważ używasz odwrotnych ukośników w łańcuchach. Jeśli chcesz uniknąć tego komunikatu, wpisz polecenie „set standard_conforming_strings = on;”. Następnie użyj „E” przed łańcuchem, włączając ukośniki odwrotne, które postgresql ma zinterpretować.

eppesuig
źródło
1
Nie całkiem. Jeśli mam standard_conforming_strings = on i uruchomię polecenie \copy xxxxxxxxxxx FROM /support01/db/data/xxxxxxxxx_7F.txt DELIMITER AS E'\x7f', otrzymam parse error at "'\x7f'". Jeśli mam standard_conforming_strings = off; i użyj tego samego polecenia powyżej bez E i cudzysłowów ... (DELIMITER AS \ x7f) Otrzymuję komunikat ostrzegawczy, ale dane ładują się dobrze. Więc twoje stwierdzenie może być poprawne, ale nie w tym przypadku.
Odnosiłem się do ciągów znaków w instrukcjach SQL, podczas gdy teraz używasz polecenia psql. Czy ten sam błąd pojawia się przy użyciu polecenia COPY zamiast \ copy?
eppesuig
1
To jest właściwa odpowiedź. Nowoczesne wersje PG mają teraz domyślnie włączone.
jpmc26
3

Uważam, że jest bardzo mało prawdopodobne, aby Postgres obcinał dane wejściowe - albo je odrzuca, albo przechowuje tak, jak jest.

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=>
Milen A. Radev
źródło
Wypróbuj przykład testowy, który podałem, a zobaczysz to na własne oczy.
rjohnston,
Ciekawe, wygląda na to, że problem
tkwił
3
Postgres nie obciąć dane dotyczące wejścia w pewnych bardzo specyficznych sytuacjach. Na przykład character varying(4)kolumna, która ma dane wejściowe „test” (dwie spacje po słowie, 6 znaków) obetnie spacje i zapisze wartość „test”. Z reguły jednak można założyć, że Postgres będzie raczej mylić, niż obcinać dane.
Bryson
0

Naprawdę głupie pytanie: czy jesteś pewien, że ciąg jest obcinany, a nie tylko przerywany w określonym przez ciebie podziale linii (i prawdopodobnie nie pojawia się w twoim interfejsie)? To znaczy, czy spodziewasz się, że pole będzie wyświetlane jako

To zostanie wstawione \ n To nie będzie

lub

To zostanie wstawione

To nie będzie

Jakiego interfejsu używasz? Czy to możliwe, że coś po drodze zjada twoje ukośne ukośne?

Społeczność
źródło
1
to mi się przydarzyło. Tekst był wstawiany do pola tekstowego, przeglądał źródło i
oczywiście