Hi All,The statement affected rows problem occurs because SQLAPI executes mysql_next_result just after mysql_real_query. The patch uses saved rows affected value and fix the problem.
Thanks to Christoph Merten.The patch also fixes the problem with datetime/timestamp second part/fraction (the binding SADateTime values produces an empty MySQL field values.).
Thanks to Helmut Ebersmann. The patch is attached. -- Best regards, Sergey Chumakov, SQLAPI++ development team
*** myClient.cpp 30 Jun 2007 09:41:25 -0000 1.31 --- myClient.cpp 10 Aug 2007 08:33:46 -0000 *************** *** 358,368 **** --- 358,370 ---- #define SA_MYSQL_MAX_NUMERIC_LENGTH 72 #define SA_MYSQL_MAX_INTERVAL_LENGTH 11 + #define SA_MYSQL_NO_ROWS_AFFECTED (my_ulonglong)(-1) class ImyCursor : public ISACursor { // private handles myCommandHandles m_handles; + my_ulonglong cRows; // private handles (OLD API) MYSQL_ROW m_mysql_row; *************** *** 491,496 **** --- 493,500 ---- SACommand *pCommand) : ISACursor(pImyConnection, pCommand) { + cRows = SA_MYSQL_NO_ROWS_AFFECTED; + m_bOpened = false; m_bResultSetCanBe = false; *************** *** 539,545 **** date_time = SADateTime(dtInternal.year, dtInternal.month, dtInternal.day, dtInternal.hour, dtInternal.minute, dtInternal.second); ! date_time.Fraction() = dtInternal.second_part; } /*virtual */ --- 543,549 ---- date_time = SADateTime(dtInternal.year, dtInternal.month, dtInternal.day, dtInternal.hour, dtInternal.minute, dtInternal.second); ! date_time.Fraction() = dtInternal.second_part * 1000; } /*virtual */ *************** *** 759,768 **** SAString &sInternal) { // format should be YYYY-MM-DD HH:MM:SS.fraction ! sInternal.Format(_TSA("%.4d-%.2d-%.2d %.2d:%.2d:%.2d.%.9ld"), date_time.GetYear(), date_time.GetMonth(), date_time.GetDay(), date_time.GetHour(), date_time.GetMinute(), date_time.GetSecond(), ! date_time.Fraction()); } /*static */ --- 763,772 ---- SAString &sInternal) { // format should be YYYY-MM-DD HH:MM:SS.fraction ! sInternal.Format(_TSA("%.4d-%.2d-%.2d %.2d:%.2d:%.2d.%.6d"), date_time.GetYear(), date_time.GetMonth(), date_time.GetDay(), date_time.GetHour(), date_time.GetMinute(), date_time.GetSecond(), ! (int)(date_time.Fraction() / 1000)); } /*static */ *************** *** 780,786 **** dtInternal.hour = date_time.GetHour(); dtInternal.minute = date_time.GetMinute(); dtInternal.second = date_time.GetSecond(); ! dtInternal.second_part = date_time.Fraction(); } /*virtual */ --- 784,790 ---- dtInternal.hour = date_time.GetHour(); dtInternal.minute = date_time.GetMinute(); dtInternal.second = date_time.GetSecond(); ! dtInternal.second_part = (unsigned long)(date_time.Fraction() / 1000); } /*virtual */ *************** *** 1227,1232 **** --- 1231,1238 ---- } else m_bResultSetCanBe = false; + + cRows = SA_MYSQL_NO_ROWS_AFFECTED; } // executes statement (also binds parameters if needed) *************** *** 1402,1407 **** --- 1408,1416 ---- if(g_myAPI.mysql_query(pConH->mysql, sBoundStmt.GetMultiByteChars())) Check(pConH->mysql); + // save affected rows + GetRowsAffected(); + // procedure can return result set MYSQL_RES *localResult = g_myAPI.mysql_store_result(pConH->mysql); Check(pConH->mysql); *************** *** 1436,1441 **** --- 1445,1453 ---- } else { + // save affected rows + GetRowsAffected(); + SAString sOption = m_pCommand->Option(_TSA("HandleResult")); if(sOption.CompareNoCase(_TSA("store")) == 0) m_handles.result = g_myAPI.mysql_store_result(pConH->mysql); *************** *** 2014,2028 **** /*virtual */ long ImyCursor::GetRowsAffected() { ! my_ulonglong cRows = 0; ! ! if( NULL != m_handles.stmt ) // Use satetment API ! cRows = g_myAPI.mysql_stmt_affected_rows(m_handles.stmt); ! else { ! myConnectionHandles *pConH = ! (myConnectionHandles *)m_pCommand->Connection()->NativeHandles(); ! cRows = g_myAPI.mysql_affected_rows(pConH->mysql); } return (long)cRows; --- 2026,2041 ---- /*virtual */ long ImyCursor::GetRowsAffected() { ! if( SA_MYSQL_NO_ROWS_AFFECTED == cRows ) { ! if( NULL != m_handles.stmt ) // Use satetment API ! cRows = g_myAPI.mysql_stmt_affected_rows(m_handles.stmt); ! else ! { ! myConnectionHandles *pConH = ! (myConnectionHandles *)m_pCommand->Connection()->NativeHandles(); ! cRows = g_myAPI.mysql_affected_rows(pConH->mysql); ! } } return (long)cRows;