sql >> Database teknologi >  >> RDS >> PostgreSQL

Sådan forberedes sætninger og bindeparametre i Postgresql til C++

Et simpelt eksempel. Dette udskriver blot antallet af poster med id-værdi 0.

#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;
}

Funktionen w.prepared() er en smule indviklet. Det ligner en curried(curry)-funktion i Haskell, da den tager en parameter og returnerer en anden funktion, som igen tager en anden parameter. Den slags.

Dokumentationen siger:

Hvordan videregiver du disse parametre? C++ har ingen god måde at lade dig videregive et ubegrænset, variabelt antal argumenter til et funktionskald, og compileren ved ikke, hvor mange du vil videregive. Der er et trick for det:du kan behandle den værdi, du får tilbage fra forberedt, som en funktion, som du kalder for at videregive en parameter. Det, du får tilbage fra det opkald, er det samme igen, så du kan kalde det igen for at videregive en anden parameter og så videre.

Når du har videregivet alle parametre på denne måde, kalder du sætningen med parametrene ved at kalde exec på invokationen

Hvis der er flere parametre, brug $1 $2 og så videre i prepare funktion.

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

og giv variablerne som

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

Et eksempel på dynamisk forberedelse

#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;
}

hvis du ønsker at håndtere andre datatyper, brug denne 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;
}


  1. Sådan migreres Standalone Moodle til en skalerbar opsætning i grupperet database

  2. SQL Server-udførelsesplan — hvad er det, og hvordan hjælper det med ydeevneproblemer?

  3. Kommaseparerede værdier med SQL Query

  4. psycopg2.OperationalError:FATAL:ikke-understøttet frontend-protokol 1234.5679:server understøtter 2.0 til 3.0