int3
int3

Reputation: 658

MySQL C API parameterized query fetch result

I've been like 3 hours on this and I can't make this work. I read MySQL C API documentation like 10 times about mysql_stmt functions.

What I need is like this: mysql_stmt_fetch()

The thing is I need a parametrized query because there is 1 user input.

Code is as follows:

char* regSol(char* token,MYSQL *conn){
    char* regnr;
    MYSQL_STMT *stmt;
    MYSQL_BIND bind[1];
    unsigned long str_length;
   /*
    * Validation
    */
    stmt = mysql_stmt_init(conn);
    char *sql="SELECT REGNR,Token FROM registed WHERE Token=?";
    if(mysql_stmt_prepare(stmt,sql,strlen(sql))){
        fprintf(stderr, " mysql_stmt_prepare(), SELECT failed\n");
        fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
        exit(1);
    }

    memset(bind, 0, sizeof(bind)); //clears the structure.

    bind[0].buffer= 0;
    bind[0].buffer_length= 0;
    bind[0].length= &str_length;

    if(mysql_stmt_bind_result(stmt,bind))
    {
      fprintf(stderr, " mysql_stmt_bind_result(), failed\n");
      fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
      exit(1);
    }    
    /*
     fetch data
     */

    unsigned long long nrow=0;

    mysql_stmt_fetch(stmt);
    if (str_length > 0)
    {
      char *data= (char*) malloc(str_length);
      bind[0].buffer= data;
      bind[0].buffer_length= str_length;
      mysql_stmt_fetch_column(stmt, bind, 0, 0);
      fprintf(stdout,"DEBUG !! - %s - !!\n",data);
    }

    return NULL;
}

I already tested mysql_stmt_bind_result and other functions. The first try was preparing, binding and execute. fetch num of rows and it was always 0. No matter what, always 0.

Can anyone tell me the right way to get a result from a parametrized query?

EDIT 1: new code that seems what will work but something is weird:

char* regSol(char* token,MYSQL *conn){

    /*
     * Needs to be completed. I have no idea why I can make this work
     * Tested a lot of functions and got some SEGVs and 0 rows.
     * And results that aren't even in the database
     */
    char* regnr;
    MYSQL_STMT *stmt;
    MYSQL_BIND bind[1];
    unsigned long str_length;
   /*
    * Validation
    */
    stmt = mysql_stmt_init(conn);
    char *sql="SELECT REGNR FROM registed WHERE Token=?";
    if(mysql_stmt_prepare(stmt,sql,strlen(sql))){
        fprintf(stderr, " mysql_stmt_prepare(), SELECT failed\n");
        fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
        exit(1);
    }

    memset(bind, 0, sizeof(bind)); //clears the structure.
    bind[0].buffer_type=MYSQL_TYPE_STRING;
    bind[0].buffer=(char*)token;
    bind[0].buffer_length=strlen(token)+1;
    bind[0].length= &str_length;

    if(mysql_stmt_bind_param(stmt,bind))
    {
      fprintf(stderr, " mysql_stmt_bind_param(), failed\n");
      fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
      exit(1);
    }

    if(mysql_stmt_execute(stmt)){
        fprintf(stderr," mysql_stmt_execute(), failed\n");
        fprintf(stderr, "%s\n",mysql_stmt_error(stmt));
        exit(1);
    }

    /*
     fetch data
     */
    //bind result
    MYSQL_BIND resbind[1];
    unsigned long reslen=0;
    resbind[0].buffer=0;
    resbind[0].buffer_length=0;
    resbind[0].length=&reslen;

    if(mysql_stmt_bind_result(stmt,resbind)){
        fprintf(stderr," mysql_stmt_bind_result(), failed\n");
        fprintf(stderr, "%s\n",mysql_stmt_error(stmt));
        exit(1);
    }

    mysql_stmt_fetch(stmt);
    if (reslen > 0) //size of buffer?
    {
        char *data=(char*)malloc(reslen);
        bind[0].buffer=data;
        bind[0].buffer_length=reslen;
        mysql_stmt_fetch_column(stmt, bind, 0, 0);
        fprintf(stdout,"Result Len:%lu\nRegistation NR:%s",reslen,data);
        free(data);
    }
    return "1";
}

The out is:

mysql_stmt_execute(), failed
Got packet bigger than 'max_allowed_packet' bytes

I think it's on here:

if(mysql_stmt_execute(stmt)){
        fprintf(stderr," mysql_stmt_execute(), failed\n");
        fprintf(stderr, "%s\n",mysql_stmt_error(stmt));
        exit(1);
    }

So,I created MYSQL_BIND and prepare to bind params (input). Then I executed. It makes an error which I don't know what It is. I'm googling how I can access a char* to see the current sql query for troubleshooting.

Upvotes: 2

Views: 841

Answers (1)

I think, you have a couple of errors:

1) your query has one (input) parameter and 2 (output) columns, but your defining just one MYSQL_BIND, maybe for input parameter.

2) when you initialize:

bind[0].buffer= 0;
bind[0].buffer_length= 0;
bind[0].length= &str_length;

if this bind is for input parameter, you must change to:

bind[0].buffer= token;
bind[0].buffer_length= strlen(token) + 1;

and pass it with this call:

mysql_stmt_bind_param(stmt,bind);

3) where is your mysql_stmt_execute command? fetch dont work is your query is not executed

I dont check fetch code, but it looks like fine (notice me if not)

Upvotes: 2

Related Questions