Chuỗi ký tự và ký tự thoát trong postgresql


113

Cố gắng chèn một ký tự thoát vào bảng dẫn đến một cảnh báo.

Ví dụ:

create table EscapeTest (text varchar(50));

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

Đưa ra cảnh báo:

WARNING:  nonstandard use of escape in a string literal

( Sử dụng PSQL 8.2 )

Bất cứ ai biết làm thế nào để có được xung quanh điều này?

Câu trả lời:


131

Một phần. Văn bản được chèn vào, nhưng cảnh báo vẫn được tạo ra.

Tôi đã tìm thấy một cuộc thảo luận chỉ ra văn bản cần được đặt trước bằng 'E', chẳng hạn như:

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

Điều này đã dập tắt cảnh báo, nhưng văn bản vẫn không được trả lại chính xác. Khi tôi thêm dấu gạch chéo bổ sung như Michael đề xuất, nó đã hoạt động.

Như vậy:

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

5
Lưu ý rằng trên PostgreSQL 9.0 E'testing \\ x20double-slash 'sẽ đánh giá là 'thử nghiệm \\ x20double-slash', vì vậy chỉ đơn slash công trình tiếp cận để E'string' literals phong cách
Alexander

2
Đối với PostgreSQL 9.2 xem: postgresql.org/docs/9.2/interactive/...
Pitt

psql \copylưu ý: Tôi thấy rằng nó E'\n'được ghi vào tệp '\n'thay vì dưới dạng dòng mới khi tôi sử dụng nó trong đối số truy vấn cho lệnh meta `` \ copy 'của psql.
Hầm

40

Mát mẻ.

Tôi cũng tìm thấy tài liệu liên quan đến E:

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

PostgreSQL cũng chấp nhận các hằng số chuỗi "thoát", là một phần mở rộng cho tiêu chuẩn SQL. Hằng số chuỗi thoát được chỉ định bằng cách viết chữ E (viết hoa hoặc viết thường) ngay trước dấu nháy đơn mở đầu, ví dụ: E'foo '. (Khi tiếp tục một chuỗi thoát liên tục trên các dòng, chỉ viết E trước dấu ngoặc kép đầu tiên.) Trong chuỗi thoát, một ký tự gạch chéo ngược (\) bắt đầu chuỗi thoát dấu gạch chéo ngược giống C, trong đó sự kết hợp của dấu gạch chéo ngược và ký tự sau ( s) đại diện cho một giá trị byte đặc biệt. \ b là dấu cách lùi, \ f là nguồn cấp biểu mẫu, \ n là dòng mới, \ r là dấu xuống dòng, \ t là tab. Cũng được hỗ trợ là \ chữ số, trong đó chữ số biểu thị giá trị byte bát phân và \ xhexdigits, trong đó chữ số lục phân biểu thị giá trị byte thập lục phân. (Trách nhiệm của bạn là các chuỗi byte bạn tạo là các ký tự hợp lệ trong mã hóa bộ ký tự máy chủ.) Bất kỳ ký tự nào khác theo sau dấu gạch chéo ngược được hiểu theo nghĩa đen. Do đó, để bao gồm một ký tự dấu gạch chéo ngược, hãy viết hai dấu gạch chéo ngược (\\). Ngoài ra, một trích dẫn duy nhất có thể được đưa vào chuỗi thoát bằng cách viết \ ', ngoài cách viết bình thường là' '.


6

Cảnh báo được đưa ra vì bạn đang sử dụng dấu gạch chéo ngược trong chuỗi của mình. Nếu bạn muốn tránh thông báo, hãy gõ lệnh này "set standard_conforming_strings = on;". Sau đó, sử dụng "E" trước chuỗi của bạn bao gồm cả dấu gạch chéo ngược mà bạn muốn postgresql diễn giải.


1
Không hẳn. Nếu tôi bật standard_conforming_strings = và chạy lệnh \copy xxxxxxxxxxx FROM /support01/db/data/xxxxxxxxx_7F.txt DELIMITER AS E'\x7f', tôi nhận được parse error at "'\x7f'". Nếu tôi có standard_conforming_strings = off; và sử dụng lệnh tương tự ở trên mà không có E và Dấu ngoặc kép ... (DELIMITER AS \ x7f) Tôi nhận được thông báo cảnh báo, nhưng dữ liệu tải tốt. Vì vậy câu nói của bạn có thể đúng nhưng không đúng trong trường hợp này.

Tôi đã đề cập đến chuỗi trong câu lệnh SQL, trong khi bạn đang sử dụng lệnh psql. Bạn có gặp lỗi tương tự khi sử dụng lệnh COPY thay vì \ copy không?
eppesuig

1
Đây là câu trả lời đúng. Các phiên bản PG hiện đại bây giờ được mặc định là có bật nó.
jpmc26

3

Tôi thấy rất khó để Postgres cắt bớt dữ liệu của bạn khi nhập - nó từ chối hoặc lưu trữ nguyên trạng.

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

Hãy thử trường hợp thử nghiệm tôi đưa ra và bạn sẽ thấy nó cho chính mình.
rjohnston 22/09/08

Thú vị, trông giống như vấn đề là trong trình điều khiển JDBC sau đó, vì văn bản ra khỏi cơ sở dữ liệu đã được rất chắc chắn bị cắt ngắn ...
rjohnston

3
Postgres làm dữ liệu truncate trên đầu vào trong một số tình huống rất cụ thể. Ví dụ: một character varying(4)cột có đầu vào là "test" (hai khoảng trắng theo sau từ, 6 ký tự) sẽ cắt bớt khoảng trắng và lưu trữ giá trị "test". Tuy nhiên, theo nguyên tắc chung, bạn có thể cho rằng Postgres sẽ báo lỗi hơn là cắt bớt dữ liệu của bạn.
Bryson

0

Câu hỏi thực sự ngu ngốc: Bạn có chắc chắn chuỗi đang bị cắt ngắn và không chỉ bị đứt ở dấu ngắt dòng mà bạn chỉ định (và có thể không hiển thị trong giao diện của bạn) không? Tức là, bạn có mong đợi trường hiển thị như

Cái này sẽ được chèn \ n Cái này sẽ không được

hoặc là

Điều này sẽ được chèn

Điều này sẽ không

Ngoài ra, bạn đang sử dụng giao diện nào? Có thể nào đó trên đường đi đang ăn mòn dấu gạch chéo ngược của bạn?


1
điều này đã xảy ra với tôi. Các văn bản đã được chèn vào một hộp văn bản, xem nguồn, và chắc chắn đủ, đã có một báo giá và toàn bộ văn bản đã có mặt, chỉ cần không nhìn thấy được
roberthuttinger
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.