วิธีแทรกค่าที่มีเครื่องหมายอัญประกาศเดี่ยว (อัญประกาศเดี่ยว) ได้อย่างไร


310

ไวยากรณ์ SQL ที่ถูกต้องในการแทรกค่าด้วยเครื่องหมายอัญประกาศเดี่ยวนั้นคืออะไร?

Insert into Person
  (First, Last)
Values
  'Joe',
  'O'Brien'

ฉันได้รับข้อผิดพลาดอย่างต่อเนื่องเนื่องจากฉันคิดว่าเครื่องหมายอัญประกาศเดี่ยวหลังจาก O เป็นแท็กสิ้นสุดสำหรับค่า


16
โปรดยืนยันว่าคุณไม่ได้เปิดการโจมตีด้วยการฉีด SQL ใช้พารามิเตอร์ที่เป็นไปได้ทั้งหมด
Andrew

คุณใช้ภาษาสคริปต์อะไร ตัวอย่างเช่นมีฟังก์ชั่นใน PHP เพื่อทำสิ่งนี้ให้ถูกต้องสำหรับคุณ
philfreo

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

จริง ๆ แล้วมันอยู่ในโค้ด .. ถ้าฉันมีคิวรี่แบบพารามิเตอร์แล้วฉันไม่ต้องทำแบบเดียวกันเหรอ?
leora

2
เชิงลบ ขึ้นอยู่กับฐานข้อมูลและไดรเวอร์ที่คุณใช้การแยกพารามิเตอร์อาจได้รับการจัดการแตกต่างกัน แต่พารามิเตอร์ในคำสั่งที่กำหนดพารามิเตอร์ไม่จำเป็นต้องมีการยกเว้น ดูen.wikipedia.org/wiki/SQL_injection#Preventing_SQL_injection
charstar

คำตอบ:


485

ยกเว้นเครื่องหมายอัญประกาศเดี่ยว (เช่นเพิ่มอักขระคำพูดเดี่ยวสองครั้ง) ใน SQL ของคุณ:

INSERT INTO Person
    (First, Last)
VALUES
    ('Joe', 'O''Brien')
              /\
          right here  

เช่นเดียวกับการสืบค้น SELECT:

SELECT First, Last FROM Person WHERE Last = 'O''Brien'

เครื่องหมายวรรคตอนหรืออัญประกาศเดี่ยวเป็นอักขระพิเศษใน SQL ที่ระบุจุดเริ่มต้นและจุดสิ้นสุดของข้อมูลสตริง ซึ่งหมายความว่าการใช้เป็นส่วนหนึ่งของข้อมูลสตริงตัวอักษรของคุณคุณต้องescapeใช้อักขระพิเศษ ด้วยการเสนอราคาครั้งเดียวสิ่งนี้สามารถทำได้โดยการเพิ่มการเสนอราคาของคุณเป็นสองเท่า (อักขระเครื่องหมายคำพูดเดี่ยวสองตัวไม่ใช่เครื่องหมายคำพูดคู่แทนที่จะเป็นเครื่องหมายคำพูดเดี่ยว)

หมายเหตุ : คุณควรกังวลเกี่ยวกับปัญหานี้เมื่อคุณแก้ไขข้อมูลด้วยตนเองผ่านทางอินเทอร์เฟซ SQL ดิบเนื่องจากการเขียนแบบสอบถามนอกการพัฒนาและการทดสอบควรจะเกิดขึ้นได้ยาก ในรหัสมีเทคนิคและกรอบ (ขึ้นอยู่กับสแต็คของคุณ) ที่ดูแลการหลบหนีอักขระพิเศษ, การฉีด SQLฯลฯ


6
$ linkQuestion = str_replace ("'", "' '", $ linkQuestion); (เอ้ยอ่านยาก!)
user462990

จะเกิดอะไรขึ้นถ้าข้อมูลถูกแทรกลงในบุคคล (แรก, สุดท้าย) ค่า 'Joe', 'ร้านของพ่อ'
vijesh


21

คุณต้องหลบหนี apostrophe ในT-SQLนี่คือเครื่องหมายอัญประกาศคู่ดังนั้นinsertคำสั่งของคุณจะกลายเป็น:

Insert into Person
(First, Last)
Values
'Joe', 'O''Brien'

AFAIK Valuesต้องอยู่ในเครื่องหมายปีกกา (ซึ่งจะทำให้เป็นคำตอบเดียวกับ @JustinNiessner)
qwerty_so

15

เนื่องจากเครื่องหมายคำพูดเดี่ยวใช้สำหรับระบุจุดเริ่มต้นและจุดสิ้นสุดของสตริง คุณต้องหลบหนี

คำตอบสั้น ๆ คือการใช้อัญประกาศเดี่ยวสองคำ''สั่งเพื่อให้ฐานข้อมูล SQL เก็บค่า'ไว้

ดูที่การใช้ REPLACE เพื่อฆ่าเชื้อค่าที่เข้ามา:

คุณต้องการตรวจสอบ''''และแทนที่พวกเขาหากพวกเขามีอยู่ในสตริงด้วย''''''เพื่อที่จะหลบหนีอ้างคำพูดเดียว


3

eduffy มีความคิดที่ดี เขาได้รับมันย้อนกลับในตัวอย่างรหัสของเขา ใน JavaScript หรือใน SQLite คุณสามารถแทนที่เครื่องหมายวรรคตอนด้วยสัญลักษณ์เน้นเสียง

เขา (โดยบังเอิญฉันแน่ใจ) วางสัญลักษณ์เน้นเสียงเป็นตัวคั่นสำหรับสตริงแทนที่จะแทนที่เครื่องหมายอัญประกาศเดี่ยวใน O'Brian นี่คือความจริงแล้วโซลูชันที่ยอดเยี่ยมสำหรับกรณีส่วนใหญ่


ทางออกที่ยอดเยี่ยมและเรียบง่ายและนามสกุลของฉันคือ O`Reilly!
PhillipOReilly

อย่างไรก็ตามขอแนะนำให้ใช้อักขระเลี่ยง ตั้งใจ :) ตั้งแต่วันที่ฉันใช้แป้นพิมพ์ ฉันใช้สัญลักษณ์เน้นเสียงโดยไม่ได้ตั้งใจแทนคำพูดเดียวในขณะที่เขียนเอกสาร (อย่างไรก็ตามในรหัสฉันใช้ 'เป็นตัวระบุถ่าน) จนกระทั่งเมื่อปีที่แล้วมีคนบอกรหัสผ่านแก่เขาและฉันไม่สามารถลงชื่อเข้าใช้ระบบของเขาได้ เราไม่สามารถคิดออกได้จนกว่าจะถึงเวลาที่ฉันจะพิมพ์ 'เป็น'
ผู้เรียน

3

สามารถแทรกอักขระอะโพสโทรฟีได้โดยการเรียกฟังก์ชันCHARด้วยเครื่องหมายอะโพสโทรฟีการค้นหาตาราง ASCIIค่า 39. ค่าสตริงจากนั้นจะสามารถตัดแบ่งร่วมกับผู้ประกอบการ concatenate

Insert into Person
  (First, Last)
Values
  'Joe',
  concat('O',char(39),'Brien')

2

ราคาเดียวที่รอดหนีไปโดยการเพิ่มพวกเขาขึ้น ,

SQL ต่อไปนี้แสดงฟังก์ชันการทำงานนี้

declare @person TABLE (
    [First] nvarchar(200),
    [Last] nvarchar(200)
)

insert into @person 
    (First, Last)
values
    ('Joe', 'O''Brien')

select * from @person

ผล

First   | Last
===================
Joe     | O'Brien

0

ใช้เครื่องหมายคำพูดคู่รอบค่า

insert into Person (First, Last) Values("Joe","O'Brien")

3
โปรดทราบว่านี่ไม่ใช่ SQL มาตรฐานอีกต่อไปแม้ว่าฉันจะรู้จัก Informix ในการตั้งชื่อ แต่หนึ่ง DBMS อนุญาต นอกจากนี้คุณควรอยู่ที่วิธีการที่คุณต้องการแทรกสตริงเช่นHe said, "Don't!"ใช้ราคาเดียวและ / หรือคำพูดสอง - ซึ่งสามารถทำได้: หรือ'He said, "Don''t!"' "He said, ""Don't!"""เมื่อเพิ่มคำตอบใหม่ให้กับคำถามที่มีมานานแล้วพร้อมกับคำตอบที่ยอมรับคุณต้องให้ข้อมูลใหม่ที่ครบถ้วน การใช้เครื่องหมายคำพูดคู่เป็นสิ่งใหม่ - แต่ จำกัด เพียงไม่กี่ DBMS คุณควรใช้ความเจ็บปวดในการระบุอย่างน้อยหนึ่งในนั้นที่ยอมรับพวกเขา
Jonathan Leffler

-1

ใช้ backtick (ที่ปุ่ม ~) แทน

`O'Brien`

1
จากนั้นปัญหาจะกลายเป็น: วิธีแทรก backtick?
Jasper de Vries

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