Struct hdbconnect::PreparedStatement
source · pub struct PreparedStatement { /* private fields */ }
Expand description
Allows injection-safe SQL execution and repeated calls of the same statement with different parameters with as few roundtrips as possible.
§Providing Input Parameters
§Type systems
Type systems, really? Yes, there are in fact four type systems involved!
-
Your application is written in rust, and uses the rust type system.
-
hdbconnect
’s driver API represents values with theenum
HdbValue
; this type system aims to be as close to the rust type system as possible and hides the complexity of the following two internal type systems. -
The wire has its own type system - it’s focus is on efficient data transfer.
hdbconnect
deals with these types internally. -
The database type system consists of the standard SQL types and proprietary types to represent values, like TINYINT, FLOAT, NVARCHAR, and many others. This type system is NOT directly visible to
hdbconnect
.TypeId
enumerates a somewhat reduced superset of the server-side and the wire type system.
§From Rust types to HdbValue
Prepared statements typically take one or more input parameter(s).
As part of the statement preparation, the database server provides the client
with detailed metadata for these parameters, which are kept by the PreparedStatement
.
The parameter values can be handed over to the PreparedStatement
either as
Serializable
rust types, or explicitly as HdbValue
instances.
If they are handed over as Serializable
rust types, then the built-in
serde_db
-based
conversion will convert them directly into those HdbValue
variants
that correspond to the TypeId
that the server has requested.
The application can also provide the values explicitly as HdbValue
instances and by that
enforce the usage of a different wire type and of server-side type conversions.
§Sending HdbValue
s to the database
The protocol for sending values can be version-specific. Sending e.g. an
HdbValue::DECIMAL
to the database occurs in different formats:
- with older HANA versions, a proprietary DECIMAL format is used that is independent of the number range of the concrete field.
- In newer HANA versions, three different formats are used
(
TypeId::FIXED8
,TypeId::FIXED12
andTypeId::FIXED16
) that together allow for a wider value range and a lower bandwidth.
hdbconnect
cares about these details.
Similarly, an HdbValue::STRING
is used to transfer values to all string-like wire types.
The wire protocol sometimes also allows sending data in another wire type than requested.
If the database e.g. requests an INT, you can also send a String representation of the
number, by using HdbValue::STRING("1088")
, instead of the binary INT representation
HdbValue::INT(1088)
.
Implementations§
source§impl<'a> PreparedStatement
impl<'a> PreparedStatement
sourcepub fn execute<T>(&mut self, input: &T) -> Result<HdbResponse, HdbError>where
T: Serialize,
pub fn execute<T>(&mut self, input: &T) -> Result<HdbResponse, HdbError>where
T: Serialize,
Converts the input into a row of parameters, and executes the statement with these parameters immediately.
The row of parameters must be consistent with the input parameter metadata.
The input conversion is done with the help of serde, so the input must implement
serde::ser::Serialize
.
let mut statement = connection.prepare("select * from phrases where ID = ? and text = ?")?;
let hdbresponse = statement.execute(&(42, "Foo is bar"))?;
If the statement has no parameter, you can execute it like this
let hdbresponse = stmt.execute(&())?;
or like this
let hdbresponse = stmt.execute_batch()?;
§Errors
Several variants of HdbError
can occur.
sourcepub fn execute_row(
&'a mut self,
hdb_values: Vec<HdbValue<'a>>
) -> Result<HdbResponse, HdbError>
pub fn execute_row( &'a mut self, hdb_values: Vec<HdbValue<'a>> ) -> Result<HdbResponse, HdbError>
Consumes the given HdbValue
s as a row of parameters for immediate execution.
In most cases
PreparedStatement::execute()
will be more convenient. Streaming LOBs to the database however is an important exception -
it only works with this method!
Note that with older versions of HANA, streaming LOBs to the database only works if auto-commit is switched off. Consequently, you need to commit the update then explicitly.
§Example for streaming LOBs to the database
The first parameter in this example inserts a string into a normal NVARCHAR column.
We’re using a HdbValue::STR
here which allows passing the String as reference
(compared to HdbValue::STRING
, which needs to own the String).
The second parameter of type HdbValue::LOBSTREAM
wraps a shared mutable reference to a reader object
which is supposed to produce the content you want to store.
use std::io::Cursor;
use std::sync::{Arc,Mutex};
let mut stmt = connection.prepare(&insert_stmt_string)?;
stmt.execute_row(vec![
HdbValue::STR("nice descriptive text, could be quite long"),
HdbValue::LOBSTREAM(Some(Arc::new(Mutex::new(Cursor::new("foo bar"))))),
])?;
PreparedStatement::execute_row()
first sends the specified statement to the database,
with the given parameter values, where LOBSTREAM instances are replaced with placeholders.
Subsequently the data from the readers are transferred to the database in additional
roundtrips. Upon completion of the last LOB chunk transfer, the database really executes
the procedure and returns its results.
§Errors
Several variants of HdbError
can occur.
sourcepub fn add_batch<T>(&mut self, input: &T) -> Result<(), HdbError>where
T: Serialize,
pub fn add_batch<T>(&mut self, input: &T) -> Result<(), HdbError>where
T: Serialize,
Converts the input into a row of parameters and adds it to the batch of this
PreparedStatement
, if it is consistent with the metadata.
§Errors
Several variants of HdbError
can occur.
sourcepub fn add_row_to_batch(
&mut self,
hdb_values: Vec<HdbValue<'static>>
) -> Result<(), HdbError>
pub fn add_row_to_batch( &mut self, hdb_values: Vec<HdbValue<'static>> ) -> Result<(), HdbError>
Consumes the input as a row of parameters for the batch.
Useful mainly for generic code.
In most cases add_batch()
is more convenient.
Note that LOB streaming can not be combined with using the batch.
§Errors
Several variants of HdbError
can occur.
sourcepub fn execute_batch(&mut self) -> Result<HdbResponse, HdbError>
pub fn execute_batch(&mut self) -> Result<HdbResponse, HdbError>
Executes the statement with the collected batch, and clears the batch.
Does nothing and returns with an error, if the statement needs input and no batch exists. If the statement does not need input and the batch is empty, a single execution is triggered.
§Errors
Several variants of HdbError
can occur.
sourcepub fn parameter_descriptors(&self) -> Arc<ParameterDescriptors>
pub fn parameter_descriptors(&self) -> Arc<ParameterDescriptors>
Descriptors of all parameters of the prepared statement (in, out, inout).
sourcepub fn server_usage(&self) -> ServerUsage
pub fn server_usage(&self) -> ServerUsage
Provides information about the the server-side resource consumption that
is related to this PreparedStatement
object.