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

如何在C中创建高效函数处理多参数格式化字符数组构建SQL查询

在C语言中从结构体生成SQL查询字符串的实用方法

你需要从C结构体里提取字段值构建SQL查询,就像Python的字符串格式化那样,而且因为要处理大量不同SQL,希望有工具函数来搞定。下面给你几种实用的实现方式:

1. 基础专用函数(适合少量结构体)

直接用标准库的snprintf拼接字符串,针对每个结构体写对应的生成函数,直观好理解:

#include <stdio.h>
#include <string.h>

typedef struct {
  char title[50];
  char text[5000];
} post_t;

// 专门生成post_t的INSERT语句
void build_post_insert_sql(const post_t* post, char* buf, size_t buf_size) {
    // 注意:直接拼接存在SQL注入风险,后面会提供安全版本
    snprintf(buf, buf_size, "INSERT INTO main.post VALUES('%s', '%s');", post->title, post->text);
}

int main() {
    post_t post = {
        "title",
        "Some random text here..."
    };
    // 预留足够缓冲区空间,覆盖字段长度+SQL模板长度
    char sql_buf[50 + 5000 + 100];
    build_post_insert_sql(&post, sql_buf, sizeof(sql_buf));
    puts(sql_buf);
    return 0;
}

运行后输出和你的Python示例一致:

INSERT INTO main.post VALUES('title', 'Some random text here...');

2. 宏生成函数(适合大量结构体)

如果要处理很多不同的结构体和SQL模板,用宏自动生成函数框架,减少重复代码:

// 定义通用宏,自动生成结构体对应的SQL插入函数
#define GENERATE_INSERT_FUNC(struct_name, sql_template, ...) \
void build_##struct_name##_insert_sql(const struct_name* obj, char* buf, size_t buf_size) { \
    snprintf(buf, buf_size, sql_template, __VA_ARGS__); \
}

// 针对post_t生成插入函数,直接传入模板和字段
GENERATE_INSERT_FUNC(post_t, "INSERT INTO main.post VALUES('%s', '%s');", obj->title, obj->text)

// 后续新增结构体示例:
// typedef struct { char name[20]; int age; } user_t;
// GENERATE_INSERT_FUNC(user_t, "INSERT INTO main.user VALUES('%s', %d);", obj->name, obj->age)

3. 安全版本(必须处理SQL注入)

基础方法存在隐患:如果字段包含单引号(比如title是O'Neil),生成的SQL会语法错误,还可能引发注入风险。因此必须添加字符串转义逻辑:

// 把字符串中的单引号转成两个单引号(SQL标准转义方式)
void escape_sql_string(const char* src, char* dest, size_t dest_size) {
    size_t i = 0, j = 0;
    while (src[i] != '\0' && j < dest_size - 1) {
        if (src[i] == '\'') {
            dest[j++] = '\'';
            if (j >= dest_size - 1) break;
        }
        dest[j++] = src[i++];
    }
    dest[j] = '\0';
}

// 安全版的post_t SQL生成函数
void build_post_insert_sql_safe(const post_t* post, char* buf, size_t buf_size) {
    // 为转义后的字符串预留足够空间(最多为原长度的2倍+1)
    char escaped_title[100];
    char escaped_text[10000];
    
    escape_sql_string(post->title, escaped_title, sizeof(escaped_title));
    escape_sql_string(post->text, escaped_text, sizeof(escaped_text));
    
    snprintf(buf, buf_size, "INSERT INTO main.post VALUES('%s', '%s');", escaped_title, escaped_text);
}

比如当title是O'Neil时,转义后会变成O''Neil,生成的SQL就不会出现语法错误了。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 05:10:29