3

希望有人可以帮助我使用 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 数据加号

                  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            | 

谢谢,

标记

4

3 回答 3

2

尝试传递一个空值oidTypes并让服务器推断数据类型。

手册说:

如果paramTypesisNULL或数组中的任何特定元素为零,则服务器将数据类型分配给参数符号,其方式与对无类型文字字符串的处理方式相同。

...只要适当地定义了表格,推断这些类型中的任何一种都不应该有任何问题。

您也可以传递NULLparamFormats因为默认情况下假定所有参数都是文本而不是二进制。

paramLengths使用文本格式参数时没有用或不需要。将其保留为空。这实际上可能是问题的原因。

于 2013-06-04T11:58:22.530 回答
1

这是一个相当古老的线程,但我仍然会回答,因为其他人可能正在查看它。就 libpq 调用而言,这里的一切似乎都很好,但问题在于以下代码:

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

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

lexical_cast 返回一个临时的 std::string 并且您正在保存一个指向将被/被破坏的字符串的指针。需要将这些字符串保存在某处或将 memcpy 数据保存到 paramValues(然后将其删除)。像这样的东西:

std::array<std::string, 6> temp_params;
temp_params[0] = lexical_cast<string>(datasetid);
paramValues[0] = temp_params[0].c_str();
于 2017-02-03T09:44:53.533 回答
0

It is likely that the reason of the error is not at all in the code shown, which by itself looks OK.

data_plus is not a table, it's a view according to the first line output by \d data_plus. So there's probably a RULE or an INSTEAD OF trigger which does the actual insertion. Plus there is an id column that is not filled in by your code, so it's done somewhere else too.

You may want to focus on that code and check for any confusion between columns and values transfered into them.

于 2013-06-04T15:18:36.063 回答