[−][src]Macro include_sql::include_sql
include_sql!() { /* proc-macro */ }
Includes SQL from the provided file.
This macro needs 2 arguments:
- Path to the SQL file. The path should be defined relative to the package root.
- Prefix that will the database interface uses to tag positional SQL parameters.
For example, it would be
"?"
for SQLite,"$"
for Postgresql or":"
for Oracle.
There is an additional requirement. The code generated by the include-sql
assumes that
the database interface has defined and implementatedsome trait to convert argument values
into a format suitable for sending to the database. The genrated code expects that that
trait is called ToSql
and thus this database specfic trait must be imported by a module
as ToSql
.
For example, with rusqlite one need to:
use rusqlite::types::ToSql;
With rust-postgres:
use postgres::types::ToSql;
With rust-oracle:
use oracle::ToSql;
And with oci_rs:
use oci_rs::types::ToSqlValue as ToSql;
For each of the statements found in the SQL file include-sql
will generate:
&str
constant with the text of the preprocessed SQL - named parameters will be replaced by numbered positional onesstruct
that will be used to convert query arguments from a named into a positional form- a macro to transparently convert the argument struct into an argument slice when the struct cannot be used directly
Examples
Execution of queries with a dynamic IN (:list)
component:
-- name: select_ship_crew_by_rank
-- Selects sailors of a given ship that also have
-- specific ranks
SELECT id, name, rank
FROM sailors
WHERE ship_id = :ship
AND rank IN (:ranks)
Query execution in Oracle:
println!("Officers:"); let (sql, args) = SelectShipCrewByRank { ship: &ship_id, ranks: &[ &"captain" as &ToSql, &"midshipman" ] }.into_sql_with_args(); let rows = conn.query(&sql, &args)?; for row in &rows { let row = row?; let id : i32 = row.get(0)?; let name: String = row.get(1)?; let rank: String = row.get(2)?; println!(" - {} {}, ID: {}", rank, name, id); }