PQprepare and PQexecPrepared Usage

PQprepare and PQexecPrepared Usage

本文关键字:Usage PQexecPrepared and PQprepare      更新时间:2023-10-16

希望有人能帮助我使用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);
}

                  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            | 

谢谢,马克

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

手册说:

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

…只要表的定义合适,推断这些类型应该没有任何问题。

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

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

paramLengths不是有用的或必需的。将其保留为空。

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

const char* paramValues[6];
int paramLengths[6];
paramValues[0] = lexical_cast<string>(datasetid).c_str();

lexical_cast返回一个临时std::string,你保存了一个指向string的指针,该指针将被销毁。需要将这些字符串保存在某个地方,或者将内存数据保存到paramValues(稍后删除它)。像这样:

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

很可能错误的原因根本不在所显示的代码中,该代码本身看起来没有问题。

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

您可能需要关注该代码,并检查列和传递到其中的值之间是否存在混淆