Value
Use db.Value to read a single scalar value from a database query.
Value
Use db.Value when a query is expected to return one scalar value.
It is commonly used for counts, generated IDs, aggregate values, boolean flags, and simple lookups.
total, found, err := db.Value[int64](ctx, conn, countUsersQuery)
if err != nil {
return 0, false, err
}
if !found {
return 0, false, nil
}Function
func Value[T any](ctx context.Context, c db.Conn, query string, args ...any) (T, bool, error)Value accepts:
- a
context.Context - a
db.Conn - a SQL or CQL query string
- optional query arguments
It returns:
T, found, errorfound is false when the query returns no rows.
When to Use Value
Use db.Value when:
- the query returns exactly one column
- you need a scalar result
- you are reading a count
- you are reading a generated ID with PostgreSQL
RETURNING - you are checking a simple value
- you are reading an aggregate result
Common examples:
SELECT COUNT(*) FROM usersSELECT active FROM users WHERE id = ?INSERT INTO users (name, email, active)
VALUES ($1, $2, $3)
RETURNING idCount Example
For MySQL and Scylla, use ? placeholders.
const countActiveUsersQuery = `
SELECT COUNT(*)
FROM users
WHERE active = ?
`For PostgreSQL, use numbered placeholders.
const countActiveUsersQuery = `
SELECT COUNT(*)
FROM users
WHERE active = $1
`Complete Query Example
This example returns the number of active users.
package main
import (
"context"
"github.com/netlifeguru/db"
)
const countActiveUsersQuery = `
SELECT COUNT(*)
FROM users
WHERE active = ?
`
func CountActiveUsers(ctx context.Context, conn db.Conn) (int64, bool, error) {
return db.Value[int64](ctx, conn, countActiveUsersQuery, true)
}Complete Usage Example
This example connects to the database, reads the count, and prints it.
package main
import (
"context"
"fmt"
"log"
_ "github.com/go-sql-driver/mysql"
"github.com/joho/godotenv"
)
func main() {
err := godotenv.Load()
if err != nil {
log.Println(".env file not found, I'm using system env variables")
}
conn, err := connectDB()
if err != nil {
log.Fatal(err)
}
ctx := context.Background()
total, found, err := CountActiveUsers(ctx, conn)
if err != nil {
log.Fatal(err)
}
if !found {
log.Println("count not found")
return
}
fmt.Printf("active users: %d\n", total)
}PostgreSQL Returning Example
PostgreSQL commonly uses RETURNING when an insert should return a generated ID.
const insertUserQuery = `
INSERT INTO users (name, email, active)
VALUES ($1, $2, $3)
RETURNING id
`
func InsertUser(ctx context.Context, conn db.Conn, name string, email string, active bool) (db.Result, error) {
return db.Insert(ctx, conn, insertUserQuery, name, email, active)
}For MySQL inserts, use db.Insert and read result.LastInsertId() instead.
Single Column Requirement
db.Value expects the query result to contain exactly one selected column.
Good:
SELECT COUNT(*) FROM usersGood:
SELECT email FROM users WHERE id = ?Not suitable:
SELECT id, email FROM users WHERE id = ?For multiple columns, use db.Get or db.List.
Empty Result
If the query returns no rows, db.Value returns found = false.
value, found, err := db.Value[string](ctx, conn, selectEmailQuery, id)
if err != nil {
return "", false, err
}
if !found {
return "", false, nil
}Too Many Rows
db.Value expects zero or one row.
If the query returns more than one row, it returns an error.
Use a unique condition, aggregate query, or LIMIT 1 when appropriate.
SELECT email
FROM users
WHERE id = ?
LIMIT 1Driver Placeholder Differences
The Go call stays the same across drivers.
total, found, err := db.Value[int64](ctx, conn, countActiveUsersQuery, true)Only the query placeholder syntax changes.
| Driver | Placeholder |
|---|---|
| MySQL | ? |
| Postgres | $1 |
| Scylla | ? |
Scylla Example
Use db.Value when a Scylla query returns a single scalar value.
const countPostsByUserQuery = `
SELECT COUNT(*)
FROM posts_by_user
WHERE user_id = ?
`
func CountPostsByUser(ctx context.Context, conn db.Conn, userID string) (int64, bool, error) {
return db.Value[int64](ctx, conn, countPostsByUserQuery, userID)
}Related Helpers
Use db.List when the query can return multiple typed rows.
users, err := db.List[User](ctx, conn, selectUsersQuery, 10)Use db.Get when the query returns zero or one typed row.
user, found, err := db.Get[User](ctx, conn, selectUserQuery, id)Use db.Maps when the result shape is dynamic.
rows, err := db.Maps(ctx, conn, selectRowsQuery)Related Examples
Standalone examples are available in the examples repository: