Executing queries
The Go SDK provides two ways to execute SurrealQL queries: Query for typed, parameterized queries and QueryRaw for composing multiple statements with per-statement results. Both are generic functions that work with *DB, *Session, and *Transaction.
This page covers running queries, parameterizing them, handling multi-statement results, and managing connection-scoped variables.
API References
Running a query
The Query function executes a SurrealQL string and returns typed results. The first type parameter specifies the expected result type. The second parameter s can be a *DB, *Session, or *Transaction.
results, err := surrealdb.Query[[]Person](ctx, db,
"SELECT * FROM persons WHERE age > $min_age",
map[string]any{"min_age": 18},
)
if err != nil {
log.Fatal(err)
}
for _, qr := range *results {
fmt.Println(qr.Status, qr.Result)
}
The function returns *[]QueryResult[T], where each QueryResult contains the Status, execution Time, Result, and an optional Error for that statement.
Parameterizing queries
Always use parameters ($name) instead of string interpolation to prevent injection attacks and ensure correct CBOR encoding of value types.
results, err := surrealdb.Query[[]Person](ctx, db,
"SELECT * FROM persons WHERE name = $name AND age > $age",
map[string]any{
"name": "Tobie",
"age": 25,
},
)
Pass nil for the variables map when no parameters are needed:
results, err := surrealdb.Query[[]Person](ctx, db,
"SELECT * FROM persons",
nil,
)
Handling multi-statement queries
When a query string contains multiple statements, Query returns a QueryResult for each statement. Check the Error field on each result to detect per-statement failures.
results, err := surrealdb.Query[[]any](ctx, db,
"CREATE person:tobie SET name = 'Tobie'; SELECT * FROM person;",
nil,
)
for i, qr := range *results {
if qr.Error != nil {
fmt.Printf("Statement %d failed: %s\n", i, qr.Error.Message)
continue
}
fmt.Printf("Statement %d: %v\n", i, qr.Result)
}
The err returned by Query is a joined error containing all per-statement QueryError values. You can check individual statements via the Error field, or use errors.Is(err, &surrealdb.QueryError{}) on the returned error.
Composing queries with QueryRaw
QueryRaw lets you compose a batch of QueryStmt objects, each with its own SQL and variables. After execution, each statement’s result is available via .GetResult().
stmts := []surrealdb.QueryStmt{
{SQL: "CREATE person:alice SET name = $name", Vars: map[string]any{"name": "Alice"}},
{SQL: "SELECT * FROM person", Vars: nil},
}
if err := surrealdb.QueryRaw(ctx, db, &stmts); err != nil {
log.Fatal(err)
}
var persons []Person
if err := stmts[1].GetResult(&persons); err != nil {
log.Fatal(err)
}
Defining connection variables
Use .Let() to define a variable that persists on the connection and is available in all subsequent queries. Use .Unset() to remove it.
if err := db.Let(ctx, "app_version", "1.0.0"); err != nil {
log.Fatal(err)
}
results, err := surrealdb.Query[[]any](ctx, db,
"RETURN $app_version",
nil,
)
db.Unset(ctx, "app_version")
Connection variables are scoped to the connection (or session if using sessions). They do not affect other connections. You can also build queries programmatically using the query builder.
Learn more