sql >> データベース >  >> RDS >> PostgreSQL

Postgresql forC++でステートメントとバインドパラメータを準備する方法

    簡単な例。これは、ID値が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;
    }
    

    関数w.prepared()は少し複雑です。これは、haskellのcurried(curry)関数に似ています。これは、パラメーターを受け取り、別のパラメーターを受け取る別の関数を返すためです。そういうことです。

    ドキュメントによると:

    これらのパラメータをどのように渡しますか? C ++には、無制限の可変数の引数を関数呼び出しに渡すための適切な方法がなく、コンパイラーは、渡す引数の数を認識していません。そのための秘訣があります。preparedから取得した値を、パラメーターを渡すために呼び出す関数として扱うことができます。その呼び出しから返されるものは再び同じなので、別のパラメーターを渡すためにもう一度呼び出すことができます。

    この方法ですべてのパラメーターを渡したら、呼び出し時にexecを呼び出して、パラメーターを使用してステートメントを呼び出します。

    さらにパラメータがある場合は、prepareで$1$2などを使用します。 機能。

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

    変数を次のように指定します

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

    動的準備の例

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

    他のデータ型を処理する場合は、この関数定義を使用してください

    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. SELECTタイプのクエリは、ネストできる唯一のタイプですか?

    2. Mysql select recursiveは、複数のレベルを持つすべての子を取得します

    3. 2MySQLの日付から月の名前を返す関数

    4. デフォルト以外のNLS_NUMERIC_CHARACTERSを使用してOraclePL/ SQLでテキストを数値に効率的に変換するにはどうすればよいですか?