如何在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
相关产品推荐
相关产品推荐

