sql >> Databasteknik >  >> RDS >> PostgreSQL

Hur man förbereder satser och bindningsparametrar i Postgresql för C++

Ett enkelt exempel. Detta skriver bara ut antalet poster med id-värde 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() är lite invecklad. Det liknar en curry(curry)-funktion i Haskell, eftersom den tar en parameter och returnerar en annan funktion som i sin tur tar en annan parameter. Sånt.

Dokumentationen säger:

Hur skickar du dessa parametrar? C++ har inget bra sätt att låta dig skicka ett obegränsat, variabelt antal argument till ett funktionsanrop, och kompilatorn vet inte hur många du kommer att skicka. Det finns ett knep för det:du kan behandla värdet du får tillbaka från preparerat som en funktion, som du anropar för att skicka en parameter. Det du får tillbaka från det samtalet är detsamma igen, så du kan ringa det igen för att skicka en annan parameter och så vidare.

När du har skickat alla parametrar på detta sätt anropar du satsen med parametrarna genom att anropa exec på anropet

Om det finns fler parametrar använd $1 $2 och så vidare i prepare funktion.

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

och ge variablerna som

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

Ett exempel för dynamisk förberedelse

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

om du vill hantera andra datatyper använd denna 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. Kolumn _ID finns inte fel även om den finns i tabellen

  2. Oracle:Java lagrad procedur som skickar JMS-meddelande

  3. Hur man släpper en kolumn med en begränsning i SQL Server

  4. Uppdatera data i en MySQL-databas