CodeBlanks Logo Icon CodeBlanks

Prepared statement

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

main.go
package main

import "fmt"

func main() {
    // buraya yaz
}

Sample solution

main.go
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

Question
stmt, err := db.____("DELETE FROM sepet WHERE id = ?")
Answer
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

All lessons in Advanced