PQprepare和PQexecPrepared用法

时间:2013-06-04 11:13:04

标签: c++ postgresql libpq

希望有人可以帮助我使用PQprepare和PQexecPrepared。我确定我一定有什么不对劲,但我尝试的任何东西似乎都没有用。

我正在尝试使用准备好的查询插入表中,但我一直收到此错误

ERROR: invalid input syntax for integer: "50.2000008"

这是我将Oid设置为701(float8)的纬度值,但它表示整数。我完全错过了什么或者有错误的方法吗?

bool database::AddDataRow(int datasetid, string readingdatetime, float depth, float value, float latitude, float longitude) {
    //data_plus

    const char* stmtName = "PREPARE_DATA_PLUS_INSERT";
    Oid oidTypes[6] = {23, 1114, 701, 701, 701, 701};
    int paramFormats[6] = {0, 0, 0, 0, 0, 0};
    PGresult* stmt = PQprepare(
            conn,
            stmtName,
            "INSERT INTO data_plus(datasetid, readingdatetime, depth, value, uploaddatetime, longitude, latitude)"
            "VALUES ($1, $2, $3, $4, NOW(), $5, $6);",
            6,
            (const Oid *) oidTypes
            );

    cout << PQresultErrorMessage(stmt) << " Test";

    const char* paramValues[6];
    int paramLengths[6];

    paramValues[0] = lexical_cast<string>(datasetid).c_str();
    paramValues[1] = readingdatetime.c_str();
    paramValues[2] = lexical_cast<string>(depth).c_str();
    paramValues[3] = lexical_cast<string>(value).c_str();
    paramValues[4] = lexical_cast<string>(longitude).c_str();
    paramValues[5] = lexical_cast<string>(latitude).c_str();

    paramLengths[0] = strlen (paramValues[0]);
    paramLengths[1] = strlen (paramValues[1]);
    paramLengths[2] = strlen (paramValues[2]);
    paramLengths[3] = strlen (paramValues[3]);
    paramLengths[4] = strlen (paramValues[4]);
    paramLengths[5] = strlen (paramValues[5]);

    PGresult* test = PQexecPrepared(conn,
            stmtName,
            6,
            paramValues,
            paramLengths, 
            paramFormats,
            0);

    cout << PQresultErrorMessage(test);

    PQclear(test);
    PQclear(stmt);
}

\ d data_plus

                  View "public.data_plus"
     Column      |            Type             | Modifiers 
-----------------+-----------------------------+-----------
 id              | bigint                      | 
 datasetid       | integer                     | 
 readingdatetime | timestamp without time zone | 
 depth           | double precision            | 
 value           | double precision            | 
 uploaddatetime  | timestamp without time zone | 
 longitude       | double precision            | 
 latitude        | double precision            | 

谢谢,

标记

3 个答案:

答案 0 :(得分:2)

尝试传递oidTypes的空值,让服务器推断数据类型。

手册说:

  

如果paramTypesNULL,或者数组中的任何特定元素为零,则服务器会以与对无类型文字字符串相同的方式为参数符号分配数据类型。 / p>

...只要表格被适当定义,就不应该有任何推断这些类型的问题。

您也可以为NULL传递paramFormats,因为默认情况下假设所有参数都是非二进制文本。

当您使用文本格式参数时,

paramLengths没有用或不需要。保留为null。这实际上可能是问题的原因。

答案 1 :(得分:0)

在显示的代码中可能没有出现错误的原因,这本身看起来还不错。

data_plus不是表,它是根据\d data_plus输出的第一行的视图。 因此,实际插入可能会有RULEINSTEAD OF触发器。 另外,您的代码中没有填充id列,所以它也在其他地方完成。

您可能希望专注于该代码,并检查传输到它们的列和值之间是否存在任何混淆。

答案 2 :(得分:0)

这是一个相当古老的线索,但我仍然会回答,因为其他人可能正在研究它。这里的所有内容似乎都很好用于libpq调用,但问题在于以下代码:

const char* paramValues[6];
int paramLengths[6];

paramValues[0] = lexical_cast<string>(datasetid).c_str();

lexical_cast返回一个临时的std :: string,你正在保存一个指向string的指针,该指针将被解析。 需要将这些字符串保存在某处或将memcpy数据保存到paramValues(以后删除它)。像这样:

std::array<std::string, 6> temp_params;
temp_params[0] = lexical_cast<string>(datasetid);
paramValues[0] = temp_params[0].c_str();