pub struct Statement<'con, 'param, 'col, C = NoCursor, A = Unprepared> { /* private fields */ }Expand description
A Statement is most easily thought of as an SQL statement, such as
SELECT * FROM Employee.
- The statement’s state
- The current statement-level diagnostics
- The addresses of the application variables bound to the statement’s parameters and result set columns
- The current settings of each statement attribute
Specific to the rust wrapper of an ODBC Statement is, that we do keep track
of the lifetimes of
the parent Connection, parameters as well as columns bound to the
Statement. Since it is
possible to unbind the parameters and columns we have to keep track of
their lifetimes
seperatly.
Implementations§
Source§impl<'con, 'param, 'col, S, A> Statement<'con, 'param, 'col, S, A>
impl<'con, 'param, 'col, S, A> Statement<'con, 'param, 'col, S, A>
Sourcepub fn bind_input_parameter<'p, T>(
self,
parameter_number: SQLUSMALLINT,
parameter_type: DataType,
value: &'p T,
indicator: Option<&'p SQLLEN>,
) -> Return<Statement<'con, 'p, 'col, S, A>, Self>
pub fn bind_input_parameter<'p, T>( self, parameter_number: SQLUSMALLINT, parameter_type: DataType, value: &'p T, indicator: Option<&'p SQLLEN>, ) -> Return<Statement<'con, 'p, 'col, S, A>, Self>
Binds a parameter to a parameter marker in an SQL Statement
§Result
This method will destroy the statement and create a new one which may not outlive the bound
parameter. This is to ensure that the statement will not derefernce an invalid pointer
during execution. Use reset_parameters to reset the bound parameters and increase the
'param lifetime back to 'static.
§Arguments
parameter_number- Index of the marker to bind to the parameter. Starting at1parameter_type- SQL Type of the parametervalue- Reference to bind to the marker
See [SQLBindParameter Function][1] [1]: https://docs.microsoft.com/sql/odbc/reference/syntax/sqlbindparameter-function#columnsize-argument
Examples found in repository?
33fn execute_query<'a>(
34 stmt: Statement<'a, 'a, 'a, NoCursor, Prepared>,
35 year: i32,
36) -> ResultSet<'a, 'a, 'a, Prepared> {
37 let stmt = stmt.bind_input_parameter(1, DataType::Integer, &year, None)
38 .unwrap();
39 let stmt = match stmt.execute() {
40 ReturnOption::Success(s) |
41 ReturnOption::Info(s) => s,
42 ReturnOption::NoData(_) |
43 ReturnOption::Error(_) => panic!("No Result Set"),
44 };
45 stmt.reset_parameters()
46}Sourcepub fn bind_col<'col_new, T>(
self,
column_number: SQLUSMALLINT,
value: &'col_new mut T,
indicator: Option<&'col_new mut SQLLEN>,
) -> Return<Statement<'con, 'param, 'col_new, S, A>, Self>
pub fn bind_col<'col_new, T>( self, column_number: SQLUSMALLINT, value: &'col_new mut T, indicator: Option<&'col_new mut SQLLEN>, ) -> Return<Statement<'con, 'param, 'col_new, S, A>, Self>
Binds a buffer and an indicator to a column.
See [SQLBindCol][1]: [1]: [https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlbindcol-function]
Examples found in repository?
106fn fetch<'con, 'p, 'c, C>(
107 cursor: Statement<'con, 'p, 'c, C>,
108 year: &mut u32,
109 title: &mut [u8],
110 ind_year: &mut SQLLEN,
111 ind_title: &mut SQLLEN,
112) -> MyResult<Option<Statement<'con, 'p, 'c, Positioned>>>
113where
114 C: CursorState,
115{
116 use ReturnOption::*;
117 let cursor = cursor.bind_col(1, year, Some(ind_year)).into_result()?;
118 let cursor = cursor.bind_col(2, &mut title[..], Some(ind_title)).into_result()?;
119 let cursor = match cursor.fetch() {
120 Success(s) | Info(s) => Some(s.reset_columns()),
121 NoData(_) => None,
122 Error(s) => return Err(s.into()),
123 };
124 Ok(cursor)
125}Sourcepub fn reset_parameters(self) -> Statement<'con, 'static, 'col, S, A>
pub fn reset_parameters(self) -> Statement<'con, 'static, 'col, S, A>
Unbinds the parameters from the parameter markers
Examples found in repository?
33fn execute_query<'a>(
34 stmt: Statement<'a, 'a, 'a, NoCursor, Prepared>,
35 year: i32,
36) -> ResultSet<'a, 'a, 'a, Prepared> {
37 let stmt = stmt.bind_input_parameter(1, DataType::Integer, &year, None)
38 .unwrap();
39 let stmt = match stmt.execute() {
40 ReturnOption::Success(s) |
41 ReturnOption::Info(s) => s,
42 ReturnOption::NoData(_) |
43 ReturnOption::Error(_) => panic!("No Result Set"),
44 };
45 stmt.reset_parameters()
46}Sourcepub fn reset_columns(self) -> Statement<'con, 'param, 'static, S, A>
pub fn reset_columns(self) -> Statement<'con, 'param, 'static, S, A>
Unbinds column buffers from result set.
Examples found in repository?
106fn fetch<'con, 'p, 'c, C>(
107 cursor: Statement<'con, 'p, 'c, C>,
108 year: &mut u32,
109 title: &mut [u8],
110 ind_year: &mut SQLLEN,
111 ind_title: &mut SQLLEN,
112) -> MyResult<Option<Statement<'con, 'p, 'c, Positioned>>>
113where
114 C: CursorState,
115{
116 use ReturnOption::*;
117 let cursor = cursor.bind_col(1, year, Some(ind_year)).into_result()?;
118 let cursor = cursor.bind_col(2, &mut title[..], Some(ind_title)).into_result()?;
119 let cursor = match cursor.fetch() {
120 Success(s) | Info(s) => Some(s.reset_columns()),
121 NoData(_) => None,
122 Error(s) => return Err(s.into()),
123 };
124 Ok(cursor)
125}Source§impl<'con, 'param, 'col, C, A> Statement<'con, 'param, 'col, C, A>where
C: CursorState,
impl<'con, 'param, 'col, C, A> Statement<'con, 'param, 'col, C, A>where
C: CursorState,
Sourcepub fn num_result_cols(&self) -> Return<SQLSMALLINT>
pub fn num_result_cols(&self) -> Return<SQLSMALLINT>
Returns the number of columns of the result set
See [SQLNumResultCols][1] [1]: https://docs.microsoft.com/sql/odbc/reference/syntax/sqlnumresultcols-function
Examples found in repository?
83fn print_fields(result_set: ResultSet<Unprepared>) -> MyResult<()> {
84 let cols = result_set.num_result_cols().unwrap();
85 let mut buffer = [0u8; 512];
86 let mut cursor = match result_set.fetch() {
87 ReturnOption::Success(r) |
88 ReturnOption::Info(r) => r,
89 ReturnOption::NoData(_) => return Ok(()),
90 ReturnOption::Error(e) => return Err(e.into()),
91 };
92 loop {
93 for index in 1..(cols + 1) {
94 match cursor.get_data(index as u16, &mut buffer as &mut [u8]) {
95 ReturnOption::Success(ind) |
96 ReturnOption::Info(ind) => {
97 match ind {
98 Indicator::NoTotal => panic!("No Total"),
99 Indicator::Null => println!("NULL"),
100 Indicator::Length(l) => {
101 print!("{}", from_utf8(&buffer[0..l as usize]).unwrap());
102 }
103 }
104 }
105 ReturnOption::NoData(_) => panic!("No Field Data"),
106 ReturnOption::Error(_) => return Err(cursor.into()),
107 }
108 print!(" | ");
109 }
110 cursor = match cursor.fetch() {
111 ReturnOption::Success(r) |
112 ReturnOption::Info(r) => r,
113 ReturnOption::NoData(_) => break Ok(()),
114 ReturnOption::Error(e) => break Err(e.into()),
115 };
116 println!("");
117 }
118}Sourcepub fn affected_row_count(&self) -> Return<SQLLEN>
pub fn affected_row_count(&self) -> Return<SQLLEN>
Returns the number of rows affetced by INSERT, UPDATE, etc
See [SQLRowCount][1] [1]: https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlrowcount-function
Examples found in repository?
15fn exec(conn: &Connection<AutocommitOn>, sql: &str) {
16 let stmt = Statement::with_parent(conn).unwrap();
17 let rs = match stmt.exec_direct(sql) {
18 ReturnOption::Success(s) |
19 ReturnOption::Info(s) => Ok(s),
20 ReturnOption::NoData(_) => Err("Statement did not return a Result Set.".to_owned()),
21 ReturnOption::Error(_) => Err("Error".to_owned()),
22 };
23
24 let row_count = rs.unwrap().affected_row_count();
25 println!("Affected row count for last statement: {:?}", row_count);
26}Sourcepub fn fetch(
self,
) -> ReturnOption<Statement<'con, 'param, 'col, Positioned, A>, Statement<'con, 'param, 'col, NoCursor, A>>
pub fn fetch( self, ) -> ReturnOption<Statement<'con, 'param, 'col, Positioned, A>, Statement<'con, 'param, 'col, NoCursor, A>>
Advances Cursor to next row
See [SQLFetch][1] See [Fetching a Row of Data][2] [1]: https://docs.microsoft.com/sql/odbc/reference/syntax/sqlfetch-function [2]: https://docs.microsoft.com/sql/odbc/reference/develop-app/fetching-a-row-of-data
Examples found in repository?
106fn fetch<'con, 'p, 'c, C>(
107 cursor: Statement<'con, 'p, 'c, C>,
108 year: &mut u32,
109 title: &mut [u8],
110 ind_year: &mut SQLLEN,
111 ind_title: &mut SQLLEN,
112) -> MyResult<Option<Statement<'con, 'p, 'c, Positioned>>>
113where
114 C: CursorState,
115{
116 use ReturnOption::*;
117 let cursor = cursor.bind_col(1, year, Some(ind_year)).into_result()?;
118 let cursor = cursor.bind_col(2, &mut title[..], Some(ind_title)).into_result()?;
119 let cursor = match cursor.fetch() {
120 Success(s) | Info(s) => Some(s.reset_columns()),
121 NoData(_) => None,
122 Error(s) => return Err(s.into()),
123 };
124 Ok(cursor)
125}More examples
48fn print_fields<'a>(
49 result_set: ResultSet<'a, 'a, 'a, Prepared>,
50) -> Statement<'a, 'a, 'a, NoCursor, Prepared> {
51 let mut buffer = [0u8; 512];
52 let mut cursor = match result_set.fetch() {
53 ReturnOption::Success(r) |
54 ReturnOption::Info(r) => r,
55 ReturnOption::NoData(r) |
56 ReturnOption::Error(r) => return r,
57 };
58 loop {
59 match cursor.get_data(1, &mut buffer as &mut [u8]) {
60 ReturnOption::Success(ind) |
61 ReturnOption::Info(ind) => {
62 match ind {
63 Indicator::NoTotal => panic!("No Total"),
64 Indicator::Null => println!("NULL"),
65 Indicator::Length(l) => {
66 print!("{}", from_utf8(&buffer[0..l as usize]).unwrap());
67 }
68 }
69 }
70 ReturnOption::NoData(_) |
71 ReturnOption::Error(_) => panic!("No Field Data"),
72 }
73 cursor = match cursor.fetch() {
74 ReturnOption::Success(r) |
75 ReturnOption::Info(r) => r,
76 ReturnOption::NoData(r) |
77 ReturnOption::Error(r) => break r,
78 };
79 println!("");
80 }
81}83fn print_fields(result_set: ResultSet<Unprepared>) -> MyResult<()> {
84 let cols = result_set.num_result_cols().unwrap();
85 let mut buffer = [0u8; 512];
86 let mut cursor = match result_set.fetch() {
87 ReturnOption::Success(r) |
88 ReturnOption::Info(r) => r,
89 ReturnOption::NoData(_) => return Ok(()),
90 ReturnOption::Error(e) => return Err(e.into()),
91 };
92 loop {
93 for index in 1..(cols + 1) {
94 match cursor.get_data(index as u16, &mut buffer as &mut [u8]) {
95 ReturnOption::Success(ind) |
96 ReturnOption::Info(ind) => {
97 match ind {
98 Indicator::NoTotal => panic!("No Total"),
99 Indicator::Null => println!("NULL"),
100 Indicator::Length(l) => {
101 print!("{}", from_utf8(&buffer[0..l as usize]).unwrap());
102 }
103 }
104 }
105 ReturnOption::NoData(_) => panic!("No Field Data"),
106 ReturnOption::Error(_) => return Err(cursor.into()),
107 }
108 print!(" | ");
109 }
110 cursor = match cursor.fetch() {
111 ReturnOption::Success(r) |
112 ReturnOption::Info(r) => r,
113 ReturnOption::NoData(_) => break Ok(()),
114 ReturnOption::Error(e) => break Err(e.into()),
115 };
116 println!("");
117 }
118}Sourcepub fn close_cursor(
self,
) -> Return<Statement<'con, 'param, 'col, NoCursor>, Statement<'con, 'param, 'col, C, A>>
pub fn close_cursor( self, ) -> Return<Statement<'con, 'param, 'col, NoCursor>, Statement<'con, 'param, 'col, C, A>>
Closes the cursor. Cursors only need to be closed explicitly if the Statement handle is intended to be reused, but a result set is not consumed.
See [SQLCloseCursor][1] See [Closing the Cursor][2] [1]: https://docs.microsoft.com/sql/odbc/reference/syntax/sqlclosecursor-function [2]: https://docs.microsoft.com/sql/odbc/reference/develop-app/closing-the-cursor
Sourcepub fn describe_col<T>(
&mut self,
column_number: SQLUSMALLINT,
column_name: &mut T,
column_name_indicator: &mut SQLSMALLINT,
nullable: &mut Nullable,
) -> Return<Option<DataType>>where
T: OutputBuffer + ?Sized,
pub fn describe_col<T>(
&mut self,
column_number: SQLUSMALLINT,
column_name: &mut T,
column_name_indicator: &mut SQLSMALLINT,
nullable: &mut Nullable,
) -> Return<Option<DataType>>where
T: OutputBuffer + ?Sized,
Return information about result set column
See [SQLDescribeCol Function][1] [1]: https://docs.microsoft.com/sql/odbc/reference/syntax/sqldescribecol-function
Source§impl<'con, 'param, 'col> Statement<'con, 'param, 'col, NoCursor, Unprepared>
impl<'con, 'param, 'col> Statement<'con, 'param, 'col, NoCursor, Unprepared>
Sourcepub fn with_parent<AC: AutocommitMode>(
parent: &'con Connection<'_, AC>,
) -> Return<Self>
pub fn with_parent<AC: AutocommitMode>( parent: &'con Connection<'_, AC>, ) -> Return<Self>
Allocates a new Statement
Examples found in repository?
More examples
15fn exec(conn: &Connection<AutocommitOn>, sql: &str) {
16 let stmt = Statement::with_parent(conn).unwrap();
17 let rs = match stmt.exec_direct(sql) {
18 ReturnOption::Success(s) |
19 ReturnOption::Info(s) => Ok(s),
20 ReturnOption::NoData(_) => Err("Statement did not return a Result Set.".to_owned()),
21 ReturnOption::Error(_) => Err("Error".to_owned()),
22 };
23
24 let row_count = rs.unwrap().affected_row_count();
25 println!("Affected row count for last statement: {:?}", row_count);
26}5fn main() {
6 let env = Environment::new().unwrap();
7 let env = env.declare_version_3().unwrap();
8
9 let ds = DataSource::with_parent(&env).unwrap();
10 let conn = ds.connect("TestDataSource", "", "").unwrap();
11 let mut conn = conn.disable_autocommit().unwrap();
12
13 {
14 //Any statement now will start transaction which could be ended with conn.commit() or conn.rollback()
15 //If either commit or rollback was not called before connection drop automatic rollback will be issued
16 let stmt = Statement::with_parent(&conn).unwrap();
17 let res = stmt.exec_direct("SELECT 'HELLO' FROM MOVIES");
18 println!("Result {:?}", res);
19 }
20
21 let end_tx_result = conn.commit();
22
23 println!("End TX result {:?}", end_tx_result);
24}Sourcepub fn prepare<T>(
self,
statement_text: &T,
) -> Return<Statement<'con, 'param, 'col, NoCursor, Prepared>, Statement<'con, 'param, 'col, NoCursor>>
pub fn prepare<T>( self, statement_text: &T, ) -> Return<Statement<'con, 'param, 'col, NoCursor, Prepared>, Statement<'con, 'param, 'col, NoCursor>>
Prepares a Statement for execution by creating an Access Plan.
See [SQLPrepare Function][1] See [Prepare and Execute a Statement (ODBC)][2] [1]: https://docs.microsoft.com/sql/odbc/reference/syntax/sqlprepare-function [2]: https://docs.microsoft.com/sql/relational-databases/native-client-odbc-how-to/execute-queries/prepare-and-execute-a-statement-odbc
Sourcepub fn exec_direct<T>(
self,
statement_text: &T,
) -> ReturnOption<ResultSet<'con, 'param, 'col, Unprepared>, Statement<'con, 'param, 'col, NoCursor>>
pub fn exec_direct<T>( self, statement_text: &T, ) -> ReturnOption<ResultSet<'con, 'param, 'col, Unprepared>, Statement<'con, 'param, 'col, NoCursor>>
Executes a preparable statement, using the current values of the parametr marker variables.
- See [SQLExecDirect][1]
- See [Direct Execution][2] [1]: https://docs.microsoft.com/sql/odbc/reference/syntax/sqlexecdirect-function [2]: https://docs.microsoft.com/sql/odbc/reference/develop-app/direct-execution-odbc
Examples found in repository?
More examples
15fn exec(conn: &Connection<AutocommitOn>, sql: &str) {
16 let stmt = Statement::with_parent(conn).unwrap();
17 let rs = match stmt.exec_direct(sql) {
18 ReturnOption::Success(s) |
19 ReturnOption::Info(s) => Ok(s),
20 ReturnOption::NoData(_) => Err("Statement did not return a Result Set.".to_owned()),
21 ReturnOption::Error(_) => Err("Error".to_owned()),
22 };
23
24 let row_count = rs.unwrap().affected_row_count();
25 println!("Affected row count for last statement: {:?}", row_count);
26}5fn main() {
6 let env = Environment::new().unwrap();
7 let env = env.declare_version_3().unwrap();
8
9 let ds = DataSource::with_parent(&env).unwrap();
10 let conn = ds.connect("TestDataSource", "", "").unwrap();
11 let mut conn = conn.disable_autocommit().unwrap();
12
13 {
14 //Any statement now will start transaction which could be ended with conn.commit() or conn.rollback()
15 //If either commit or rollback was not called before connection drop automatic rollback will be issued
16 let stmt = Statement::with_parent(&conn).unwrap();
17 let res = stmt.exec_direct("SELECT 'HELLO' FROM MOVIES");
18 println!("Result {:?}", res);
19 }
20
21 let end_tx_result = conn.commit();
22
23 println!("End TX result {:?}", end_tx_result);
24}Source§impl<'con, 'param, 'col> Statement<'con, 'param, 'col, NoCursor, Prepared>
impl<'con, 'param, 'col> Statement<'con, 'param, 'col, NoCursor, Prepared>
Sourcepub fn describe_col<T>(
&mut self,
column_number: SQLUSMALLINT,
column_name: &mut T,
column_name_indicator: &mut SQLSMALLINT,
nullable: &mut Nullable,
) -> Return<Option<DataType>>where
T: OutputBuffer + ?Sized,
pub fn describe_col<T>(
&mut self,
column_number: SQLUSMALLINT,
column_name: &mut T,
column_name_indicator: &mut SQLSMALLINT,
nullable: &mut Nullable,
) -> Return<Option<DataType>>where
T: OutputBuffer + ?Sized,
Return information about result set column
See [SQLDescribeCol Function][1] [1]: https://docs.microsoft.com/sql/odbc/reference/syntax/sqldescribecol-function
Sourcepub fn execute(
self,
) -> ReturnOption<ResultSet<'con, 'param, 'col, Prepared>, Self>
pub fn execute( self, ) -> ReturnOption<ResultSet<'con, 'param, 'col, Prepared>, Self>
Executes a prepared statement, using the current values fo the parameter marker variables if any parameter markers exist in the statement.
See [SQLExecute Function][1] See [Prepared Execution][2] [1]: https://docs.microsoft.com/sql/odbc/reference/syntax/sqlexecute-function [2]: https://docs.microsoft.com/sql/odbc/reference/develop-app/prepared-execution-odbc
Examples found in repository?
33fn execute_query<'a>(
34 stmt: Statement<'a, 'a, 'a, NoCursor, Prepared>,
35 year: i32,
36) -> ResultSet<'a, 'a, 'a, Prepared> {
37 let stmt = stmt.bind_input_parameter(1, DataType::Integer, &year, None)
38 .unwrap();
39 let stmt = match stmt.execute() {
40 ReturnOption::Success(s) |
41 ReturnOption::Info(s) => s,
42 ReturnOption::NoData(_) |
43 ReturnOption::Error(_) => panic!("No Result Set"),
44 };
45 stmt.reset_parameters()
46}Source§impl<'con, 'param, 'col, A> Statement<'con, 'param, 'col, Positioned, A>
impl<'con, 'param, 'col, A> Statement<'con, 'param, 'col, Positioned, A>
Sourcepub fn get_data<T>(
&mut self,
col_or_param_num: SQLUSMALLINT,
target: &mut T,
) -> ReturnOption<Indicator>
pub fn get_data<T>( &mut self, col_or_param_num: SQLUSMALLINT, target: &mut T, ) -> ReturnOption<Indicator>
Retrieves data for a single column or output parameter.
See [SQLGetData][1] [1]: https://docs.microsoft.com/sql/odbc/reference/syntax/sqlgetdata-function
Examples found in repository?
48fn print_fields<'a>(
49 result_set: ResultSet<'a, 'a, 'a, Prepared>,
50) -> Statement<'a, 'a, 'a, NoCursor, Prepared> {
51 let mut buffer = [0u8; 512];
52 let mut cursor = match result_set.fetch() {
53 ReturnOption::Success(r) |
54 ReturnOption::Info(r) => r,
55 ReturnOption::NoData(r) |
56 ReturnOption::Error(r) => return r,
57 };
58 loop {
59 match cursor.get_data(1, &mut buffer as &mut [u8]) {
60 ReturnOption::Success(ind) |
61 ReturnOption::Info(ind) => {
62 match ind {
63 Indicator::NoTotal => panic!("No Total"),
64 Indicator::Null => println!("NULL"),
65 Indicator::Length(l) => {
66 print!("{}", from_utf8(&buffer[0..l as usize]).unwrap());
67 }
68 }
69 }
70 ReturnOption::NoData(_) |
71 ReturnOption::Error(_) => panic!("No Field Data"),
72 }
73 cursor = match cursor.fetch() {
74 ReturnOption::Success(r) |
75 ReturnOption::Info(r) => r,
76 ReturnOption::NoData(r) |
77 ReturnOption::Error(r) => break r,
78 };
79 println!("");
80 }
81}More examples
83fn print_fields(result_set: ResultSet<Unprepared>) -> MyResult<()> {
84 let cols = result_set.num_result_cols().unwrap();
85 let mut buffer = [0u8; 512];
86 let mut cursor = match result_set.fetch() {
87 ReturnOption::Success(r) |
88 ReturnOption::Info(r) => r,
89 ReturnOption::NoData(_) => return Ok(()),
90 ReturnOption::Error(e) => return Err(e.into()),
91 };
92 loop {
93 for index in 1..(cols + 1) {
94 match cursor.get_data(index as u16, &mut buffer as &mut [u8]) {
95 ReturnOption::Success(ind) |
96 ReturnOption::Info(ind) => {
97 match ind {
98 Indicator::NoTotal => panic!("No Total"),
99 Indicator::Null => println!("NULL"),
100 Indicator::Length(l) => {
101 print!("{}", from_utf8(&buffer[0..l as usize]).unwrap());
102 }
103 }
104 }
105 ReturnOption::NoData(_) => panic!("No Field Data"),
106 ReturnOption::Error(_) => return Err(cursor.into()),
107 }
108 print!(" | ");
109 }
110 cursor = match cursor.fetch() {
111 ReturnOption::Success(r) |
112 ReturnOption::Info(r) => r,
113 ReturnOption::NoData(_) => break Ok(()),
114 ReturnOption::Error(e) => break Err(e.into()),
115 };
116 println!("");
117 }
118}