How to Fix Go Database/sql Rows Iteration Errors
In this tutorial, you'll learn about How to Fix Go Database/sql Rows Iteration Errors. We cover key concepts, practical examples, and best practices.
Go database/sql errors like sql: Rows closed or sql: Rows Next iteration failed occur when rows are not properly iterated, the connection is closed mid-iteration, or rows.Close() is deferred incorrectly.
Quick Fix
Wrong
rows, err := db.Query("SELECT id, name FROM users")
if err != nil {
log.Fatal(err)
}
for rows.Next() {
var id int
var name string
rows.Scan(&id, &name)
fmt.Println(id, name)
}
// Missing rows.Close() and rows.Err() check
If the loop breaks early (e.g., due to an error or break statement), the rows are not closed, leaking the database connection.
Right
rows, err := db.Query("SELECT id, name FROM users")
if err != nil {
log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
var id int
var name string
if err := rows.Scan(&id, &name); err != nil {
log.Fatal(err)
}
fmt.Println(id, name)
}
if err := rows.Err(); err != nil {
log.Fatal(err)
}
1 Alice
2 Bob
Fix when breaking early
rows, err := db.Query("SELECT id, name FROM users")
if err != nil {
log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
var id int
var name string
rows.Scan(&id, &name)
if name == "Alice" {
break // defer closes rows
}
}
Fix for multiple result sets
rows, err := db.Query("SELECT id FROM users; SELECT id FROM orders")
if err != nil {
log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
var id int
rows.Scan(&id)
fmt.Println("User:", id)
}
if rows.NextResultSet() {
for rows.Next() {
var id int
rows.Scan(&id)
fmt.Println("Order:", id)
}
}
Prevention
- Always
defer rows.Close()immediately after checking query error. - Always check
rows.Err()after the iteration loop. - Use
rows.Close()before deferred close for early termination when needed. - Handle
rows.Scanerrors inside the loop. - Use prepared statements for repeated queries.
DodaTech Tools
Doda Browser's Go database tracer shows query execution plans and row iteration counts. DodaZIP archives slow query logs. Durga Antivirus Pro detects SQL injection attempts through row iteration patterns.
Common Mistakes with sql rows iteration
- Using
headandtailinstead of pattern matching, causing runtime errors on empty lists - Forgetting that lazy evaluation defers computation until the value is forced, causing space leaks with unevaluated thunks
- Using
returnto exit a function early instead of wrapping a pure value in the monad
These mistakes appear frequently in real-world GO code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.
Practice Exercise
Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.
This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.
FAQ
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro