From 1a564f84da39a309e40353ae52f2bb4366268a1e Mon Sep 17 00:00:00 2001 From: Paul Oliver Date: Thu, 26 Nov 2009 13:54:36 +0000 Subject: SQL_NO_DATA and SQLSTATE 00000 indicate success for updates/deletes that affect no rows I noticed the following when no rows were updated for an update statement: 4> odbc:param_query(Ref, "update tbadger set status = ? where badger_id = ?", [{{sql_varchar,1},["R"]}, {sql_integer, [61111]}]). {error,"No SQL-driver information available."} 5> odbc:param_query(Ref, "update tbadger set status = ? where badger_id = ?", [{{sql_varchar,1},["R"]}, {sql_integer, [61]}]). {updated,1} The attached patch, which requires the ODBC patch from Andrew Thompson, should fix it: 3> odbc:param_query(Ref, "update tbadger set status = ? where badger_id = ?", [{{sql_varchar,1},["R"]}, {sql_integer, [61111]}]). {updated,0} 4> I've followed the advice given on MSDN (http://msdn.microsoft.com/en-us/library/ms715424%28VS.85%29.aspx) and checked for SQL_NO_DATA combined with SQLSTATE 000000 --- lib/odbc/c_src/odbcserver.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'lib') diff --git a/lib/odbc/c_src/odbcserver.c b/lib/odbc/c_src/odbcserver.c index 63177121bc..c292e23206 100644 --- a/lib/odbc/c_src/odbcserver.c +++ b/lib/odbc/c_src/odbcserver.c @@ -749,11 +749,12 @@ static db_result_msg db_param_query(byte *buffer, db_state *state) byte *sql; db_result_msg msg; int i, num_param_values, ver = 0, - erl_type = 0, index = 0, size = 0, cols = 0; + erl_type = 0, index = 0, size = 0, cols = 0; long long_num_param_values; param_status param_status; diagnos diagnos; - param_array *params; + param_array *params; + SQLRETURN result; if (associated_result_set(state)) { clean_state(state); @@ -784,10 +785,16 @@ static db_result_msg db_param_query(byte *buffer, db_state *state) num_param_values, state); if(params != NULL) { - if(!sql_success(SQLExecDirect(statement_handle(state), - sql, SQL_NTS))) { - diagnos = get_diagnos(SQL_HANDLE_STMT, statement_handle(state)); - msg = encode_error_message(diagnos.error_msg); + + result = SQLExecDirect(statement_handle(state), sql, SQL_NTS); + if (!sql_success(result) || result == SQL_NO_DATA) { + diagnos = get_diagnos(SQL_HANDLE_STMT, statement_handle(state)); + } + /* SQL_NO_DATA and SQLSTATE 00000 indicate success for + updates/deletes that affect no rows */ + if(!sql_success(result) && + !(result == SQL_NO_DATA && !strcmp((char *)diagnos.sqlState, INFO))) { + msg = encode_error_message(diagnos.error_msg); } else { for (i = 0; i < param_status.params_processed; i++) { switch (param_status.param_status_array[i]) { @@ -2452,6 +2459,7 @@ static diagnos get_diagnos(SQLSMALLINT handleType, SQLHANDLE handle) int acc_errmsg_size; byte *current_errmsg_pos; SQLCHAR current_sql_state[SQL_STATE_SIZE]; + SQLRETURN result; diagnos.error_msg[0] = 0; @@ -2464,10 +2472,10 @@ static diagnos get_diagnos(SQLSMALLINT handleType, SQLHANDLE handle) /* Foreach diagnostic record in the current set of diagnostic records the error message is obtained */ for(record_nr = 1; ;record_nr++) { - if(SQLGetDiagRec(handleType, handle, record_nr, current_sql_state, + result = SQLGetDiagRec(handleType, handle, record_nr, current_sql_state, &nativeError, current_errmsg_pos, - (SQLSMALLINT)errmsg_buffer_size, &errmsg_size) - != SQL_SUCCESS) { + (SQLSMALLINT)errmsg_buffer_size, &errmsg_size); + if(result != SQL_SUCCESS && result != SQL_NO_DATA) { break; -- cgit v1.2.3