String literal dan karakter escape di postgresql


113

Mencoba memasukkan karakter escape ke dalam tabel akan menghasilkan peringatan.

Sebagai contoh:

create table EscapeTest (text varchar(50));

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

Menghasilkan peringatan:

WARNING:  nonstandard use of escape in a string literal

( Menggunakan PSQL 8.2 )

Ada yang tahu bagaimana menyiasati ini?

Jawaban:


131

Sebagian. Teks sudah dimasukkan, tetapi peringatan masih dibuat.

Saya menemukan sebuah diskusi yang mengindikasikan teks harus diawali dengan 'E', seperti:

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

Ini menekan peringatan, tetapi teks masih belum dikembalikan dengan benar. Ketika saya menambahkan garis miring tambahan seperti yang disarankan Michael, itu berhasil.

Dengan demikian:

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

5
Perhatikan bahwa pada PostgreSQL 9.0 E'testing \\ x20double-slash 'akan dievaluasi sebagai' testing \\ x20double-slash ', jadi hanya pendekatan garis miring tunggal yang berfungsi untuk literal gaya E'string'
Alexander

2
Untuk PostgreSQL 9.2 lihat: postgresql.org/docs/9.2/interactive/…
Pitt

psql \copycatatan: Saya menemukan bahwa E'\n'itu ditulis ke file '\n'daripada sebagai baris baru ketika saya menggunakannya dalam argumen kueri ke perintah meta `\ copy 'psql.
Rebus

40

Keren.

Saya juga menemukan dokumentasi tentang E:

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

PostgreSQL juga menerima konstanta string "escape", yang merupakan ekstensi dari standar SQL. Konstanta string escape ditentukan dengan menulis huruf E (huruf besar atau kecil) tepat sebelum kutipan tunggal pembuka, misalnya E'foo '. (Saat melanjutkan konstanta string escape melintasi baris, tulis E hanya sebelum kutipan pembuka pertama.) Dalam string escape, karakter garis miring terbalik (\) memulai urutan escape seperti garis miring terbalik C, di mana kombinasi garis miring terbalik dan karakter berikut ( s) mewakili nilai byte khusus. \ b adalah spasi mundur, \ f adalah umpan formulir, \ n adalah baris baru, \ r adalah carriage return, \ t adalah tab. Juga didukung adalah \ digit, di mana digit mewakili nilai byte oktal, dan \ xhexdigits, di mana heksadesimal mewakili nilai byte heksadesimal. (Ini adalah tanggung jawab Anda bahwa urutan byte yang Anda buat adalah karakter yang valid dalam pengkodean kumpulan karakter server.) Karakter lain apa pun setelah garis miring terbalik diambil secara harfiah. Jadi, untuk memasukkan karakter garis miring terbalik, tulis dua garis miring terbalik (\\). Selain itu, satu kutipan dapat dimasukkan ke dalam string escape dengan menulis \ ', selain cara normal' '.


6

Peringatan dikeluarkan karena Anda menggunakan garis miring terbalik di string Anda. Jika Anda ingin menghindari pesan tersebut, ketik perintah ini "set standard_conforming_strings = on;". Kemudian gunakan "E" sebelum string Anda termasuk garis miring terbalik yang Anda ingin postgresql ke intrepret.


1
Tidak juga. Jika saya memiliki standard_conforming_strings = on dan menjalankan perintah \copy xxxxxxxxxxx FROM /support01/db/data/xxxxxxxxx_7F.txt DELIMITER AS E'\x7f', saya mengerti parse error at "'\x7f'". Jika saya memiliki standard_conforming_strings = off; dan menggunakan perintah yang sama di atas tanpa E dan Kutipan ... (DELIMITER AS \ x7f) Saya mendapatkan pesan peringatan, tetapi data dimuat dengan baik. Jadi pernyataan Anda mungkin benar tetapi tidak dalam kasus ini.

Saya mengacu pada string dalam pernyataan SQL, sementara Anda sekarang menggunakan perintah psql. Apakah Anda mendapatkan kesalahan yang sama menggunakan perintah COPY daripada \ copy?
eppesuig

1
Ini adalah jawaban yang benar. Versi modern PG sekarang default untuk mengaktifkannya.
jpmc26

3

Saya merasa sangat tidak mungkin bagi Postgres untuk memotong data Anda pada input - itu menolak atau menyimpannya apa adanya.

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=>

Silakan coba kasus uji yang saya berikan dan Anda akan melihatnya sendiri.
rjohnston

Menarik, sepertinya masalahnya ada di driver JDBC saat itu, karena teks yang keluar dari database pasti terpotong ...
rjohnston

3
Postgres melakukan Data truncate masukan dalam beberapa situasi yang sangat spesifik. Misalnya, character varying(4)kolom yang diberi input "test" (dua spasi setelah kata, 6 karakter) akan memotong spasi dan menyimpan nilai "test". Sebagai aturan umum, bagaimanapun, Anda dapat berasumsi bahwa Postgres akan error daripada memotong data Anda.
Bryson

0

Pertanyaan yang benar-benar bodoh: Apakah Anda yakin string sedang terpotong, dan tidak hanya putus pada pemutusan baris yang Anda tentukan (dan mungkin tidak muncul di antarmuka Anda)? Yaitu, apakah Anda mengharapkan bidang ditampilkan sebagai

Ini akan disisipkan \ n Ini tidak akan

atau

Ini akan disisipkan

Ini tidak akan terjadi

Juga, antarmuka apa yang Anda gunakan? Mungkinkah sesuatu di sepanjang jalan memakan garis miring terbalik Anda?


1
ini terjadi pada saya. Teks itu dimasukkan ke dalam kotak teks, dilihat sumbernya, dan tentu saja, ada kutipan dan seluruh teks ada, hanya tidak terlihat
roberthuttinger
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.