From eba063a12088e82bcdf1ac1453bed4081a17cbf8 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 3 May 2012 20:58:30 +0200 Subject: [PATCH] Implement get_affected_rows() for ODBC backend. Use SQLRowCount() to implement this but also check for SQL_NO_DATA to avoid calling it unnecessarily when we are sure that no rows were affected anyhow. Signed-off-by: Vadim Zeitlin --- src/backends/odbc/soci-odbc.h | 1 + src/backends/odbc/statement.cpp | 22 +++++++++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/backends/odbc/soci-odbc.h b/src/backends/odbc/soci-odbc.h index 4aadcb136..9c5ecbcd6 100644 --- a/src/backends/odbc/soci-odbc.h +++ b/src/backends/odbc/soci-odbc.h @@ -197,6 +197,7 @@ struct odbc_statement_backend : details::statement_backend bool hasVectorUseElements_; bool boundByName_; bool boundByPos_; + bool lastNoData_; // true if last query returned SQL_NO_DATA std::string query_; std::vector names_; // list of names for named binds diff --git a/src/backends/odbc/statement.cpp b/src/backends/odbc/statement.cpp index 0811dbe2f..5b4da07d5 100644 --- a/src/backends/odbc/statement.cpp +++ b/src/backends/odbc/statement.cpp @@ -24,7 +24,8 @@ using namespace soci::details; odbc_statement_backend::odbc_statement_backend(odbc_session_backend &session) : session_(session), hstmt_(0), numRowsFetched_(0), - hasVectorUseElements_(false), boundByName_(false), boundByPos_(false) + hasVectorUseElements_(false), boundByName_(false), boundByPos_(false), + lastNoData_(false) { } @@ -163,6 +164,8 @@ odbc_statement_backend::execute(int number) "Statement Execute"); } + lastNoData_ = rc == SQL_NO_DATA; + SQLSMALLINT colCount; SQLNumResultCols(hstmt_, &colCount); @@ -201,8 +204,21 @@ odbc_statement_backend::fetch(int number) long long odbc_statement_backend::get_affected_rows() { - // ... - return -1; + // Calling SQLRowCount() when the last call to SQLExecute() returned + // SQL_NO_DATA can fail, so simply always return 0 in this case as we know + // that nothing was done anyhow. + if (lastNoData_) + return 0; + + SQLLEN res; + SQLRETURN rc = SQLRowCount(hstmt_, &res); + if (is_odbc_error(rc)) + { + throw odbc_soci_error(SQL_HANDLE_STMT, hstmt_, + "Getting number of affected rows"); + } + + return res; } int odbc_statement_backend::get_number_of_rows()