我正在尝试使用以下稍微简单的代码将一些整数插入到Postgres表中。
#include <libpq-fe.h>
#include <stdio.h>
#include <stdint.h>
int main() {
int64_t i = 0;
PGconn * connection = PQconnectdb( "dbname='babyfood'" );
if( !connection || PQstatus( connection ) != CONNECTION_OK )
return 1;
printf( "Number: " );
scanf( "%d", &i );
char * params[1];
int param_lengths[1];
int param_formats[1];
param_lengths[0] = sizeof( i );
param_formats[0] = 1;
params[0] = (char*)&i;
PGresult * res = PQexecParams( connection,
"INSERT INTO intlist VALUES ( $1::int8 )",
1,
NULL,
params,
param_lengths,
param_formats,
0 );
printf( "%s\n", PQresultErrorMessage( res ) );
PQclear( res );
PQfinish( connection );
return 0;
}
我得到以下结果:
Number: 55 ERROR: integer out of range
Number: 1 ERROR: integer out of range
我很确定int64_t总是适合任何理智平台上的8字节整数。我做错了什么?
答案 0 :(得分:3)
而不是:
params[0] = (char*)&i;
你应该使用:
#include <endian.h>
/* ... */
int64_t const i_big_endian = htobe64(i);
params[0] = (char*)&i_big_endian;
htobe64
函数会在little-endian上切换endianness,并且不会对big-endian执行任何操作。
抛弃你的flip_endian
功能,因为它会使你的程序与大端/双端计算机不兼容,如PowerPC,Alpha,摩托罗拉,SPARC,IA64等。即使你的程序不希望是在他们身上运行这是一种糟糕的风格,缓慢且容易出错。
答案 1 :(得分:1)
好吧,它似乎是一个endian问题,仍然没有解释它,因为一个小端(即x86)64位有符号整数应该适合大端64位整数,反之亦然,它们只是被腐败了。但是,在整数上交换endian会产生正确的值。交换使用以下函数完成:
int64_t flip_endian( int64_t endi ) {
char* bytearray;
char swap;
int64_t orig = endi;
int i;
bytearray = (char*)&orig;
for( i = 0; i < sizeof( orig )/2; ++i ) {
swap = bytearray[i];
bytearray[i] = bytearray[ sizeof( orig ) - i - 1 ];
bytearray[ sizeof( orig ) - i - 1 ] = swap;
}
return orig;
}
答案 2 :(得分:-1)
我认为它会以32位int的形式传递,然后被转换为64位,因为你没有告诉libpq格式是什么。
尝试为paramTypes指定一个数组,其中oid为参数的int8(即20)。