Koka / odbc-rs

Rust ODBC FFI binding
MIT License
103 stars 31 forks source link

Running Insert Prepared Statement in Vertica returns Resultsetstate Data #81

Closed vnnv01 closed 5 years ago

vnnv01 commented 6 years ago

I tried running prepared statementinsert into test (a) values (:?) and stmt.execute returned resultsetstate with value as Data. Now I cannot resuse this prepare statement because , when I call stmt.close_cursor() vertica complains "Invalid cursor state". So how can I reuse the prepared statement again. Why is the stmt.execute gives me ResultsetState of Data in place of NoData.

Koka commented 6 years ago

@vnnv01 Not sure about resultset from insert statement - it looks like it's specific for Vertica or something.

But nevertheless you should be able to reuse prepared statement using reset_parameters statement method as shown in https://github.com/Koka/odbc-rs/blob/master/examples/bind_params.rs - you could try just not to iterate result set and not close cursor if you sure it's returned to you by error. Like just bind params, call insert, reset params, repeat.

vnnv01 commented 6 years ago

@Koka Thanks for your response. executefunction of statement returns resultsetstatewith Data or No Data values and when I try to run insert prepared statement , execute function returns resultsetstatewith Data values. So now when I tried to run the matchstatement, I have to run close_cursorto get compatible types and then run the stmt.reset_parameters()and it seems statement.reset_parameters cannot be called on statement which has trait with Preparedor HasResultvalue. below is my code.

fn execute_sql_stmt<'a>(
    stmt: Statement<'a,'a, Prepared, NoResult>) -> errors::Result<Statement<'a, 'a, Prepared, NoResult>> {
    println!("Inside execute sql stmt function");
    let stmt = match stmt.execute()?{
       Data(stmt) => stmt.close_cursor()?,
        NoData(stmt) => stmt,
    };
       println!("execute_sql_stmt function executed the statement");
       Ok(stmt.reset_parameters().chain_err(|| "Hi")?)
}
adlerd commented 6 years ago

@Koka I got the same thing from [ODBC Driver 13 for SQL Server].

match stmt.exec_direct("select * into ...")? {
    odbc::ResultSetState::NoData(s) => s,
    odbc::ResultSetState::Data(s) => s.close_cursor()?,
};

resulted in

State: 24000, Native error: 0, Message: [Microsoft][ODBC Driver 13 for SQL Server]Invalid cursor state

from the close_cursor line.

Unfortunately I think that the odbc crate is not correctly modeling the state transition. SQL_SUCCESS return value from, e.g., SQLExecDirect does not guarantee that a result set has been created. Though it doesn't say it directly, the documentation strongly implies this, and also offers a way to know for sure.

Koka commented 5 years ago

@vnnv01 @adlerd I've created pull request which tries to use SQLNumResultCols call to determine if resultset is available. Unfortunately, I can't properly test it at this moment - could you please check if this PR actually fixes the problem?

Koka commented 5 years ago

Let's merge this PR and close this issue. If problem will be reproduced again - feel free to reopen it again