0

I have a helper function for using prepared statements with mysql. All works well as long as i dont want to retrieve any results.

If i want to retrieve a result (e.g. simple long ID) im getting a warning from visual studio debugger that the stack is corrupted around my ID variable.

Header bool RunPreparedStatement(std::string query, std::vector paramList, std::string& errbuf, int* affected_rows, bool fetchResultID = false, int32* result_id=0, bool fetchInsertID = false, int32* last_insert_id=0);

bool RunPreparedStatement(std::string sql, std::vector<MYSQL_BIND> paramList, std::string& errStr, int* affected_rows, bool fetchResultID, int32* result_id, bool fetchInsertID, int32* last_insert_id) {
char errbuf[MYSQL_ERRMSG_SIZE];

int numParams = paramList.size();

bool fetchResult = fetchResultID;

if(numParams == 0) {
    errStr = "0 parameters supplied";        
    return false;
}

MYSQL_STMT *stmt = mysql_stmt_init(&mysql);

if (!stmt) {
    errStr = "mysql_stmt_init(), out of memory";         
    return false;
}

if (mysql_stmt_prepare(stmt, sql.c_str(), sql.length())) {
    errStr =  "mysql_stmt_prepare() failed ";
    errStr.append(mysql_stmt_error(stmt));
    return false;
}

int param_count= mysql_stmt_param_count(stmt);

if (param_count != numParams) /* validate parameter count */{
    errStr = "invalid parameter count returned by MySQL";
    return false;
}

if (mysql_stmt_bind_param(stmt, &paramList[0])) {
    errStr = "mysql_stmt_bind_param() failed ";
    errStr.append(mysql_stmt_error(stmt));  
    return false;
}

int32 id = 0;
MYSQL_BIND resultParam1;    
BindValue(&resultParam1,MYSQL_TYPE_LONGLONG,&id,0,0,0);

if(fetchResult) {                       
     /* Bind the results buffer */
  if (mysql_stmt_bind_result(stmt,  &resultParam1) != 0) {      
    errStr = "mysql_stmt_bind_result() failed ";
    errStr.append(mysql_stmt_error(stmt));  
    return false;
  }
}

if (mysql_stmt_execute(stmt)) {
    errStr = "mysql_stmt_execute() failed ";
    errStr.append(mysql_stmt_error(stmt));          
    return false;
}

if(fetchResult) {

    if (mysql_stmt_store_result(stmt) != 0) {         
        errStr = "Could not buffer result set ";
        errStr.append(mysql_stmt_error(stmt));      
        return false;
    }

  if(mysql_stmt_fetch (stmt) == 0) {

      (*result_id) = id;

    // OK
      *affected_rows = 1;
  } else {      
      *affected_rows = 0;
    /*errStr = "no results found ";
    errStr.append(mysql_stmt_error(stmt));
    return false;*/
  }
} else {
    *affected_rows = mysql_stmt_affected_rows(stmt);        
}

if(fetchInsertID) {
    *last_insert_id= mysql_stmt_insert_id(stmt);
}

if(stmt != NULL) {

    // Deallocate result set
    mysql_stmt_free_result(stmt); /* deallocate result set */

     if (mysql_stmt_close(stmt)) {
         errStr = "closing the statement failed ";
         errStr.append(mysql_stmt_error(stmt));
        return false;
    }
}

return true;

}

I call it like this

std::string errBuf;
int affected_rows = 0;
std::string sql = "SELECT count(*) FROM name WHERE (?) like name";

std::vector<MYSQL_BIND> paramList;  
std::vector<MYSQL_BIND> resultParamList;

char data[1024];
safe_strncpy(data,name,sizeof(data), __FILE__, __LINE__);

MYSQL_BIND param1;  
BindValue(&param1,MYSQL_TYPE_STRING,data,strlen(data),0,0);
paramList.push_back(param1);    

int32 count = 0;    

bool ret = true;

if(RunPreparedStatement(sql,paramList,errBuf,&affected_rows,true,&count)){
 ...
}

I previously had also a resultParamList instead of simple the ID and had the same error and thought it was related to return a list of values but that wasnt it.

Im receiving the warning as soon as the RunPreparedStatement method is finished.

4
  • RunPreparedStatement takes 8 arguments, you're only calling it with 6. Commented Aug 8, 2014 at 21:59
  • Sorry the header is bool RunPreparedStatement(std::string query, std::vector<MYSQL_BIND> paramList, std::string& errbuf, int* affected_rows, bool fetchResultID = false, int32* result_id=0, bool fetchInsertID = false, int32* last_insert_id=0); Commented Aug 8, 2014 at 22:08
  • Don't post it in a comment, edit the question. Commented Aug 8, 2014 at 22:08
  • I already did, just FYI Commented Aug 8, 2014 at 22:09

1 Answer 1

0

Trying another sample code i found the issue

int32 id = 0;
MYSQL_BIND resultParam1;    
BindValue(&resultParam1,MYSQL_TYPE_LONGLONG,&id,0,0,0);

im telling that the result type is MYSQL_TYPE_LONGLONG but im only giving it a int32 (unsigned int ) instead of unsigned long long.

So either change to MYSQL_TYPE_LONG or increase var size.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.