可以通过MariaDB Connect/c准备的语句通过transmate字符串

发布于 2025-02-13 15:29:00 字数 3612 浏览 0 评论 0原文

作业

MariaDB none@(none):test> SELECT * FROM t3
c
使用
MariadbConnector
3 rows in set
Time: 0.010s
MariaDB none@(none):test> DESC t3
正在/密钥默认额外
aint(11)nopri
bchar(10)是的
2 rows in set
Time: 0.011s

,我用来测试的代码:

#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...                                                 

我对此遇到了两天的麻烦,明天是截止日期,我'我很着急。你能帮忙吗?多谢!

I'm using "MariaDB Connector/C" for my homework, but I got a problem: I always get an empty string when I pass in a string parameter, the db table is:

MariaDB none@(none):test> SELECT * FROM t3
ab
0abc
1bcd
2af
3 rows in set
Time: 0.010s
MariaDB none@(none):test> DESC t3
FieldTypeNullKeyDefaultExtra
aint(11)NOPRI
bchar(10)YES
2 rows in set
Time: 0.011s

And the code I use to test:

#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);

}

I only got an empty result:

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

I have been in trouble with this for two days, and tomorrow is the deadline, I'm very anxious. Can you help? Thanks a lot!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

命比纸薄 2025-02-20 15:29:00

1)常规

  • 避免“很难编写,因此应该很难读取”代码
  • 在函数开始时添加变量声明,而不是在代码中间(wdeclaration-terter-sattatement)
  • 使用C ++注释
  • 请勿使用API​​函数mysql_set_character_set()
  • 编写正确的错误处理,包括mysql_error/mysql_stmt_error结果,请不要 。错误后继续执行后续代码。
  • 始终初始化mysql_bind

2)输入绑定缓冲区

  • U. Indicator用于批量操作,在这里不需要
  • bind.is_null 注释)

3)输出绑定缓冲区

  • 在mysql_stmt_execute()之后始终绑定输出参数,因为MySQL_STMT_PREPARE不能总是确定参数数量,例如调用存储过程时:在这种情况下,MySQL_STMT_BIND_PARAM将返回错误。
  • 则绑定错误指示器没有多大意义

如果不设置mysql_report_data_truncation(mysql_optionsv) , -Connector-C/Tree/3.3/Unitest/libmariaDB“ rel =“ nofollow noreferrer”> Mariadb连接器/C单元测试

1) General

  • Avoid "it was hard to write, so it should be hard to read" code
  • add variable declarations at the beginning of the function, not in the middle of code (Wdeclaration-after-statement)
  • don't use c++ comments in C
  • set character set with api function mysql_set_character_set()
  • write proper error handling, including mysql_error/mysql_stmt_error results and don't continue executing subsequent code after error.
  • always initialize MYSQL_BIND

2) input bind buffer

  • u.indicator is used for bulk operations and doesn't make sense here
  • bind.is_null is not required, since you specified a valid buffer address
  • buffer_length is not set (in comments)

3) Output bind buffer

  • Always bind output parameters after mysql_stmt_execute(), since mysql_stmt_prepare can't always determine the number of parameters, e.g. when calling a stored procedure: In this case mysql_stmt_bind_param will return an error.
  • binding an error indicator doesn't make much sense without setting MYSQL_REPORT_DATA_TRUNCATION (mysql_optionsv)

For some examples how to deal with prepared statements check the file ps.c of MariaDB Connector/C unit tests

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文