查詢語法與輸入值要分開
把輸入直接接進 SQL 字串,會讓資料中的引號或其他語法影響查詢解讀。參數化查詢先定義結構,再用資料庫介面的綁定機制傳入值;請依實際驅動程式的 placeholder 語法使用。
參數通常用於值,不能任意拿來代替資料表名、欄位名或排序方向。這些結構若真的需要動態變動,應從明確允許的固定選項映射,而不是直接接受任意字串。
參數化之外仍有其他邊界
參數綁定不會替你判斷使用者是否有權看那筆資料,也不會自動選擇資料庫帳號權限。授權、最小權限與錯誤處理仍需各自設計。
本練習用 SQLite 記憶體資料庫與一筆虛構名稱,觀察一般含引號文字如何被正確處理。它驗證這條查詢的值綁定,不代表所有程式路徑都安全。
例子:查詢 O’Neil 這個名字
用字串拼接時,一個正常姓名中的 ASCII 單引號也可能破壞 SQL 結構。下方程式用 ? 綁定值。
SQL 結構維持 name = ?;姓名由 execute 的第二個參數傳入。資料庫會把整個姓名當成值來比對。
判斷:預期取得唯一一筆合成資料,不需要手動移除引號。
離線練習:記憶體資料庫查詢
本機 Python 3 與 sqlite3 標準模組;不建立磁碟資料庫、不連線,也不使用真實個資。
- 閱讀下方程式,找出固定 SQL 與綁定值的位置。
- 在本機執行,核對輸出。
- 把查詢值改成不存在的名稱,預期空清單。
import sqlite3
con = sqlite3.connect(":memory:")
try:
con.execute("CREATE TABLE people (name TEXT)")
con.execute("INSERT INTO people VALUES (?)", ("O'Neil",))
print(con.execute("SELECT name FROM people WHERE name = ?", ("O'Neil",)).fetchall())
finally:
con.close()預期結果
第一次輸出 [("O'Neil",)];查詢不存在名稱時輸出 []。
自行檢核
如果改用參數作資料表名稱,為什麼不是同一種綁定問題?
結束與清理
程式結束即關閉記憶體資料庫,不留下資料檔。