Saltar al contenido

sql"…" — Plantilla Segura y Scalar

En esta página

El literal sql"..." es una forma más expresiva de construir queries dinámicas. Cualquier {valor} dentro de la plantilla se compila como ? y se vincula automáticamente — escribes la query como si fuera una cadena interpolada, pero con total seguridad contra inyección.

El resultado es un TaggedSqlQuery con cuatro métodos:

Método Qué hace
.query(db) Ejecuta SELECT, devuelve lista de maps
.execute(db) Ejecuta DDL/DML, devuelve filas afectadas
.scalar(db) Devuelve el primer valor de la primera fila
.one(db) Devuelve la primera fila como map

Filtra libros por año con {min_year} y usa .scalar para contar el total.

06-tagged-sql.zolo
Playground
// Feature: Database — `sql"..."` tagged template with auto-parametrization

// Syntax: `sql"SELECT ... WHERE x = {value}"` — interpolations become `?`

// and the values are bound. Returns a TaggedSqlQuery with methods

// `:query(db)`, `:execute(db)`, `:one(db)`, `:scalar(db)`.

// When to use: dynamic, safe queries without string concatenation.


use std::database::Database

let db = Database.open("sqlite://:memory:").unwrap()
defer db.close()

db.execute(sql"CREATE TABLE books (id INTEGER PRIMARY KEY, title TEXT, year INTEGER)").unwrap()
db.execute(sql"INSERT INTO books VALUES (1, 'Zolo Guide', 2025)").unwrap()
db.execute(sql"INSERT INTO books VALUES (2, 'Lua in 24h', 2010)").unwrap()
db.execute(sql"INSERT INTO books VALUES (3, 'Rust Book',  2020)").unwrap()

const min_year = 2020

// `{min_year}` compiles to `?` + binding — safe against injection.

let q = sql"SELECT title, year FROM books WHERE year >= {min_year} ORDER BY year"

let rows = q.query(db).unwrap()
for row in rows {
  print("  {row.title} ({row.year})")
}

// expected:

//   Rust Book (2020)

//   Zolo Guide (2025)


// `:scalar` returns the first value of the first column.

let total = sql#"SELECT COUNT(*) "total" FROM books"#.scalar(db).unwrap()
print("total: {total}")
// expected: total: 3

Requiere la CLI o el host de Zolo; ábrelo en el playground o ejecútalo localmente.

.scalar es el atajo ideal para agregaciones (COUNT, MAX, SUM) y consultas que devuelven exactamente una celda:

Cuenta SKUs por valor con sql"...{target}".scalar(db) — el {target} es vinculado, no concatenado.

07-scalar.zolo
Playground
// Feature: `sql"...".scalar(db)` — first column of first row, as a value

// Syntax: returns the value directly (number/string/bool/nil) rather

// than a row object.

// When to use: COUNT(*), MAX/MIN/SUM aggregates, SELECT 1, single

// scalar lookups by primary key — anywhere the result is exactly

// one cell.


use std::database::Database

let db = Database.open("sqlite://:memory:").unwrap()
defer db.close()

db.execute(sql"CREATE TABLE items (id INTEGER PRIMARY KEY, sku TEXT)").unwrap()
db.execute(sql"INSERT INTO items VALUES (1, 'a')").unwrap()
db.execute(sql"INSERT INTO items VALUES (2, 'b')").unwrap()
db.execute(sql"INSERT INTO items VALUES (3, 'a')").unwrap()

// Interpolated value is bound, not concatenated — safe.

let target = "a"
let n = sql"SELECT COUNT(*) FROM items WHERE sku = {target}".scalar(db).unwrap()
print("count: {n}")

// expected: count: 2


// `scalar` also works without interpolation.

let total = sql"SELECT COUNT(*) FROM items".scalar(db).unwrap()
print("total: {total}")
// expected: total: 3

Requiere la CLI o el host de Zolo; ábrelo en el playground o ejecútalo localmente.

Desafío

Usa sql"..." para calcular el precio medio con AVG(price) y muestra el resultado formateado con dos decimales.

Buscar en Zolo

9 resultados

enespt-br