2015-04-22 26 views
2

我想将整数数组发布到我的postgresql数据库中。我知道我可以将所有格式都格式化为一个字符串,然后将该字符串作为一个SQL命令发送。但是,我相信PQexecParams函数也应该带来一些帮助。但是,我很遗憾,因为如何使用它。在C中使用postgresql插入整数数组(libpq)

//we need to convert the number into network byte order 
    int val1 = 131; 
    int val2 = 2342; 
    int val3[5] = { 0, 7, 15, 31, 63 }; 
    //set the values to use 
    const char *values[3] = { (char *) &val1, (char *) &val2, (char *) val3 }; 
    //calculate the lengths of each of the values 
    int lengths[3] = { sizeof(val1), sizeof(val2), sizeof(val3) * 5 }; 
    //state which parameters are binary 
    int binary[3] = { 1, 1, 1 }; 

    PGresult *res = PQexecParams(conn, "INSERT INTO family VALUES($1::int4, $2::int4, $3::INTEGER[])", 3, //number of parameters 
      NULL, //ignore the Oid field 
      values, //values to substitute $1 and $2 
      lengths, //the lengths, in bytes, of each of the parameter values 
      binary, //whether the values are binary or not 
      0); //we want the result in text format 

是的,这是从一些教程复制。 然而,这将返回:

ERROR: invalid array flags 

使用传统的方法做工作:

PQexec(conn, "INSERT INTO family VALUES (2432, 31, '{0,1,2,3,4,5}')"); 

插入数据就好了,我可以读出来罚款以及。

任何帮助将不胜感激! :)

回答

5

libpqPQexecParams可以接受文本或二进制形式的值。

对于文本值,您必须将sprintf整数放入您放入char**值数组中的缓冲区中。这通常是如何完成的。您可以使用带有查询参数的文本格式,没有特别的理由可以退回到自己将参数内插到SQL字符串中。

如果要使用二进制模式传输,则必须确保整数是目标字段的正确大小,是网络字节顺序,并且您已指定OID类型。为此,使用htonl(对于uint32_t)或htons(对于uint16_t)。由于您只是重新排序字节,因此可以放弃签名。

所以:

  • 不能忽略OID字段,如果你打算使用二进制传输
  • 使用htonl,不要酿造自己的字节顺序转换
  • values数组构造是错误的。您将char** s放入char*的数组中,并丢弃错误的类型。你想&val1[0]或(相当于大多数/所有真实世界的C实现,但在技术上并不占规格相同)刚刚val1,而不是(char*)&val1
  • 你不能假设的integer[]的上线格式同C的int32_t[]。你必须传递类型OID INT4ARRAYOID(见include/catalog/pg_type.hselect oid from pg_type where typname = '_int4' - 的阵列的内部类型名称是_在其底部型的前部)和必须构造与typreceive功能兼容一个PostgreSQL数组值在pg_type该类型(这是array_recv),如果你打算以二进制模式发送。特别是,二进制格式数组的头部标题为。你不能忽略标题。

换句话说,代码是以多种令人兴奋的方式破坏的,不可能按照书面的方式工作。

真的,在二进制模式下发送整数几乎没有任何好处。发送文本模式通常实际上更快,因为它通常更紧凑(小值)。如果您打算使用二进制模式,您需要了解C代表整数,网络与主机字节顺序的工作方式等。

尤其是在使用数组时,文本格式更容易。

libpq通过为文本和二进制数组提供良好的数组构造/解构函数,可以使它比现在要容易得多。修补程序一如既往地受到欢迎。现在,3rd party libraries like libpqtypes在很大程度上填补了这个角色。

+0

postgresql文档(http://www.postgresql.org/docs/9.4/static/libpq-exec.html#LIBPQ-EXEC-MAIN)表示即使对于二进制数据,也可以通过后缀参数符号来避免OID类型(例如'$ 1 :: bigint')。这是错的吗? –

+0

@undur_gongor它是正确的文本格式。不知道二进制。 –