GCC C и передача целого числа в PostgreSQL - PullRequest
0 голосов
/ 21 сентября 2018

Я знаю, что, вероятно, было много на этом, но после нескольких дней поиска я не могу найти, как сделать одну простую передачу integer и char за один переход в PostgreSQL из C под Linux.

В PHP это просто, как 123, а в C, использующем libpq, это кажется чем-то необычным.

Я посмотрел на PQexecParams, но, похоже, это не помогает.Примеры в сети также не помогают, и это кажется невыполнимой миссией.

Может быть, кто-то будет достаточно любезен, чтобы перевести этот простой оператор PHP на C и показать мне, как передать несколько переменных разных типов в одномINSERT запрос.

col1 is INT
col2 is CHAR
$int1 = 1;
$char1 = 'text';
$query = "INSERT INTO table (col1, col2) values ('$int1',$char1)";
$result = ibase_query($query);

Это покажет, что я пытаюсь сделать (учтите, что код очень неправильный):

void insert_CommsDb(PGconn *conn, PGresult *pgres, int csrv0) {                                                                                                                                                                                                             const char * params[1];
params[0] = csrv0;

pgres = PQexecParams(conn, "INSERT INTO comms_db (srv0::int) values ($1)",
1,
NULL,
params,
1,
NULL,
0);

if (PQresultStatus(pgres) != PGRES_COMMAND_OK)
{
    fprintf(stderr, "INSERT failed: %s", PQerrorMessage(conn));
    exit_nicely(conn,pgres);
}
    PQclear(pgres);                                                                                                                                                                                           
}

Ответы [ 2 ]

0 голосов
/ 24 сентября 2018

Ответ wildplasser показывает путь в целом.

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

Если вы неЕсли вы хотите преобразовать целые числа в строки, альтернативой может быть использование внешнего двоичного формата соответствующего типа данных.Это требует внутренних знаний и, вероятно, чтения исходного кода PostgreSQL.Для некоторых типов данных это также может зависеть от аппаратного обеспечения.

PGresult *res;
PGconn *conn;
Oid types[2];
char * values[2];
int lengths[2], formats[2];
int arg0;

/* connect to the database */

/*  
 * The first argument is in binary format.
 * Apart from having to use the "external binary
 * format" for the data, we have to specify
 * type and length.
 */
arg0 = htonl(42);  /* external binary format: network byte order */
types[0] = 23;     /* OID of "int4" */
values[0] = (char *) &arg0;
lengths[0] = sizeof(int);
formats[0] = 1;

/* second argument is in text format */
types[1] = 0;
values[1] = "something";
lengths[1] = 0;
formats[1] = 0;

res = PQexecParams(
        conn,
        "INSERT INTO mytab (col1, col2) values ($1, $2)",
        2,
        types,
        (const char * const *)values,
        lengths,
        formats,
        0  /* results in text format */
      );

Я бы рекомендовал использовать текстовый формат для большинства типов данных.

Примечательным исключением является byteaгде обычно является преимуществом использование двоичного формата, так как он экономит место и мощность процессора.В этом случае внешний двоичный формат - это просто байты.

0 голосов
/ 22 сентября 2018

https://www.postgresql.org/docs/current/static/libpq-exec.html

Как прокомментировал @joop выше: Если аргумент paramTypes равен NULL, все параметры предполагаются как строки.Итак, вы должны преобразовать аргумент int в строку.


void insert_CommsDb(PGconn *conn, int csrv0) 
{
PGresult *pgres;
char * params[1];
char buff[12];

sprintf(buff, "%d", csrv0);

params[0] = buff;

pgres = PQexecParams(conn
        , "INSERT INTO comms_db (srv0::int) values ($1)"  // The query (we dont need the cast here)
        , 1     // number of params
        , NULL  // array with types, or NULL
        , params // array with parameter values
        , NULL  // ARRAY with parameter lenghts
        , NULL  // array with per-param flags indicating binary/non binary
        , 0     // set to 1 if we want BINARY results, 0 for txt
        );

if (PQrresultStatus(pgres) != PGRES_COMMAND_OK)
{
    fprintf(stderr, "INSERT failed: %s", PQerrorMessage(conn));
    exit_nicely(conn,pgres);
}

PQclear(pgres);                                                                                                                                                                                           
}
...