Postgresql'de dize değişmezleri ve kaçış karakterleri


113

Tabloya bir çıkış karakteri eklemeye çalışmak bir uyarı ile sonuçlanır.

Örneğin:

create table EscapeTest (text varchar(50));

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

Şu uyarıyı üretir:

WARNING:  nonstandard use of escape in a string literal

( PSQL 8.2 kullanarak )

Bunu nasıl aşacağını bilen var mı?

Yanıtlar:


131

Kısmen. Metin eklenir, ancak uyarı yine de üretilir.

Metnin önünde "E" olması gerektiğini belirten bir tartışma buldum, örneğin:

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

Bu, uyarıyı bastırdı, ancak metin hala doğru şekilde döndürülmüyordu. Michael'ın önerdiği ek eğik çizgiyi eklediğimde işe yaradı.

Gibi:

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

5
PostgreSQL 9.0'da E'testing \\ x20double bölü çizgisinin 'test \\ x20double bölü çizgisi' olarak değerlendirileceğini unutmayın, bu nedenle yalnızca tek eğik çizgi yaklaşımı E'string 'stili değişmezler için çalışır
Alexander

2
PostgreSQL 9.2 için bakınız: postgresql.org/docs/9.2/interactive/…
Pitt

psql \copynot: psql'nin `\ copy 'meta komutundaki sorgu bağımsız değişkeninde kullandığımda bunun satırsonu E'\n'olarak '\n'değil dosyaya yazıldığını buldum .
Stew

40

Güzel.

Ayrıca E ile ilgili belgeleri buldum:

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

PostgreSQL ayrıca SQL standardının bir uzantısı olan "escape" dizge sabitlerini de kabul eder. Bir kaçış dizesi sabiti, açılış tek tırnaktan hemen önce E harfini (büyük veya küçük harf) yazarak belirlenir, örneğin E'foo '. (Bir kaçış dizesi sabitini satırlar arasında devam ettirirken, yalnızca ilk açılış teklifinden önce E yazın.) Bir çıkış dizesi içinde, ters eğik çizgi karakteri (\), ters eğik çizgi ile izleyen karakter kombinasyonunun ( s) özel bir bayt değerini temsil eder. \ b bir backspace, \ f bir form beslemesidir, \ n bir satırsonu, \ r bir satır başı, \ t bir sekmedir. Ayrıca sayıların sekizlik bir bayt değerini temsil ettiği \ basamakları ve onaltılıkların onaltılık bir bayt değerini temsil ettiği \ xhexdigits desteklenir. (Oluşturduğunuz bayt dizilerinin sunucu karakter seti kodlamasında geçerli karakterler olması sizin sorumluluğunuzdadır.) Ters eğik çizgiyi takip eden diğer herhangi bir karakter harfi harfine alınır. Bu nedenle, bir ters eğik çizgi karakteri eklemek için iki ters eğik çizgi (\\) yazın. Ayrıca, normal yolun yanı sıra \ 'yazarak bir kaçış dizgesine tek bir alıntı eklenebilir.


6

Dizelerinizde ters eğik çizgi kullandığınız için uyarı verilir. Mesajdan kaçınmak istiyorsanız, "set standard_conforming_strings = on;" bu komutu yazın. Sonra postgresql'nin yorumlamasını istediğiniz ters eğik çizgileri içeren dizenizden önce "E" kullanın.


1
Pek sayılmaz. Standard_conforming_strings = açıksa ve komutu çalıştırırsam, \copy xxxxxxxxxxx FROM /support01/db/data/xxxxxxxxx_7F.txt DELIMITER AS E'\x7f'alırım parse error at "'\x7f'". Standard_conforming_strings = kapalı ise; ve E ve Quotes olmadan yukarıdaki aynı komutu kullanın ... (DELIMITER AS \ x7f) Uyarı mesajını alıyorum, ancak veri düzgün yükleniyor. Yani ifadeniz doğru olabilir ama bu durumda değil.

Siz şimdi bir psql komutunu kullanırken, SQL ifadelerindeki dizelerden bahsediyordum. \ Copy yerine COPY komutunu kullanırken aynı hatayı mı alıyorsunuz?
eppesuig

1
Bu doğru cevap. Modern PG sürümleri artık varsayılan olarak açık durumda.
jpmc26

3

Postgres'in verilerinizi girişte kesmesini pek olası bulmuyorum - ya reddediyor ya da olduğu gibi saklıyor.

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

Lütfen verdiğim test senaryosunu deneyin, kendiniz göreceksiniz.
rjohnston

İlginç, o zamanlar sorun JDBC sürücüsündeymiş gibi görünüyor, çünkü veritabanından çıkan metin kesinlikle kesiliyordu ...
rjohnston

3
Postgres , bazı çok özel durumlarda girişteki verileri keser. Örneğin, character varying(4)"test" girişi verilen bir sütun (kelimeyi takip eden iki boşluk, 6 karakter) boşlukları kısaltacak ve "test" değerini saklayacaktır. Ancak genel bir kural olarak, Postgres'in verilerinizi kesmek yerine hata vereceğini varsayabilirsiniz.
Bryson

0

Gerçekten aptalca bir soru: Dizenin kesildiğinden ve yalnızca belirttiğiniz satır kesmesinde kırılmadığından (ve muhtemelen arayüzünüzde gösterilmediğinden) emin misiniz? Yani, alanın şu şekilde görünmesini bekliyor musunuz?

Bu eklenecek \ n Bu eklenmeyecek

veya

Bu eklenecek

Bu olmayacak

Ayrıca, hangi arayüzü kullanıyorsunuz? Yol boyunca bir şey ters eğik çizgilerinizi yiyor olabilir mi?


1
bu bana oldu. Metin bir metin kutusuna giriliyor, kaynak görüntüleniyordu ve kesinlikle bir alıntı vardı ve metnin tamamı mevcuttu, sadece görünmüyordu
roberthuttinger
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.