SQLx provides a high-level query API built on top of prepared statements. TheDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/launchbadge/sqlx/llms.txt
Use this file to discover all available pages before exploring further.
sqlx::query() function returns a Query value that you call finalizers on to execute and retrieve results. Binding parameters, streaming rows, and mapping to Rust types all flow from this single entry point.
Prepared vs. unprepared queries
SQLx distinguishes between two query modes based on the type you pass to an executor:| Type | Mode | Description |
|---|---|---|
&str / string types | Unprepared (simple) | Sent as-is; no binary encoding, no parameter binding, supports multiple statements |
Query (from sqlx::query()) | Prepared | Parsed and cached by the database; supports parameter binding and binary row encoding |
The sqlx::query() function
sqlx::query() accepts a SQL string and returns a Query struct. Statements are transparently prepared and cached per-connection the first time they are seen — subsequent calls reuse the cached query plan.
Query value is #[must_use] — it has no effect until you call a finalizer on it.
Binding parameters
Use.bind() to supply values for query placeholders. SQLx never interpolates values into the SQL string on the client side; the database server substitutes them at execution time, which prevents SQL injection.
Placeholder syntax differs by database:
- PostgreSQL / SQLite
- MySQL / MariaDB
$1, $2, $3 … — 1-based positional. The same placeholder can appear multiple times..bind() calls:
Finalizers
Finalizers consume theQuery and execute it against an executor (&mut conn, &pool, &mut *tx).
execute()
execute()
Runs the query and returns the number of rows affected. Discards any returned rows.
fetch()
fetch()
Returns a
BoxStream of rows, decoded lazily as you iterate. Use this for large result sets to avoid loading everything into memory at once.fetch_one()
fetch_one()
Returns exactly one row. Returns
Error::RowNotFound if no rows are returned.fetch_optional()
fetch_optional()
Returns
Some(row) or None. Use this when zero rows is a valid outcome.fetch_all()
fetch_all()
Collects all rows into a
Vec. Beware of unbounded result sets — use LIMIT in your SQL when the total count is unknown.Accessing column values
Columns are accessed on aRow by name or ordinal index using row.get() or row.try_get():
Mapping rows with .map()
.map() transforms each row into a custom type before collecting:
query_as() with FromRow
sqlx::query_as() maps rows directly into any type that implements FromRow. Derive it automatically with #[derive(sqlx::FromRow)]:
query_scalar() for single-column results
When a query returns a single column, query_scalar() decodes it directly:
Dynamic queries with QueryBuilder
When the structure of a query varies at runtime — for example, building a WHERE clause from optional filters — use QueryBuilder to construct the SQL and bind parameters safely:
QueryBuilder::push_bind() always uses a parameter placeholder — it never interpolates the value directly into the SQL string.raw_sql() for batch execution and DDL
sqlx::raw_sql() sends a string as an unprepared (simple) query, which allows multiple semicolon-separated statements and DDL:
raw_sql() explicitly: