C语言 如何正确分配内存的查询字符串



我需要在C程序中执行sql查询。我用libpq来连接Postgresql。

char *formatted_query = "SELECT * FROM table LIMIT %d OFFSET %d";
char *query;
PGconn *conn;
PGresult *res;
int limit;
int offset;
/* here is connect to base get some data from user (like limit, offset etc.) */
sprintf(query, formatted_query, limit, offset);
res = PQexec(conn, query);

问题是我不知道如何为query分配足够的内存当然我也可以这样做:

char query[999]; 

但我认为这种方式是错误的。如果我这样做了:

char *query = (char *)malloc(sizeof(char) * sizeof(formatted_query));

可能会发生内存分配不足的情况(例如,limit或offset将是MAX_INT)。如何为查询字符串正确分配内存?

您应该真正使用PQexecParams。对于整数,不幸的是,您仍然必须将它们格式化为文本,但是您可以使用一个简单的静态缓冲区。

PGconn *conn;
PGresult *res;
#define MAX_INT4_DIGITS 11
const char *query = "SELECT * FROM table LIMIT $1 OFFSET $2";
Oid paramtypes[] = {INT4OID, INT4OID};
char *paramvalues[2];
char limitstr[MAX_INT4_DIGITS];
char offsetstr[MAX_INT4_DIGITS];
snprintf(offsetstr, MAX_INT4_DIGITS, "%d", limit);
snprintf(limitstr, MAX_INT4_DIGITS, "%d", offset); 
paramvalues[0] = limitstr;
paramvalues[1] = offsetstr;
res = PQexecParams(conn, query, 2, paramtypes, paramvalues, NULL, NULL, 0);

当你只有几个整数参数时,使用参数化查询并不是什么大问题,但是当你使用用户提供的字符串时,它就变得至关重要了。否则你就会陷入对SQL注入的引号和转义的可怕混乱中。

libpq二进制协议接口实际上要方便得多,但不幸的是它不能跨不同的体系结构工作(端序,字长等)。

如果需要一个更方便的接口,可以自动化一些libpq的低级操作,请查看libpqtypes。

你可以计算出有多少个符号同时使用两个数字,但最简单的方法是:

// max 32 bit unsigned integer number is 4294967295 (10 symbols)
int maxPossibleStringLength = strlen(formatted_query) + 2*10 + 1; // don't forget 0 symbol at end
char *query = (char *)malloc(sizeof(char) * maxPossibleStringLength);

相关内容

  • 没有找到相关文章

最新更新