我需要在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));
可能会发生分配的内存不足(例如,限制或偏移将是MAX_INT)。 如何为查询字符串正确分配内存?
答案 0 :(得分:1)
你应该真的使用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。
答案 1 :(得分:0)
你可以计算两个数字的符号数,但最简单的方法是:
// 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);