Pular para o conteúdo

sql"…" — Template Seguro e Scalar

Nesta página

O literal sql"..." é uma forma mais expressiva de construir queries dinâmicas. Qualquer {valor} dentro do template é compilado como ? e vinculado automaticamente — você escreve a query como se fosse uma string interpolada, mas com total segurança contra injeção.

O resultado é um TaggedSqlQuery com quatro métodos:

Método O que faz
.query(db) Executa SELECT, retorna lista de maps
.execute(db) Executa DDL/DML, retorna linhas afetadas
.scalar(db) Retorna o primeiro valor da primeira linha
.one(db) Retorna a primeira linha como map

Filtra livros por ano com {min_year} e usa .scalar para contar o 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

Requer a CLI/host do Zolo — abra no playground ou rode localmente.

.scalar é o atalho ideal para agregações (COUNT, MAX, SUM) e consultas que retornam exatamente uma célula:

Conta SKUs por valor com sql"...{target}".scalar(db) — o {target} é vinculado, não 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

Requer a CLI/host do Zolo — abra no playground ou rode localmente.

Desafio

Use sql"..." para calcular o preço médio com AVG(price) e exibir o resultado formatado com duas casas decimais.

Buscar no Zolo

9 resultados

enespt-br