PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

So bereiten Sie Anweisungen vor und binden Parameter in Postgresql für C++

Ein einfaches Beispiel. Dies gibt nur die Anzahl der Einträge mit dem ID-Wert 0 aus.

#include<pqxx/pqxx>
#include<iostream>

int main()
{
    std::string name = "name";
    int id = 0;
    try {
        //established connection to data base
        pqxx::connection c("dbname=mydb user=keutoi");
        pqxx::work w(c);
        //statement template
        c.prepare("example", "SELECT id  FROM mytable WHERE id = $1");
        //invocation as in varible binding
        pqxx::result r = w.prepared("example")(id).exec();
        
        w.commit();
        //result handling for accessing arrays and conversions look at docs
        std::cout << r.size() << std::endl;
    }
    catch(const std::exception &e)
    {
        std::cerr << e.what() << std::endl;
        return 1;
    }
    return 0;
}

Die Funktion w.prepared() ist etwas kompliziert. Es ähnelt einer Curry(Curry)-Funktion in Haskell, da es einen Parameter übernimmt und eine andere Funktion zurückgibt, die wiederum einen anderen Parameter übernimmt. So etwas.

Dokumentation sagt:

Wie übergeben Sie diese Parameter? C++ hat keine gute Möglichkeit, Ihnen eine unbegrenzte, variable Anzahl von Argumenten an einen Funktionsaufruf zu übergeben, und der Compiler weiß nicht, wie viele Sie übergeben werden. Dafür gibt es einen Trick:Sie können den Wert, den Sie von der Vorbereitung zurückerhalten, als Funktion behandeln, die Sie aufrufen, um einen Parameter zu übergeben. Was Sie von diesem Aufruf zurückerhalten, ist wieder dasselbe, sodass Sie ihn erneut aufrufen können, um einen anderen Parameter zu übergeben und so weiter.

Sobald Sie alle Parameter auf diese Weise übergeben haben, rufen Sie die Anweisung mit den Parametern auf, indem Sie beim Aufruf exec aufrufen

Wenn es mehr Parameter gibt, verwenden Sie $1 $2 und so weiter in prepare Funktion.

c.prepare("SELECT id name FROM mytable WHERE id = $1 AND name = $2")

und geben Sie die Variablen als

an
w.prepared("example")(dollar1_var)(dollar2_var).exec()

Ein Beispiel für dynamische Vorbereitung

#include<pqxx/pqxx>
#include<iostream>
#include<vector>

//Just give a vector of data you can change the template<int> to any data type
pqxx::prepare::invocation& prep_dynamic(std::vector<int> data, pqxx::prepare::invocation& inv)
{
    for(auto data_val : data)
        inv(data_val);
    return inv;
}

int main()
{
    std::string name = "name";

    //a data array to be used.
    std::vector<int> ids;
    ids.push_back(0);
    ids.push_back(1);

    try {
        pqxx::connection c("dbname=mydb user=keutoi");
        pqxx::work w(c);

        c.prepare("example", "SELECT id  FROM mytable WHERE id = $1 or id = $2");
        pqxx::prepare::invocation w_invocation = w.prepared("example");

        //dynamic array preparation
        prep_dynamic(ids, w_invocation);
        //executing prepared invocation.
        pqxx::result r = w_invocation.exec();

        w.commit();

        std::cout << r.size() << std::endl;
    }
    catch(const std::exception &e)
    {
        std::cerr << e.what() << std::endl;
        return 1;
    }
    return 0;
}

wenn Sie andere Datentypen verarbeiten möchten, verwenden Sie diese Funktionsdefinition

template<class T> pqxx::prepare::invocation& prep_dynamic(std::vector<T> data, pqxx::prepare::invocation& inv)
{
    for(auto data_val : data)
        inv(data_val);
    return inv;
}