使用libpq更新PostgreSQL表时遇ERROR: insufficient data left in message错误
使用libpq更新PostgreSQL表时出现"insufficient data left in message"错误
问题详情
执行PostgreSQL表更新操作时触发如下错误:
ERROR: insufficient data left in message
用相同参数编写示例代码后仍出现相同错误,PQerrorMessage(res)返回上述错误,状态码为PGRES_FATAL_ERROR。目前插入和查询语句可正常执行。
示例代码
std::string sQuery("update client_backlog_period set starttime = $1, endtime = $2, unavailable = $3 where periodid = $4"); int nElem = 4; timestamp start_time = 736260060000000, end_time = 736260900000000; short nUnavailable = 0; long nPeriodid = 1; start_time = boost::endian::native_to_big(start_time); end_time = boost::endian::native_to_big(end_time); nUnavailable = boost::endian::native_to_big(nUnavailable); nPeriodid = boost::endian::native_to_big(nPeriodid); const char* paramValues[4] = { (char*)&start_time, (char*)&end_time, (char*)&nUnavailable, (char*)&nPeriodid}; Oid paramTypes[4] = { TIMESTAMPOID, TIMESTAMPOID, INT2OID , INT8OID }; int paramLengths[4] = { sizeof(start_time), sizeof(end_time),sizeof(nUnavailable), sizeof(nPeriodid) }; int paramFormats[4] = { 1,1,1,1 }; PGresult* res = PQexecParams(db.m_pPGConn, sQuery.c_str(), nElem, paramTypes, paramValues, paramLengths, paramFormats, 1 ); ExecStatusType status = PQresultStatus(res); if (status != PGRES_COMMAND_OK) { std::cerr << "\nUpdate Query failed, Error: " << PQerrorMessage(res) << ",status: " << status << std::endl; PQclear(res); }
表结构
表client_backlog_period字段信息:
periodid: bigint(主键)clientid: integerstarttime: timestamp without time zoneendtime: timestamp without time zoneunavailable: smallint
问题原因及修复方案
该错误核心原因是参数类型/长度与PostgreSQL期望不匹配,导致数据库解析消息时数据不足。结合代码和表结构,问题集中在以下两点:
1. periodid的类型长度不匹配
表中periodid是bigint类型,对应libpq的INT8OID需要8字节数据,但代码中使用的long类型在Windows等平台下仅为4字节,sizeof(nPeriodid)返回4,远小于PostgreSQL要求的8字节,直接导致消息数据不足。
2. (可选)自定义timestamp类型的长度验证
PostgreSQL的timestamp without time zone二进制格式为8字节大端int64,需确保你的自定义timestamp类型是8字节的整数类型(如int64_t),否则也会出现长度不匹配问题。
修复步骤
- 将
nPeriodid的类型改为int64_t或long long,确保是8字节:int64_t nPeriodid = 1; - 确认自定义
timestamp类型为8字节,若不是则调整定义:using timestamp = int64_t; - 打印验证参数长度,确保符合要求:
std::cout << "start_time size: " << sizeof(start_time) << std::endl; // 应输出8 std::cout << "nPeriodid size: " << sizeof(nPeriodid) << std::endl; // 应输出8
内容的提问来源于stack exchange,提问作者Rakesh Mehta
相关产品推荐
相关产品推荐

