0Pricing
Python Academy · บทเรียน

คำสั่งสอบถามแบบกำหนดพารามิเตอร์

ป้องกันการแทรกคำสั่ง SQL

คำสั่งสอบถามแบบกำหนดพารามิเตอร์ เป็นบทเรียน Python Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Python Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Python Academy มีบทเรียนทั้งหมด 4 บทเรียน

อันตรายจากการประกอบสตริง

การสร้าง SQL ด้วยการนำสตริงมาต่อกันมีความเสี่ยง หากข้อมูลที่ผู้ใช้ป้อนมีคำสั่ง SQL ก็อาจเปลี่ยนความหมายของคำสั่งสืบค้นได้ การโจมตีนี้เรียกว่า การแทรกคำสั่ง SQL

อย่านำข้อมูลที่ไม่น่าเชื่อถือมาใช้ด้วยวิธีนี้

name = 'Alice'
# Unsafe pattern - do NOT do this
query = "SELECT * FROM users WHERE name = '" + name + "'"
print(query)

ลักษณะของการแทรกคำสั่ง

ลองนึกถึงค่าที่ผู้ไม่หวังดีสร้างขึ้น การนำค่านี้มาต่อกับสตริงจะเปลี่ยนความหมายของคำสั่งสืบค้นไปโดยสิ้นเชิง

name = "x' OR '1'='1"
query = "SELECT * FROM users WHERE name = '" + name + "'"
print(query)
print('The OR clause makes every row match!')

ตัวยึดค่าช่วยแก้ปัญหา

วิธีที่ปลอดภัยคือ คำสั่งสืบค้นแบบใช้พารามิเตอร์ ใช้ ? เป็นตัวยึดค่า แล้วส่งค่าในรูปทูเพิล ไดรเวอร์จะจัดการอักขระพิเศษให้ปลอดภัย

import sqlite3
conn = sqlite3.connect(':memory:')
cur = conn.cursor()
cur.execute('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)')
cur.execute('INSERT INTO users (name) VALUES (?)', ('Alice',))
cur.execute('SELECT * FROM users')
print(cur.fetchall())
conn.close()

ตัวยึดค่าหลายตัว

ใช้ ? หนึ่งตัวต่อหนึ่งค่า ส่งค่าเหล่านั้นในทูเพิลตามลำดับเดียวกับที่ปรากฏในคำสั่ง

import sqlite3
conn = sqlite3.connect(':memory:')
cur = conn.cursor()
cur.execute('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)')
cur.execute('INSERT INTO users (name, age) VALUES (?, ?)', ('Bob', 25))
cur.execute('SELECT * FROM users')
print(cur.fetchall())
conn.close()

ทูเพิลที่มีค่าเดียว

ทูเพิลที่มีสมาชิกหนึ่งตัวต้องมีจุลภาคต่อท้าย: ('Alice',) หากไม่มีจุลภาค Python จะถือว่าวงเล็บเป็นเพียงการจัดกลุ่ม

good = ('Alice',)
bad = ('Alice')
print(type(good), type(bad))

การสกัดกั้นความพยายามแทรกคำสั่ง

เมื่อใช้ตัวยึดค่า ค่าที่เป็นอันตรายจะถูกถือเป็นข้อมูลทั่วไป ไม่ใช่ SQL ดังนั้นจึงไม่ตรงกับข้อมูลใด

import sqlite3
conn = sqlite3.connect(':memory:')
cur = conn.cursor()
cur.execute('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)')
cur.execute('INSERT INTO users (name) VALUES (?)', ('Alice',))
evil = "x' OR '1'='1"
cur.execute('SELECT * FROM users WHERE name = ?', (evil,))
print('Rows matched:', cur.fetchall())
conn.close()

ตัวยึดค่าแบบมีชื่อ

SQLite ยังรองรับตัวยึดค่าแบบมีชื่อด้วยรูปแบบ :name ให้ส่งพจนานุกรมของค่าไป

import sqlite3
conn = sqlite3.connect(':memory:')
cur = conn.cursor()
cur.execute('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)')
cur.execute('INSERT INTO users (name, age) VALUES (:n, :a)', {'n': 'Carol', 'a': 40})
cur.execute('SELECT * FROM users')
print(cur.fetchall())
conn.close()

พารามิเตอร์ใน WHERE

ตัวยึดค่าใช้ได้ในส่วนคำสั่งใด ๆ ที่รับค่า รวมถึง WHERE

import sqlite3
conn = sqlite3.connect(':memory:')
cur = conn.cursor()
cur.execute('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)')
cur.execute('INSERT INTO users (name, age) VALUES (?, ?)', ('Alice', 30))
cur.execute('INSERT INTO users (name, age) VALUES (?, ?)', ('Bob', 25))
cur.execute('SELECT name FROM users WHERE age > ?', (28,))
print(cur.fetchall())
conn.close()

executemany

หากต้องการเพิ่มหลายแถว ให้ใช้ executemany() พร้อมรายการทูเพิล วิธีนี้ทำงานได้เร็วกว่าและยังคงปลอดภัย

import sqlite3
conn = sqlite3.connect(':memory:')
cur = conn.cursor()
cur.execute('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)')
rows = [('Alice',), ('Bob',), ('Carol',)]
cur.executemany('INSERT INTO users (name) VALUES (?)', rows)
cur.execute('SELECT COUNT(*) FROM users')
print(cur.fetchone())
conn.close()

ตัวยึดค่าใช้แทนตัวระบุไม่ได้

ตัวยึดค่าใช้ได้เฉพาะกับ ค่า ไม่ใช่ชื่อของตารางหรือคอลัมน์ ชื่อเหล่านั้นต้องมาจากรายการอนุญาตที่เชื่อถือได้ในโค้ดของคุณเอง

import sqlite3
conn = sqlite3.connect(':memory:')
cur = conn.cursor()
cur.execute('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)')
allowed = {'name', 'id'}
col = 'name'
if col in allowed:
    cur.execute('SELECT ' + col + ' FROM users')
    print('Safe column query ran')
conn.close()

ฟังก์ชันเพิ่มข้อมูลที่นำกลับมาใช้ใหม่ได้

การห่อหุ้มการเพิ่มข้อมูลแบบใช้พารามิเตอร์ไว้ในฟังก์ชันช่วยให้โค้ดเป็นระเบียบและปลอดภัยอย่างสม่ำเสมอ

import sqlite3
conn = sqlite3.connect(':memory:')
cur = conn.cursor()
cur.execute('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)')

def add_user(cursor, name):
    cursor.execute('INSERT INTO users (name) VALUES (?)', (name,))

add_user(cur, 'Dave')
cur.execute('SELECT * FROM users')
print(cur.fetchall())
conn.close()

ตรวจสอบความเข้าใจ

ทดสอบความรู้เกี่ยวกับคำสั่งสืบค้นที่ปลอดภัยของคุณ

สรุปทบทวน

คุณได้เรียนรู้การเขียนคำสั่งสืบค้นที่ปลอดภัยจากการแทรกคำสั่ง

  • อย่านำข้อมูลที่ไม่น่าเชื่อถือมาต่อกับ SQL โดยตรง
  • ใช้ตัวยึดค่า ? พร้อมทูเพิลของค่า
  • ตัวยึดค่าแบบมีชื่อ :name รับพจนานุกรม
  • executemany() เพิ่มหลายแถวได้อย่างปลอดภัย
  • ตัวยึดค่าใช้สำหรับค่า ไม่ใช่ตัวระบุ

คำถามที่พบบ่อย

บทเรียน “คำสั่งสอบถามแบบกำหนดพารามิเตอร์” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “คำสั่งสอบถามแบบกำหนดพารามิเตอร์” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Python Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Python Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “คำสั่งสอบถามแบบกำหนดพารามิเตอร์”

ป้องกันการแทรกคำสั่ง SQL คุณปฏิบัติ Python Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Python Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Python Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน

บทเรียน “คำสั่งสอบถามแบบกำหนดพารามิเตอร์” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Python Academy นี้ได้ไหม

ได้ บทเรียน Python Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การเชื่อมต่อและการสร้างตาราง
  2. Insert, Select, Update, Delete
  3. คำสั่งสอบถามแบบกำหนดพารามิเตอร์
  4. ธุรกรรมและตัวจัดการบริบท
← กลับไปที่ Python Academy