MySQL C API参数化查询获取结果

时间:2016-03-28 16:37:28

标签: mysql c

我已经花了3个小时才完成这项工作。 我阅读了关于mysql_stmt函数的10次MySQL C API文档。

我需要的是这样的:mysql_stmt_fetch()

问题是我需要参数化查询,因为有1个用户输入。

代码如下:

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;
}

我已经测试了mysql_stmt_bind_result和其他功能。 第一次尝试是准备,绑定和执行。获取行数并始终为0.无论如何,始终为0。

有人能告诉我从参数化查询中获得结果的正确方法吗?

编辑1: 似乎有用的新代码,但有些东西很奇怪:

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";
}

出局是:

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

我想它就在这里:

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

所以,我创建了MYSQL_BIND并准备绑定params(输入)。 然后我执行了。这是一个错误,我不知道它是什么。 我正在搜索如何访问char *以查看当前的sql查询以进行故障排除。

1 个答案:

答案 0 :(得分:2)

我想,你有几个错误:

1)你的查询有一个(输入)参数和2个(输出)列,但你只定义了一个MYSQL_BIND,可能是输入参数。

2)初始化时:

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

如果此绑定用于输入参数,则必须更改为:

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

并通过此调用传递:

mysql_stmt_bind_param(stmt,bind);

3)你的mysql_stmt_execute命令在哪里?提取不工作是您的查询未执行

我不检查提取代码,但它看起来很好(如果没有请注意我)