You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MariaDB Connector/C预处理语句传字符串查询返回空结果问题

问题:MariaDB Connector/C 预处理语句传递字符串参数无查询返回结果

使用MariaDB Connector/C完成课程作业的数据库操作时,预处理语句传递字符串参数查询无匹配结果,已排查2天临近提交截止日,相关信息如下:

测试基础信息

  • 测试表t3数据:
    执行查询SQL:
SELECT * FROM t3;

返回结果:

ab
0abc
1bcd
2af
3 rows in set
Time: 0.010s
  • 测试表结构:
    执行结构查询SQL:
DESC t3;

返回结果:

FieldTypeNullKeyDefaultExtra
aint(11)NOPRI
bchar(10)YES
2 rows in set
Time: 0.011s

测试用C语言代码

#include <mysql/mysql.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    MYSQL *mysql;
    mysql = mysql_init(NULL);
    if (!mysql_real_connect(mysql,NULL , "none", "linux", "test", 0,"/tmp/mariadb.sock",0)){
        printf( "Error connecting to database: %s",mysql_error(mysql));
    } else
        printf("Connected...\n");
    if(mysql_real_query(mysql,"SET CHARACTER SET utf8",(unsigned int)sizeof("SET CHARACTER SET utf8"))){
        printf("Failed to set Encode!\n");
    }


    char query_stmt_2[]="select * from t3 where b=?";
    MYSQL_STMT *stmt2 = mysql_stmt_init(mysql);
    if(mysql_stmt_prepare(stmt2, query_stmt_2, -1))
    {
        printf("STMT2 prepare failed.\n");
    }
    MYSQL_BIND instr_bind;
    char instr[50]="abc";
    my_bool in_is_null = 0;
    my_bool in_error = 0;
    instr_bind.buffer_type = MYSQL_TYPE_STRING;
    instr_bind.buffer = &instr[0];
    char in_ind = STMT_INDICATOR_NTS;
    instr_bind.u.indicator = &in_ind;
    unsigned long instr_len=sizeof(instr);
    // instr_bind.length = &instr_len;
    // instr_bind.buffer_length=instr_len;
    instr_bind.is_null = &in_is_null;
    instr_bind.error = &in_error;


    MYSQL_BIND out_bind[2];
    memset(out_bind, 0, sizeof(out_bind));
    int out_int[2];
    char outstr[50];
    my_bool out_int_is_null[2]={0,0};
    my_bool out_int_error[2]={0,0};
    unsigned long out_int_length[2]={0,0};
    out_bind[0].buffer = out_int+0;
    out_bind[0].buffer_type = MYSQL_TYPE_LONG;
    out_bind[0].is_null = out_int_is_null+0;
    out_bind[0].error = out_int_error+0;
    out_bind[0].length = out_int_length+0;

    out_bind[1].buffer = outstr;
    out_bind[1].buffer_type = MYSQL_TYPE_STRING;
    out_bind[1].buffer_length = 50;
    out_bind[1].is_null = out_int_is_null+1;
    out_bind[1].error = out_int_error+1;
    out_bind[1].length = out_int_length+1;

    if(mysql_stmt_bind_param(stmt2, &instr_bind) ||
    mysql_stmt_bind_result(stmt2, out_bind)){
        printf("Bind error\n");
    }

    if(mysql_stmt_execute(stmt2))
    {
        printf("Exec error: %s",mysql_stmt_error(stmt2));
    }

    if(mysql_stmt_store_result(stmt2)){
        printf("Store result error!\n");
        printf("%s\n",mysql_stmt_error(stmt2));
    }
    while(!mysql_stmt_fetch(stmt2))
    {
        printf("%d\t%s\n", out_int[0], outstr);
    }
    mysql_stmt_close(stmt2);
end:
    mysql_close(mysql);

}

运行现象

程序执行后仅输出数据库连接成功提示,无任何查询结果返回,运行输出如下:

❯ ./Exec/test/stmt_test
Connected...                                                 

问题原因与修复方案

代码核心问题出在输入参数MYSQL_BIND的配置错误,具体有两点:

  • STMT_INDICATOR_NTS指示器使用不规范
    你使用STMT_INDICATOR_NTS标识传入字符串为'\0'结尾的空终止字符串,期望驱动自动计算长度,但未给instr_bind设置buffer_length字段,旧版本MariaDB Connector/C会读取该字段未初始化的脏值作为参数长度,导致传给数据库的参数内容异常,无法匹配到b='abc'的记录。
  • 输入参数绑定结构体未初始化
    定义MYSQL_BIND instr_bind时未做清零操作,结构体中未手动赋值的字段为栈上随机脏值,会直接干扰预处理语句的参数解析逻辑。

额外注意:你代码中写的unsigned long instr_len=sizeof(instr);也存在错误,sizeof(instr)获取的是char[50]数组的总长度50,而非存储的字符串"abc"的实际长度3,就算其他配置正确,这里如果用sizeof计算长度,也会把数组后续的栈内存脏值作为参数内容传给数据库,同样无法匹配到正确结果。

修复代码

将输入参数绑定部分替换为以下内容即可:

MYSQL_BIND instr_bind;
// 先清零结构体,避免脏值干扰
memset(&instr_bind, 0, sizeof(instr_bind));
char instr[50]="abc";
my_bool in_is_null = 0;
my_bool in_error = 0;
instr_bind.buffer_type = MYSQL_TYPE_STRING;
instr_bind.buffer = instr;
// 手动指定字符串实际长度,兼容性最好
unsigned long instr_len = strlen(instr);
instr_bind.length = &instr_len;
instr_bind.buffer_length = sizeof(instr);
instr_bind.is_null = &in_is_null;
instr_bind.error = &in_error;

修改后重新编译运行,即可正常返回0 abc的查询结果。


内容的提问来源于stack exchange,提问作者pb_wang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 17:16:17