繁体   English   中英

将整数作为二进制发送时,PostgreSQL libpq“整数超出范围”错误

[英]PostgreSQL libpq “Integer out of range” error when sending integer as binary

我正在尝试使用以下一些简单的代码将一些整数插入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字节整数。 我究竟做错了什么?

代替:

params[0] = (char*)&i;

您应该使用:

#include <endian.h>
/* ... */
int64_t const i_big_endian = htobe64(i);
params[0] = (char*)&i_big_endian;

htobe64函数将在little-endian上切换字节顺序,而在big-endian上不执行任何操作。

flip_endian您的flip_endian函数,因为它会使您的程序与PowerPC,Alpha,Motorola,SPARC,IA64等大端/双端计算机不兼容。即使您的程序不希望在它们上运行,也很糟糕样式,缓慢且容易出错。

好吧,这似乎是一个endian问题,仍然没有完全解释,因为little-endian(即x86)64位有符号整数应该适合big-endian 64位整数,反之亦然,他们只是被破坏。 但是,将字节序交换为整数会产生正确的值。 交换通过以下功能完成:

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;

}

我认为它将被传递为32位int,然后转换为64位,因为您没有告诉libpq格式是什么。

尝试为paramTypes指定一个数组,并为参数int8设置oid(即20)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM