สตริงลิเทอรัลและอักขระ Escape ใน postgresql


113

การพยายามแทรกอักขระหลีกลงในตารางจะทำให้เกิดคำเตือน

ตัวอย่างเช่น:

create table EscapeTest (text varchar(50));

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

สร้างคำเตือน:

WARNING:  nonstandard use of escape in a string literal

( โดยใช้ PSQL 8.2.2 )

ใครทราบวิธีการแก้ไขปัญหานี้

คำตอบ:


131

บางส่วน ข้อความถูกแทรก แต่ยังคงสร้างคำเตือน

ฉันพบการสนทนาที่ระบุข้อความที่ต้องนำหน้าด้วย 'E' ดังต่อไปนี้:

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

การดำเนินการนี้ระงับคำเตือน แต่ข้อความยังไม่ถูกส่งกลับอย่างถูกต้อง เมื่อฉันเพิ่มเครื่องหมายทับตามที่ Michael แนะนำมันก็ใช้ได้

ดังต่อไปนี้:

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

5
โปรดทราบว่าใน PostgreSQL 9.0 E'testing \\ x20double-slash 'จะประเมินเป็น' testing \\ x20double-slash 'ดังนั้นวิธี single-slash เท่านั้นที่ใช้ได้กับตัวอักษรสไตล์ E'string
Alexander

2
สำหรับ PostgreSQL 9.2 โปรดดู: postgresql.org/docs/9.2/interactive/…
Pitt

psql \copyหมายเหตุ: ฉันพบว่าE'\n'มีการเขียนลงในไฟล์'\n'แทนที่จะเป็นบรรทัดใหม่เมื่อฉันใช้ในอาร์กิวเมนต์เคียวรีกับคำสั่งเมตาดาต้า `` คัดลอก 'ของ psql
สตูว์

40

เย็น.

ฉันยังพบเอกสารเกี่ยวกับ E:

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

PostgreSQL ยังยอมรับค่าคงที่ของสตริง "escape" ซึ่งเป็นส่วนขยายของมาตรฐาน SQL ค่าคงที่ของสตริง Escape ถูกระบุโดยการเขียนตัวอักษร E (ตัวพิมพ์ใหญ่หรือตัวพิมพ์เล็ก) ก่อนเครื่องหมายคำพูดเดี่ยวเปิดเช่น E'foo ' (เมื่อดำเนินการต่อค่าคงที่ของสตริง Escape ข้ามบรรทัดให้เขียน E ก่อนเครื่องหมายคำพูดเปิดแรกเท่านั้น) ภายในสตริง Escape อักขระแบ็กสแลช (\) เริ่มต้นลำดับการหลีกเลี่ยงแบ็กสแลชแบบ C ซึ่งการรวมกันของแบ็กสแลชและอักขระต่อไปนี้ ( s) แทนค่าไบต์พิเศษ \ b คือ backspace \ f คือฟีดฟอร์ม \ n คือขึ้นบรรทัดใหม่ \ r คือการส่งคืนค่าขนส่ง \ t คือแท็บ นอกจากนี้ยังได้รับการสนับสนุนคือ \ หลักโดยที่ตัวเลขแทนค่าไบต์ฐานแปดและ \ xhexdigits โดยที่เลขฐานสิบหกหมายถึงค่าไบต์ฐานสิบหก (เป็นความรับผิดชอบของคุณที่ลำดับไบต์ที่คุณสร้างเป็นอักขระที่ถูกต้องในการเข้ารหัสชุดอักขระเซิร์ฟเวอร์) อักขระอื่น ๆ ที่ตามหลังเครื่องหมายแบ็กสแลชจะถูกยึดตามตัวอักษร ดังนั้นหากต้องการรวมอักขระแบ็กสแลชให้เขียนแบ็กสแลชสองตัว (\\) นอกจากนี้คุณสามารถใส่เครื่องหมายคำพูดเดี่ยวในสตริง Escape ได้โดยการเขียน \ 'นอกเหนือจากวิธีปกติของ' '


6

คำเตือนจะออกเมื่อคุณใช้แบ็กสแลชในสตริงของคุณ หากคุณต้องการหลีกเลี่ยงข้อความให้พิมพ์คำสั่งนี้ "set standard_conforming_strings = on;" จากนั้นใช้ "E" นำหน้าสตริงของคุณรวมถึงแบ็กสแลชที่คุณต้องการให้ postgresql intrepret


1
ไม่จริง ถ้าผมมี standard_conforming_strings = และเรียกใช้คำสั่งฉันได้รับ\copy xxxxxxxxxxx FROM /support01/db/data/xxxxxxxxx_7F.txt DELIMITER AS E'\x7f' parse error at "'\x7f'"ถ้าฉันมี standard_conforming_strings = off; และใช้คำสั่งเดียวกันข้างต้นโดยไม่มี E และเครื่องหมายคำพูด ... (DELIMITER AS \ x7f) ฉันได้รับข้อความเตือน แต่ข้อมูลโหลดได้ดี ดังนั้นคำชี้แจงของคุณอาจถูกต้อง แต่ไม่ใช่ในกรณีนี้

ฉันอ้างถึงสตริงในคำสั่ง SQL ในขณะที่คุณกำลังใช้คำสั่ง psql คุณได้รับข้อผิดพลาดเดียวกันโดยใช้คำสั่ง COPY แทน \ copy หรือไม่?
eppesuig

1
นี่คือคำตอบที่ใช่ ตอนนี้ PG เวอร์ชันสมัยใหม่เริ่มต้นที่จะเปิดใช้งาน
jpmc26

3

ฉันคิดว่ามันไม่น่าเป็นไปได้อย่างมากที่ Postgres จะตัดทอนข้อมูลของคุณในการป้อนข้อมูล - มันอาจจะปฏิเสธหรือจัดเก็บตามที่เป็นอยู่

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

โปรดลองทดสอบกรณีที่ฉันให้แล้วคุณจะเห็นด้วยตัวคุณเอง
rjohnston

น่าสนใจดูเหมือนว่าปัญหาอยู่ในไดรเวอร์ JDBC แล้วเพราะข้อความที่ออกมาจากฐานข้อมูลนั้นถูกตัดทอนอย่างแน่นอน ...
rjohnston

3
Postgres ไม่ข้อมูลที่ตัดกับการป้อนข้อมูลในสถานการณ์เฉพาะบางอย่าง ตัวอย่างเช่นcharacter varying(4)คอลัมน์ที่ให้อินพุต "test" (ช่องว่างสองช่องต่อจากคำ 6 ตัวอักษร) จะตัดช่องว่างและเก็บค่า "test" อย่างไรก็ตามตามกฎทั่วไปคุณสามารถสันนิษฐานได้ว่า Postgres จะเกิดข้อผิดพลาดแทนที่จะตัดทอนข้อมูลของคุณ
Bryson

0

คำถามโง่จริงๆ: คุณแน่ใจหรือไม่ว่าสายอักขระกำลังถูกตัดทอนและไม่เพียง แต่ขาดที่ linebreak ที่คุณระบุ (และอาจไม่แสดงในอินเทอร์เฟซของคุณ) เช่นคุณคาดหวังว่าฟิลด์จะแสดงเป็น

สิ่งนี้จะถูกแทรก \ n จะไม่เป็นเช่นนี้

หรือ

นี้จะถูกแทรก

จะไม่เป็นเช่นนี้

คุณใช้อินเทอร์เฟซอะไร เป็นไปได้ไหมว่ามีบางสิ่งบางอย่างระหว่างทางกินแบ็กสแลชของคุณ?


1
สิ่งนี้เกิดขึ้นกับฉัน ข้อความถูกแทรกลงในกล่องข้อความดูแหล่งที่มาและนั่นเองมีข้อความอ้างอิงและมีข้อความทั้งหมดอยู่ แต่มองไม่เห็น
roberthuttinger
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.