@CHLHC@ 2025-12-04 21:43 采纳率: 100%
浏览 19
已结题

关于#c语言#sql#的问题,希望各位专家闲暇时解答一下,十分谢(❁´◡`❁)

  1. 背景:@紫雾凌寒 专家你好(^▽^),本人前一段时间已学习完c语言,现在想通过VScode编写代码(VScode已成功连接MySQL),在第三方软件Navicat中显示表格(序号,姓名,分数)
  1. 问题:sql语句中,只能把具体的值,呈现在Navicat表格里,
    变量的赋值无法体现,只能体现变量本身,具体如下:

1内容不是变量

exeSql("insert into user values ('1','张三',100);");
exeSql("select * from user;");

显示在Navicat的表格里,1 张三 100

2如果内容改成变量,就只能输出变量本身,而不能输出变量的赋值

exeSql("insert into user values ('id','name',score);");
exeSql("select * from user;");

显示在Navicat的表格里,id name (NULL),
id里已经赋值1,但是不能显示

3我想问一下,这种情况下,是我的数据类型出问题了吗?
怎么改呢?劳烦解答一下(〃` 3′〃)

  • 写回答

4条回答 默认 最新

  • 檀越@新空间 2025-12-04 21:51
    关注

    晚上好🌙🌙🌙
    本答案参考通义千问

    你好!很高兴能帮助你解决这个问题。根据你的描述,你在使用 C语言MySQL 进行数据库操作时遇到了一个问题:SQL 语句中无法正确插入变量值,只能插入变量名本身


    ✅ 问题分析

    你提到的代码如下:

    exeSql("insert into user values ('id','name',score);");
    

    这里的问题在于,你直接将字符串中的 idnamescore 当作变量名来使用,但实际上在 SQL 语句中,这些是字符串字面量,而不是 C 语言中的变量。

    也就是说,这段代码实际执行的是:

    INSERT INTO user VALUES ('id', 'name', score);
    

    其中:

    • 'id' 是字符串字面量(即“id”这个字符串);
    • 'name' 同样是字符串字面量;
    • score 被当作一个列名或字段名(如果它是一个列名的话),但如果你没有定义 score 这个列,就会报错;如果是字段名,则可能为 NULL 或其他默认值。

    ✅ 正确做法:使用变量绑定

    在 C 语言中,如果你想通过 SQL 插入变量值,应该使用 参数化查询(也叫预编译语句)的方式,而不是拼接字符串。

    🔧 解决方案

    1. 使用 MySQL 的预编译语句(Prepare Statement)

    你需要使用 mysql_stmt_prepare 来准备 SQL 语句,并通过 mysql_stmt_bind_param 绑定变量。

    2. 示例代码(修改后的版本)

    #include <mysql.h>
    #include <stdio.h>
    
    int main() {
        MYSQL *conn;
        MYSQL_STMT *stmt;
        MYSQL_BIND bind[3];
        unsigned int id = 1;
        char name[50] = "张三";
        double score = 100.0;
    
        // 初始化连接
        conn = mysql_init(NULL);
        if (!mysql_real_connect(conn, "localhost", "root", "password", "test_db", 0, NULL, 0)) {
            printf("连接失败: %s\n", mysql_error(conn));
            return 1;
        }
    
        // 准备 SQL 语句
        const char *query = "INSERT INTO user (id, name, score) VALUES (?, ?, ?)";
        stmt = mysql_stmt_init(conn);
        if (!mysql_stmt_prepare(stmt, query, strlen(query))) {
            printf("准备语句成功\n");
        } else {
            printf("准备语句失败: %s\n", mysql_stmt_error(stmt));
            return 1;
        }
    
        // 初始化绑定
        memset(bind, 0, sizeof(bind));
    
        // 绑定 id
        bind[0].buffer_type = MYSQL_TYPE_LONG;
        bind[0].buffer = &id;
        bind[0].is_null = 0;
    
        // 绑定 name
        bind[1].buffer_type = MYSQL_TYPE_STRING;
        bind[1].buffer = name;
        bind[1].buffer_length = sizeof(name);
        bind[1].is_null = 0;
    
        // 绑定 score
        bind[2].buffer_type = MYSQL_TYPE_DOUBLE;
        bind[2].buffer = &score;
        bind[2].is_null = 0;
    
        // 绑定参数
        if (mysql_stmt_bind_param(stmt, bind)) {
            printf("绑定参数失败: %s\n", mysql_stmt_error(stmt));
            return 1;
        }
    
        // 执行语句
        if (mysql_stmt_execute(stmt)) {
            printf("执行失败: %s\n", mysql_stmt_error(stmt));
            return 1;
        }
    
        // 关闭语句和连接
        mysql_stmt_close(stmt);
        mysql_close(conn);
    
        printf("插入成功!\n");
        return 0;
    }
    

    ✅ 总结与重点说明

    重点一:不要直接拼接变量名到 SQL 语句中!

    你写成:

    exeSql("insert into user values ('id','name',score);");
    

    这会变成:

    INSERT INTO user VALUES ('id', 'name', score);
    

    这是错误的,因为 idnamescore 是字符串字面量,而不是变量。

    重点二:使用参数化查询(Prepared Statements)

    这是安全且正确的做法,可以防止 SQL 注入,也能正确传递变量值。

    重点三:确保数据类型匹配

    在绑定参数时,要确保每个变量的数据类型与数据库表中对应的字段类型一致,例如:

    • id 是整数 → 使用 MYSQL_TYPE_LONG
    • name 是字符串 → 使用 MYSQL_TYPE_STRING
    • score 是浮点数 → 使用 MYSQL_TYPE_DOUBLE

    ✅ 常见错误排查建议

    | 问题 | 解决方法 | |------|----------| | SQL 语句中出现变量名(如 id, name) | 不要直接拼接变量名,使用参数化查询 | | 插入后显示 NULL 或变量名 | 检查是否正确绑定了变量,是否类型不匹配 | | 无法连接数据库 | 检查用户名、密码、数据库名、端口等信息 |


    如果你还有其他问题,比如如何获取查询结果、如何处理多条记录等,也可以继续提问,我会详细解答!😊

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
    1人已打赏
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 12月13日
  • 已采纳回答 12月5日
  • 创建了问题 12月4日