2013-06-04 4 views
2

Надеясь, что кто-то может помочь мне с использованием PQprepare и PQexecPrepared. Я уверен, что у меня должно быть что-то неправильно, но я ничего не пытаюсь работать.PQprepare и PQexecPrepared Usage

Я пытаюсь вставить в таблицу, используя подготовленный запрос, но я получаю эту ошибку

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   | 

Спасибо,

Марк

+0

Использование 'libpqtypes' спасет вас от хлопот. Вы уверены, что 701 является правильной версией для 'float8' на вашей БД (должно быть, похоже, что это было 701 в течение длительного времени, но все равно проверьте)? Вы не должны жестко кодировать жиры; команда прилагает усилия, чтобы сохранить их стабильными, но вы действительно должны искать их из 'pg_type' во время запуска программы. –

+0

Пожалуйста, покажите вывод '\ d data_plus' в' psql'. –

+0

Может оказаться полезным, если вы сделаете это самодостаточным скомпилированным примером. –

ответ

2

Попробуйте пропусканием нулевое значение для oidTypes и позволить серверу выводить типы данных.

Руководство говорит:

Если paramTypes является NULL, или какой-либо конкретный элемент массива равен нуль, сервер присваивает тип данных символа параметра таким же образом он будет делать для нетипизированной буквальным строка.

... и не должно возникать никаких проблем при выборе любого из этих типов, если таблица определена соответствующим образом.

Вы также можете передать NULL для paramFormats, так как по умолчанию предполагается, что все параметры являются не бинарными.

paramLengths не полезен или требуется при использовании параметров текстового формата. Оставьте это как null. На самом деле это может быть причиной проблемы.

+0

Спасибо за предложение, попробовав установить их все в 'NULL', все равно приводит к той же ошибке. –

+0

@MarkDavidson Odd. Самостоятельный скомпилируемый пример + sql для определения таблиц? Трудно продолжать дальше, не учитывая, что результат для меня не имеет большого смысла. Если я просто пропущу что-то очевидное. –

0

Вполне вероятно, что причина ошибки совсем не указана в показанном коде, который сам по себе выглядит нормально.

data_plus не является таблицей, это вид в соответствии с выходом первой строки \d data_plus. Так что, вероятно, есть RULE или триггер INSTEAD OF, который выполняет фактическую установку. Плюс есть столбец id, который не заполняется вашим кодом, так что это делается и в другом месте.

Возможно, вам захочется сфокусироваться на этом коде и проверить, нет ли путаницы между столбцами и значениями, переданными в них.

0

Это довольно старая нить, но я все равно отвечу, поскольку другие могут смотреть на нее. Все здесь, кажется, прекрасные условия его от libpq вызовов, но проблема заключается в следующем коде:

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

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

lexical_cast возвращает временную зЬй :: строку и вы сохраняете указатель на строку, которая будет/будет деградировавших , Необходимо сохранить эти строки где-нибудь или memcpy-данные в paramValues ​​(а затем удалить).Что-то вроде этого:

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