Prepared statement
- Go kursu
- İleri seviye
- Ders 28/68
- 4 dk
Prepare ile güvenli sorgu yazmayı öğrenirsin.
Prepared statement ve yer tutucular
Kullanıcı girdisini SQL metnine birleştirmek SQL enjeksiyonuna yol açar. Bunun yerine yer tutucu kullanılır; değerler sürücüye ayrı gönderilir:
// YANLIŞ: "SELECT * FROM uyeler WHERE ad = '" + ad + "'"
row := db.QueryRow("SELECT id FROM uyeler WHERE ad = ?", ad)Yer tutucu sözdizimi sürücüye göre değişir: MySQL/SQLite ?, PostgreSQL $1, $2.
db.Prepare
Aynı sorgu çok kez çalışacaksa Prepare ile bir kez hazırlanır, sonra farklı değerlerle çalıştırılır:
stmt, err := db.Prepare("INSERT INTO log(mesaj) VALUES(?)")
if err != nil { return err }
defer stmt.Close()
for _, m := range mesajlar {
if _, err := stmt.Exec(m); err != nil { return err }
}Hazır ifade de kaynak tutar; işin bitince Close edilir.
Uygulama Güvenli sorgu yaz
query(ad string) (string, []any) fonksiyonu yaz: SQL metni olarak "SELECT id FROM uyeler WHERE ad = ?" ve argüman listesi olarak []any{ad} döndürsün. q, args := query("Ada") ile çağırıp ikisini yazdır.
Başlangıç kodu
package main
import "fmt"
func main() {
// buraya yaz
}Örnek çözüm
package main
import "fmt"
func query(ad string) (string, []any) {
return "SELECT id FROM uyeler WHERE ad = ?", []any{ad}
}
func main() {
q, args := query("Ada")
fmt.Println(q, args)
}Beklenen çıktı
SELECT id FROM uyeler WHERE ad = ? [Ada]
Soru ve cevaplar
Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.
1 PostgreSQL sürücüsünde ikinci parametrenin yer tutucusu hangisidir?
- :2
- %2
- $2 Doğru cevap
- ?
Açıklama: PostgreSQL numaralı yer tutucular kullanır ($1, $2, ...); MySQL ve SQLite ? kullanır.
2 Hazırla
stmt, err := db.____("DELETE FROM sepet WHERE id = ?")
stmt, err := db.Prepare("DELETE FROM sepet WHERE id = ?")
Açıklama: Prepare sorguyu sunucuda bir kez derler; stmt tekrar tekrar çalıştırılabilir.
3 Güvenli sorgu
| Kavram | Anlamı |
|---|---|
? |
MySQL/SQLite yer tutucusu |
$1 |
PostgreSQL yer tutucusu |
Metin birleştirme |
SQL enjeksiyonu riski |
stmt.Close |
Hazır ifadeyi bırakır |