Форум программистов, компьютерный форум, киберфорум
PostgreSQL
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/15: Рейтинг темы: голосов - 15, средняя оценка - 5.00
2 / 2 / 3
Регистрация: 04.12.2015
Сообщений: 114

Как передать переменную в PQexec, с++

20.11.2016, 19:43. Показов 3320. Ответов 6
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте, подскаите пожалуйста как передать переменную в запрос PQexec;

Например есть строка запроса, которая создает нового юзера в БД:
C++
1
2
3
4
5
6
7
string User = "UserNew";
string Pswd = "987";
 
//Создаем нового юзера TasteMe с паролем 123
PGresult *res = PQexec(conn, "CREATE USER TasteMe WITH PASSWORD '123';");
 
// Как создать строку запроса PQexec так, чтобы создался новый пользователь User и пароль Pswd
Как передать переменную не могу понять, пожалуйста поясните, как передать переменные именно в запрос, ну или к примеру как в цикле 10 юзеров создать, взяв данные из некоторого массива. или плохо искал, или же не смог найти.

Добавлено через 7 часов 0 минут
Ребят, неужели никто не работает на с++ с PG?
Нагуглил функцию
C++
1
PQexecParams
не могу понять как Strings в неё передавать или int, или другие переменные.
Дайте пожалуйста внятный комментарий, на фоне моего примера.
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
20.11.2016, 19:43
Ответы с готовыми решениями:

Как передать из ACCESS переменную STRING в переменную окружения (типа CMD команды SET=)
Добрый день! Подскажите как установить переменную окружения из ACCESS. Допустим у меня есть переменная CurrentDir типа String и я хочу...

Как строковую переменную передать из TStringStream в переменную String?
Доброе время суток! Подскажите, как строковую переменную передать из TStringStream в переменную String? Можно ли на прямую...

Как передать переменную окна через текстовую переменную?
Открыл одно окно, потом второе, и хочу передать индетефикатор первого окна во второе, чтобы оно там что-то с ним сделало. Как это сделать...

6
1263 / 977 / 384
Регистрация: 02.09.2012
Сообщений: 3,020
20.11.2016, 23:57
См. пример №3
0
2 / 2 / 3
Регистрация: 04.12.2015
Сообщений: 114
21.11.2016, 16:08  [ТС]
grgdvo, Пример я уже смотрел, разобраться в нем не смог.
В примере Params - Это массив Char.

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

Пожалуйста, если возможно, покажите хоть какой-то нормальный вариант реализации кода.

Кроме того, что такое $1 в примере, я тоже не понял, это ссылка на номер элемента в массиве Char, или что это такое?

Добавлено через 14 часов 7 минут
Пробовал такие варианты, оба неудачные, один неудается полностью, другой чатстично рабочий:

1 вариант не получается вообще:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
                        //Задаем параметры
            const char *paramValues[1];
            string User = "oleny@zoo.org";
            string Pswd = "1234";
 
                        //Вводим в массив
            paramValues[0] = User.c_str;
            paramValues[1] = Pswd.c_str;
 
                        //Параметры соединения
                        const char *conninfo;
                        //Само соединение
            PGconn     *conn;
 
 
            conninfo = "hostaddr = '192.168.0.130' port = '5432' dbname = 'zoo' user = 'postgres' password = 'mypass' connect_timeout = '2'";
 
                       //Соединяемся
            conn = PQconnectdb(conninfo);
 
            if (PQstatus(conn) != CONNECTION_OK)
            {
                fprintf(stderr, "Connection to database failed: %s",
                    PQerrorMessage(conn));
            }
 
                        else {
                printf("Good Done Conncted\n");
 
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Этот вариант даже не компилируется
 
                                               PQexecParams(conn,
                        "CREATE USER $1 WITH PASSWORD $2",
                        1,       /* one param */
                        NULL,    /* let the backend deduce param type */
                        paramValues,
                        NULL,    /* don't need param lengths since text */
                        NULL,    /* default to all text params */
                        1);      /* ask for binary results */
 
//Этот вариант даже не компилируется
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
                               }

2 Этот вариант работает частично:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
                        //Задаем параметры
            const char *paramValues[1];
            string User = "oleny@zoo.org";
            string Pswd = "1234";
 
                        //Вводим в массив
            paramValues[0] = User.c_str;
            paramValues[1] = Pswd.c_str;
 
                        //Параметры соединения
                        const char *conninfo;
                        //Само соединение
            PGconn     *conn;
 
 
            conninfo = "hostaddr = '192.168.0.130' port = '5432' dbname = 'zoo' user = 'postgres' password = 'mypass' connect_timeout = '2'";
 
                       //Соединяемся
            conn = PQconnectdb(conninfo);
 
            if (PQstatus(conn) != CONNECTION_OK)
            {
                fprintf(stderr, "Connection to database failed: %s",
                    PQerrorMessage(conn));
            }
 
                        else {
                printf("Good Done Conncted\n");
 
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Этот вариант отрабатывается частично
                string insert = "CREATE USER " + EmailToDB + " WITH PASSWORD " + PswdToDb +";";
                cout << insert << endl;
                PGresult *res = PQexec(conn, insert.c_str());
 
 
//Этот вариант отрабатывается частично, не создаются символы 12345789 и прочие @#$%^&...
//Стандартные буквы a-Z нормально принимаются и пользователь в БД создается, но если встречаются
//иные символы PG возвращает ошибку типа:
 
// Syntax error at or near @ к примеру, или иной символ
 
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Добавлено через 1 час 16 минут
Попробовал иначе задать параметр массива:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
                        //Задаем параметры
//            const char *paramValues[1];
            string User = "oleny@zoo.org";
            string Pswd = "1234";
 
 /*                       //Вводим в массив
            paramValues[0] = User.c_str;
            paramValues[1] = Pswd.c_str;
 */
       //Задаю переменные массива сразу в момент создания оного      
           const char *paramValues[2] = { (char *)&User, (char *)&Pswd };
 
                        //Параметры соединения
                        const char *conninfo;
                        //Само соединение
            PGconn     *conn;
 
 
            conninfo = "hostaddr = '192.168.0.130' port = '5432' dbname = 'zoo' user = 'postgres' password = 'mypass' connect_timeout = '2'";
 
                       //Соединяемся
            conn = PQconnectdb(conninfo);
 
            if (PQstatus(conn) != CONNECTION_OK)
            {
                fprintf(stderr, "Connection to database failed: %s",
                    PQerrorMessage(conn));
            }
 
                        else {
                printf("Good Done Conncted\n");
 
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Компилируется
 
                                               PQexecParams(conn,
                        "CREATE USER $1 WITH PASSWORD $2",
                        2,       /* one param */
                        NULL,    /* let the backend deduce param type */
                        paramValues,
                        NULL,    /* don't need param lengths since text */
                        NULL,    /* default to all text params */
                        1);      /* ask for binary results */
 
//компилируется  также сплевывает ошибку Syntax error at or near $1
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
                               }
0
1263 / 977 / 384
Регистрация: 02.09.2012
Сообщений: 3,020
21.11.2016, 16:12
Взял за основу третий пример. Времени на всякие дополнительные проверки типов данных не было, поэтому все лаконично.
Вроде не падает.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <sys/types.h>
#include "libpq-fe.h"
#include <netinet/in.h>
#include <arpa/inet.h>
 
void show_binary_results(PGresult *res) {
    int nTuples = PQntuples(res);
    fprintf(stdout, "Tuples count: %i\n", nTuples);
    int nFields = PQnfields(res);
    fprintf(stdout, "Fields count: %i\n", nFields);
 
    int binaryTuples = PQbinaryTuples(res);
    if (binaryTuples == 1)
        fprintf(stdout, "Binary data\n");
    else
        fprintf(stdout, "Text data\n");
 
    for (int tuple = 0; tuple < nTuples; tuple++) {
        fprintf(stdout, "Row#%i\n", tuple);
        for (int field = 0; field < nFields; field++) {
            char* fieldname = PQfname(res, field);
            char* value = PQgetvalue(res, tuple, field);
            int length = PQgetlength(res, tuple, field);
            fprintf(stdout, "\t%s=%s (%i)\n", fieldname, value, length);
        }
    }
}
 
int main(int argc, char **argv) {
    PGconn* conn = PQconnectdb(argv[1]);
    if (PQstatus(conn) != CONNECTION_OK) {
        fprintf(stderr, "Connection to database failed: %s", PQerrorMessage(conn));
        PQfinish(conn); exit(1);
    }
 
    const char* sql1 = "SELECT * FROM pg_settings WHERE setting = $1";
    const char* sql1param = "on";
 
    PGresult* res = PQexecParams(conn, sql1, 1, NULL, &sql1param, NULL, NULL, 1);
    ExecStatusType resStatus = PQresultStatus(res);
    if (resStatus != PGRES_TUPLES_OK) {
        fprintf(stderr, "SELECT failed: %s", PQerrorMessage(conn));
        PQclear(res); PQfinish(conn); exit(1);
    }
    
    char* resStatusStr = PQresStatus(resStatus);
    fprintf(stdout, "Query Result Status: %s\n", resStatusStr);
    show_binary_results(res);
    PQclear(res);
 
    PQfinish(conn);
    return 0;
}
1
2 / 2 / 3
Регистрация: 04.12.2015
Сообщений: 114
21.11.2016, 23:10  [ТС]
Спасибо за потраченное время, но...блин для меня сложновато для понимания правда.
И комментариев в коде нет совсем

Мой простой пример не можете посмотреть, почему я постоянно получаю ошибку типа

Syntax error at or near $1
Почему буквы нормально распознаются а знаки и символы нет

Добавлено через 6 часов 50 минут
На трех форумах создал тему со своей проблемой, ни одного внятного ответа.
Попробую упростить, кто может заставить работать этот код в чистом новом проекте, с нормально подключенными либами.
Почему у меня постоянно ошибка появляется Syntax error at or near в чем проблема, что я делаю не так?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
//
#include "targetver.h"
 
#include <stdio.h>
#include <tchar.h>
 
#include <iostream>
#include <string.h>
 
#include "libpq-fe.h"
#include "stdafx.h"
 
using namespace std;
 
int main()
{
 
    const char *conninfo;
    PGconn     *conn;
 
 
    std::string EmailToDB = "gfdgfdshj@mail.ru";
    std::string PswdToDb = "1234";
 
    char d = char(64); //Тестовый Char для передачи чистый ANCII
 
    const char *paramValues[2] = { (char *)&EmailToDB, (char *)&PswdToDb };
 
 
    conninfo = "hostaddr = '192.168.0.130' port = '5433' user = 'postgres' password = 'pass' connect_timeout = '2'";
 
    conn = PQconnectdb(conninfo);
    PQsetClientEncoding(conn, "UTF-8");
 
    if (PQstatus(conn) != CONNECTION_OK)
    {
        fprintf(stderr, "Connection to database failed: %s",
            PQerrorMessage(conn));
        //exit(0);
    }
 
    else {
        PQsetClientEncoding(conn, "UTF8");
        printf("Good Done \n");
 
 
//      string insert = "CREATE USER [email]gfdshjk@ya.ru[/email] WITH PASSWORD '123';"; // НЕ РАБОТАЕТ
//      std::string insert = "CREATE ROLE uuuuu@u LOGIN NOINHERIT"; // НЕ РАБОТАЕТ
        std::string insert = "CREATE ROLE "+ EmailToDB+" LOGIN NOINHERIT"; // НЕ РАБОТАЕТ
        //Везде одна и таже ошибка
 
        PGresult *res = PQexec(conn, insert.c_str());
    
 
        fprintf(stderr, "UserCreeate: %s",
            PQerrorMessage(conn));
 
        PQfinish(conn);
    }
 
    system("pause");
 
 
 
    return 0;
}
ЗЫ К пням наверное этот долбанный ПГ кому нужна "наиболее продвинутая из открытых СУБДД в мире" если на элементарный вопрос я уже 3день не могу получить ответ ни на одном из 3х очень уважаемых форумов.
Разве это нормально, я понимаю что никто никому ничего не должен...вопрос не в этом, никто даже в ветку не заходит, ересь не пишет, да в ней тем новых не появляется даже.
Как самостоятельно разобраться в этом всем не понимаю, элементарные запросы сделать не получается...или это особенность взаимодействия с++ в VS...в чем головняк то?
Кто-нибудь отпишитесь, неужели ни у кого подобных проблем не возникало как у меня?
Начиная с установки никак не могу слона выдрессировать. Времени уже нет с ним возиться, убью запущу мускуль.
Там уж точно полн информации и поддержки в доступных примерах пользователей.
0
1263 / 977 / 384
Регистрация: 02.09.2012
Сообщений: 3,020
21.11.2016, 23:59
Лучший ответ Сообщение было отмечено lostandleft как решение

Решение

К сожалению вы сразу стали использовать не самый удобный запрос
1. DDL выражения не параметризуются (см. аналог PREPARE)
2. При использовании специальных символов в именах объектов (таблиц, ролей....) необходимо их брать в кавычки

Поэтому и дает ошибку синтаксиса!!

В вашем случае правильно написать

C++
1
std::string insert="CREATE ROLE \"" + EmailToDB + "\" LOGIN NOINHERIT";

Вы просили еще комментарии по тексту примера вставить

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <sys/types.h>
#include "libpq-fe.h"
#include <netinet/in.h>
#include <arpa/inet.h>
 
void show_binary_results(PGresult *res) {
    /* узнали кол-во записей (строк) в результатах запроса */
    int nTuples = PQntuples(res);
    fprintf(stdout, "Tuples count: %i\n", nTuples);
    /* узнали кол-во полей (колонок) в результатах запроса */
    int nFields = PQnfields(res);
    fprintf(stdout, "Fields count: %i\n", nFields);
 
    /* узнали формат результата: бинарный или текстовый?? */
    int binaryTuples = PQbinaryTuples(res);
    if (binaryTuples == 1)
        fprintf(stdout, "Binary data\n");
    else
        fprintf(stdout, "Text data\n");
 
    /* в циклах по всем строкам и столбцам */
    for (int tuple = 0; tuple < nTuples; tuple++) {
        fprintf(stdout, "Row#%i\n", tuple);
        for (int field = 0; field < nFields; field++) {
            /* узнали имя поля (колонки) */
            char* fieldname = PQfname(res, field);
            /* узнали указатели на значение */
            char* value = PQgetvalue(res, tuple, field);
            /* Узнали длину в байтах, сколько занимает значение */
            int length = PQgetlength(res, tuple, field);
            /* вывели значение */
            fprintf(stdout, "\t%s=%s (%i)\n", fieldname, value, length);
        }
    }
    /* ВАЖНО!!! Данная функция не рассчитана на вывод
       параметров отличных от строк. Их нужно разбирать
       по типу. Например для integer будет распечатано
       intfield= (4) */
}
 
int main(int argc, char **argv) {
    /* Устанавливаем соединение с базой данных.
       На входе строка вида: "dbname=mydb user=myuser"
       подробности в описании функции в документации */
    PGconn* conn = PQconnectdb(argv[1]);
    if (PQstatus(conn) != CONNECTION_OK) {
        fprintf(stderr, "Connection to database failed: %s", PQerrorMessage(conn));
        PQfinish(conn); exit(1);
    }
 
    /* Готовим данные для выполнения запроса */
    const char* sql1 = "SELECT * FROM pg_settings WHERE setting = $1";
    const char* sql1param = "on";
 
    /* Запускаем запрос. Параметры по порядку:
       1. conn - указатель соединения
       2. sql1 - текст запроса (параметры запроса пронумерованы в текст запроса $1, $2 ....)
       3. 1 - передаем один параметр (в тексте всего один $)
       4. NULL - пусть сервер сам догадывается о типах данных подставляемых параметров
       5. указатель на память, где лежат указатели на значения параметров
           или массив, где лежат указатели на значения параметров
       6. массив размеров значений (по указателям из №5)
       7. массив форматов значений параметров
           либо текстовый, тогда просто строка символов, заканчивающаяся 0, длина не нужна
           либо бинарный, тогда длина учитывается
       7. ожидаем результаты в двоичном виде */
    PGresult* res = PQexecParams(conn, sql1, 1, NULL, &sql1param, NULL, NULL, 1);
    ExecStatusType resStatus = PQresultStatus(res);
    if (resStatus != PGRES_TUPLES_OK) {
        fprintf(stderr, "SELECT failed: %s", PQerrorMessage(conn));
        PQclear(res); PQfinish(conn); exit(1);
    }
 
    /* вывели строку статуса результата запроса */   
    char* resStatusStr = PQresStatus(resStatus);
    fprintf(stdout, "Query Result Status: %s\n", resStatusStr);
    /* выводим сами данные результата */
    show_binary_results(res);
    PQclear(res);
 
    /* Закрыли соединение */
    PQfinish(conn);
    return 0;
}
1
2 / 2 / 3
Регистрация: 04.12.2015
Сообщений: 114
22.11.2016, 01:44  [ТС]
Спасибо большое, я уже отчаялся.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
22.11.2016, 01:44
Помогаю со студенческими работами здесь

Как передать переменную
Доброго времени суток, столкнулся с такой проблемой, не могу предать переменную из одной формы в другую(из avtoriz в admin, переменная lst)

Как передать переменную?
Есть скрипт: &lt;!doctype html&gt; &lt;html lang=&quot;ru&quot;&gt; &lt;head&gt; &lt;title&gt;Прогноз погоды&lt;/title&gt; &lt;meta http-equiv=&quot;Content-Type&quot;...

Как передать переменную
Как передать переменную от 1 вормы к другой или чтоб по нажитию кнопки в Form2 значение переменной, скажем i менялось в Form1?

Как передать переменную в Report
Доброго дня всем! Программирую на Visual Basic 2010. Подскажите, пожалуйста, каким образом передать значение переменной объявленной в...

Как передать переменную в шорткод?
День добрый. Имеется такая конструкция (в wordpress) echo do_shortcode(''); Есть переменная $addr=&quot;Moscow, Birulevskaya,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru