Was this page helpful?
Caution
You're viewing documentation for an unstable version of Scylla Rust Driver. Switch to the latest stable version.
Query text is constant, but the values might change.
You can pass changing values to a query by specifying a list of variables as bound values.
Each ?
in query text will be filled with the matching value.
Never pass values by adding strings, this could lead to SQL Injection
Each list of values to send in a query must implement the trait ValueList
.
By default this can be a slice &[]
, a tuple ()
(max 16 elements) of values to send,
or a custom struct which derives from ValueList
.
A few examples:
// Empty slice means that there are no values to send
session.query("INSERT INTO ks.tab (a) VALUES(1)", &[]).await?;
// Empty tuple/unit also means that there are no values to send
session.query("INSERT INTO ks.tab (a) VALUES(1)", ()).await?;
// Sending three integers using a slice:
session
.query("INSERT INTO ks.tab (a, b, c) VALUES(?, ?, ?)", [1_i32, 2, 3].as_ref())
.await?;
// Sending an integer and a string using a tuple
session
.query("INSERT INTO ks.tab (a, b) VALUES(?, ?)", (2_i32, "Some text"))
.await?;
// Sending an integer and a string using a named struct.
// The values will be passed in the order from the struct definition
#[derive(ValueList)]
struct IntString {
first_col: i32,
second_col: String,
}
let int_string = IntString {
first_col: 42_i32,
second_col: "hello".to_owned(),
};
session
.query("INSERT INTO ks.tab (a, b) VALUES(?, ?)", int_string)
.await?;
// Sending a single value as a tuple requires a trailing coma (Rust syntax):
session.query("INSERT INTO ks.tab (a) VALUES(?)", (2_i32,)).await?;
// Each value can also be sent using a reference:
session
.query("INSERT INTO ks.tab (a, b) VALUES(?, ?)", &(&2_i32, &"Some text"))
.await?;
// A map of named values can also be provided:
let mut vals: HashMap<&str, CqlValue> = HashMap::new();
vals.insert("avalue", CqlValue::Text("hello".to_string()));
vals.insert("bvalue", CqlValue::Int(17));
session
.query("INSERT INTO ks.tab (a, b) VALUES(:avalue, :bvalue)", &vals)
.await?;
NULL
values¶Null values can be sent using Option<>
- sending a None
will make the value NULL
:
let null_i32: Option<i32> = None;
session
.query("INSERT INTO ks.tab (a) VALUES(?)", (null_i32,))
.await?;
Unset
values¶When performing an insert with values which might be NULL
, it’s better to use Unset
.
Database treats inserting NULL
as a delete operation and will generate a tombstone.
Using Unset
results in better performance:
use scylla::frame::value::{MaybeUnset, Unset};
// Inserting a null results in suboptimal performance
let null_i32: Option<i32> = None;
session
.query("INSERT INTO ks.tab (a) VALUES(?)", (null_i32,))
.await?;
// Using MaybeUnset enum is better
let unset_i32: MaybeUnset<i32> = MaybeUnset::Unset;
session
.query("INSERT INTO ks.tab (a) VALUES(?)", (unset_i32,))
.await?;
// If we are sure that a value should be unset we can simply use Unset
session
.query("INSERT INTO ks.tab (a) VALUES(?)", (Unset,))
.await?;
See the issue for more information about Unset
See Data Types for instructions on sending other data types
Was this page helpful?