Skip to main content
DuckDB positional parameters are written $1, $2, … (or ?). Bind them with execute_with, passing values as &mut dyn AppendAble. Every DuckValue and the primitive Rust types (i32, f64, &str / String, bool, …) implement AppendAble, and mixed types coerce to &mut dyn AppendAble at the call site.

execute_with

execute_with(sql, binds: &mut [&mut dyn AppendAble]) -> Result<DuckResult>. Heterogeneous types are fine; binds fill $1, $2, … in slice order.
Why &mut? Binding goes through DuckDB’s value API, and the AppendAble contract takes the value by mutable reference so it can hand ownership of a built duckdb_value to the FFI call without an extra copy. The slice itself is &mut for the same reason.

Binding an explicit NULL

An Option<T> also binds as Null / Some — None becomes SQL NULL.

The params! macro

With the derive feature, params![…] builds the &mut [&mut dyn AppendAble] slice for you, mixing literals, owned values, and Null without the &mut x as &mut dyn … boilerplate:
See helper macros for details.

insert — homogeneous bind-and-run

For a statement filled from a homogeneous iterator, insert is terser:
insert errors if no rows changed. Use execute_with when a zero-change result is valid, or when the bind values have different types. See executing SQL.

Errors

See also