Prepared statement
- Go course
- Advanced
- Lesson 28/68
- 4 min
Learn to write safe queries with Prepare.
Prepared statements and placeholders
Concatenating user input into SQL text leads to SQL injection. Use placeholders instead; values are sent to the driver separately:
// WRONG: "SELECT * FROM uyeler WHERE ad = '" + ad + "'"
row := db.QueryRow("SELECT id FROM uyeler WHERE ad = ?", ad)Placeholder syntax depends on the driver: MySQL/SQLite ?, PostgreSQL $1, $2.
db.Prepare
If the same query will run many times, prepare it once with Prepare and run it with different values:
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 }
}A prepared statement also holds resources; Close it when you are done.
Practice Write a safe query
Write query(ad string) (string, []any): return the SQL text "SELECT id FROM uyeler WHERE ad = ?" and the argument list []any{ad}. Call it with q, args := query("Ada") and print both.
Starter code
package main
import "fmt"
func main() {
// buraya yaz
}Sample solution
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)
}Expected output
SELECT id FROM uyeler WHERE ad = ? [Ada]
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 With the PostgreSQL driver, which is the placeholder for the second parameter?
- :2
- %2
- $2 Correct answer
- ?
Explanation: PostgreSQL uses numbered placeholders ($1, $2, ...); MySQL and SQLite use ?.
2 Prepare
stmt, err := db.____("DELETE FROM sepet WHERE id = ?")
stmt, err := db.Prepare("DELETE FROM sepet WHERE id = ?")
Explanation: Prepare compiles the query on the server once; stmt can be run again and again.
3 Safe queries
| Term | Meaning |
|---|---|
? |
MySQL/SQLite placeholder |
$1 |
PostgreSQL placeholder |
String concatenation |
SQL injection risk |
stmt.Close |
Releases the statement |