หนีอักขระเครื่องหมายและในสตริง SQL


143

ฉันกำลังพยายามค้นหาแถวตามชื่อในฐานข้อมูล sql ของฉันและมีเครื่องหมายและ ฉันพยายามตั้งค่าอักขระเลี่ยงแล้วหลบหนีจากเครื่องหมายและด้วยเหตุผลบางอย่างนี้ไม่ทำงานและฉันไม่แน่ใจว่าปัญหาของฉันคืออะไร

Set escape '\'
    select * from V1144engine.T_nodes where node_id in(
    select node2_id from V1144engine.T_edges where node1_id in(
    select node2_id from V1144engine.T_edges where node1_id in(
    select node2_id from V1144engine.T_edges where node1_id = 
      (select node_id from V1144engine.T_nodes where node_name = 'Geometric Vectors \& Matrices')))
    and edge_type_id = 1)
    and node_type_id = 1
    and node_id in (
    select node2_id from V1144engine.T_edges where node1_id =
      (select node_id from V1144engine.T_nodes where node_name = 'Algebra II')
    and edge_type_id = 2);

แม้ว่านี่จะมีวิธีแก้ไขปัญหาคล้าย ๆ กับคำถามนี้แต่ปัญหาต่างกันมาก พวกเขาอาจลงเอยด้วยวิธีการแก้ปัญหาแบบเดียวกัน แต่นั่นไม่ได้หมายความว่าคำถามจะเหมือนกัน


ฉันไม่คิดว่าคุณจะต้องมีเครื่องหมายคำพูดรอบตัวละคร Escape ('\')
mcalex

29
set define offเป็นวิธีที่ง่ายที่สุดที่จะทำ
AnBisw

คำตอบ:


206

แทน

node_name = 'Geometric Vectors \& Matrices'

ใช้

node_name = 'Geometric Vectors ' || chr(38) || ' Matrices' 

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

อีกวิธีหนึ่งอาจใช้ LIKE และขีดเส้นใต้แทนอักขระ '&':

node_name LIKE 'Geometric Vectors _ Matrices' 

โอกาสที่คุณจะได้พบกับบันทึกอื่น ๆ ด้วยซึ่งแตกต่างกันในตัวละครตัวเดียวนี้ก็ค่อนข้างต่ำ


45
แทนที่จะ unintuitive chr(38)คุณสามารถทำnode_name = 'Geometric Vectors &' || ' Matrices'
เจซัลลิแวน

1
สำหรับวิญญาณสับสนอื่น ๆ ที่น่าสงสารเหมือนกันกับตัวเองทราบว่ามันเป็นchr(38), ไม่ char(38)
xdhmoore

ทราบว่า&ไม่จำเป็นต้องหลบหนีใน MySQL นอกจากนี้ยัง MySQL CHR()ไม่ได้มีฟังก์ชั่น
asmaier

113

ค่า Escape ถูกกำหนดเป็นค่า\เริ่มต้นดังนั้นคุณไม่จำเป็นต้องตั้งค่า แต่ถ้าคุณทำอย่าห่อมันด้วยเครื่องหมายคำพูด

เครื่องหมายแอมเปอร์แซนด์เป็นเครื่องหมายการแทนที่ตัวแปร SQL * Plus ; แต่คุณสามารถเปลี่ยนได้หรือมากกว่าในกรณีของคุณปิดโดยสมบูรณ์ด้วย:

set define off

จากนั้นคุณไม่ต้องกังวลกับการหลบหนีจากค่าทั้งหมด


2
อักขระ escape ถูกตั้งค่าเป็นค่า\ เริ่มต้น แต่พารามิเตอร์บูลีนescapeถูกตั้งค่าเป็น OFF ตามค่าเริ่มต้น ดังนั้น OP อาจไม่จำเป็นต้องตั้งค่าตัวอักษรยกเว้น แต่เขา / เธอต้องการอย่างน้อยก็SET ESCAPE ONเพื่อให้มันทำงานได้ หรือแน่นอนใช้วิธีอื่นที่ดีกว่า
mathguy

46

คุณสามารถใช้ได้

set define off

การใช้สิ่งนี้จะไม่แสดงพร้อมท์ให้ป้อนข้อมูล


32

ตรงจากหนังสือพื้นฐาน oracle sql

SET DEFINE OFF
select 'Coda & Sid' from dual;
SET DEFINE ON

วิธีหนึ่งที่จะหลบหนีได้โดยไม่ต้องตั้งค่ากำหนด


2
การเพิ่ม SET DEFINE ON นั้นมีประโยชน์
KSev

@ Roman คุณไม่สามารถระบุได้เช่นกัน: เลือก 'Coda' '&' 'Sid' จากคู่; (เครื่องหมายคำพูดเดี่ยว)
antcalvente

8

เพื่อหลบหนี&คุณสามารถลองวิธีต่อไปนี้: -

  1. set scan off
  2. set define off
  3. set escape on จากนั้นแทนที่&ด้วย/&
  4. แทนที่&ด้วย&&

หนึ่งในนั้นควรทำงานอย่างน้อย

dditionally ถ้าคุณกำลังใช้นักพัฒนา PL / SQL แล้วมีและไอคอนในด้านล่างของหน้าต่าง SQL โปรดไปที่นั่นและปิดการใช้งานมัน หมายเหตุในรุ่นที่เก่ากว่าไม่มีตัวเลือกนี้

นอกจากนี้ตรวจสอบให้แน่ใจว่าการกำหนดปิดเขียนในตอนต้นของสคริปต์


2

วิธีนี้ใช้ได้ผลเช่นกัน:

select * from mde_product where cfn = 'A3D"&"R01'

คุณกำหนด&เป็นตัวอักษรโดยการล้อมรอบอยู่กับ qoutes สองครั้ง"&"ในสตริง


1
ถ้าคุณทำอย่างนั้นที่ราคาสองครั้งจะกลายเป็นส่วนหนึ่งของสตริงเช่นนี้A3D"&"R01
เดวิดBalažic

2
set escape on
... node_name = 'Geometric Vectors \& Matrices' ...

หรืออีกทางหนึ่ง:

set define off
... node_name = 'Geometric Vectors & Matrices' ...

วิธีแรกให้คุณใช้แบ็กสแลชเพื่อหนีการ &

ครั้งที่สองปิด & "ทั่วโลก" (ไม่จำเป็นต้องเพิ่มแบ็กสแลชที่ใดก็ได้) คุณสามารถเปิดอีกครั้งโดยset define onและจากบรรทัดนั้นบนเครื่องหมายและจะได้รับความหมายพิเศษของพวกเขากลับมาดังนั้นคุณสามารถปิดมันสำหรับบางส่วนของสคริปต์และไม่ใช่สำหรับคนอื่น



0

ฉันเขียน regex เพื่อช่วยค้นหาและแทนที่ "&" ภายใน INSERT ฉันหวังว่าสิ่งนี้จะช่วยใครบางคน

เคล็ดลับคือเพื่อให้แน่ใจว่า "&" อยู่กับข้อความอื่น

หา “(\'[^\']*(?=\&))(\&)([^\']*\')”

แทนที่ “$1' || chr(38) || '$3”

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