0Pricing
Go Academy · Lesson

Querying Rows

Read result sets.

Querying Rows is a free Go Academy lesson on CoddyKit — lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Go Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Querying Result Sets

Use Query for statements that return rows, like SELECT. It returns a *sql.Rows you iterate over. For a single value, QueryRow is simpler.

db.Query

Query sends the SQL and returns rows plus an error. Always check the error before using the rows.

rows, err := db.Query("SELECT id, name FROM users WHERE active = $1", true)
if err != nil {
    log.Fatal(err)
}

Always defer rows.Close()

The rows hold a database connection until closed. defer rows.Close() returns it to the pool. Forgetting this leaks connections under load.

defer rows.Close()

Iterating with rows.Next

rows.Next() advances to the next row and returns false when done. Inside the loop you call Scan to copy column values into variables.

for rows.Next() {
    var id int
    var name string
    if err := rows.Scan(&id, &name); err != nil {
        log.Fatal(err)
    }
    fmt.Println(id, name)
}

Scan Takes Pointers

Scan writes into the variables you pass, so you must pass pointers (&id, &name). The number and order of pointers must match the selected columns.

Checking rows.Err

The loop can end because data ran out or because an error occurred mid-iteration. After the loop, call rows.Err() to catch any iteration error.

if err := rows.Err(); err != nil {
    log.Fatal(err)
}

QueryRow for One Row

When you expect exactly one row, QueryRow plus Scan is cleaner. If no row matches, Scan returns sql.ErrNoRows.

var name string
err := db.QueryRow("SELECT name FROM users WHERE id = $1", 7).Scan(&name)
if err == sql.ErrNoRows {
    fmt.Println("not found")
}

A Runnable Scan Simulation

Real querying needs a database, so this runnable example models the Query, Next, Scan flow over an in-memory slice to show the iteration pattern.

package main

import "fmt"

type Row struct {
    ID   int
    Name string
}

func main() {
    rows := []Row{{1, "Ada"}, {2, "Lin"}, {3, "Guido"}}
    for i := 0; i < len(rows); i++ {
        var id int
        var name string
        id = rows[i].ID
        name = rows[i].Name
        fmt.Printf("id=%d name=%s\n", id, name)
    }
    fmt.Println("scanned", len(rows), "rows")
}

Handling NULLs

A NULL column cannot scan into a plain string or int. Use sql.NullString, sql.NullInt64, or a pointer type so the code can tell NULL from an empty value.

var email sql.NullString
rows.Scan(&email)
if email.Valid {
    fmt.Println(email.String)
}

Scanning Into Structs

The standard library scans into individual variables, not whole structs. You map columns to struct fields by passing &u.ID, &u.Name. Libraries like sqlx automate this.

Avoid SELECT *

List columns explicitly so the Scan order is stable. A schema change that adds a column will silently break a positional Scan if you relied on SELECT *.

Quick Check

Test your querying knowledge.

Recap

You learned querying rows:

  • Query returns *sql.Rows; defer rows.Close()
  • Loop with rows.Next, copy via Scan into pointers
  • Check rows.Err() after the loop
  • QueryRow for single rows; sql.ErrNoRows on miss
  • Use Null types for nullable columns

Frequently asked questions

Is the “Querying Rows” lesson free?

Yes — the full text of “Querying Rows” is free to read here on the web, and the Go Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Go Academy course, upgrade to CoddyKit PRO.

What will I learn in “Querying Rows”?

Read result sets. You practise Go Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Go Academy?

No prior experience is required. Go Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Querying Rows” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Go Academy lesson?

Yes. Every Go Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Opening a Connection
  2. Querying Rows
  3. Prepared Statements
  4. Transactions
← Back to Go Academy