C ++ preparedstatement

时间:2017-03-25 11:15:43

标签: c++ arguments prepared-statement

如何使用MySQL C ++ Connector从检索到的字符串及其变量中相应地将预准备语句设置为其数据类型?例如。该函数接收一个sql查询和值,那么这个函数是使它成为一个预处理语句并返回执行?

int Testing(initializer_list<any> args) {
    for(const auto &arg : args) {
            if(arg.type() == typeid(int)) { // Check for int
                    int value = any_cast<int>(arg);
                    cout << "Int value: " << value << endl;

                    //set into prepared statement according to its data type

            } else if(arg.type() == typeid(string)) {
                    string value = any_cast<string>(arg);
                    cout << "String value: " << value << endl;

                    //set into prepared statement according to its data type

            }
    }
    return 0;
}

int main() {
    Testing({std::string("Insert into table(field1, field2)VALUES(?,?)", 1 , string('thistring'))});
    return 0;
}

1 个答案:

答案 0 :(得分:0)

不幸的是,oracle mysqlcppconn接口是以古老的Java理念为蓝本的。

这意味着您将不得不应用自己的可变线管。

只要你很乐意在c ++类型和SQL类型之间选择一些标准映射,就不那么难了。

#include <string>
#include <memory>
#include <utility>

// simulate mysql class

struct PreparedStatement
{
    PreparedStatement(std::string const& sql) {};

    void setString(std::size_t column, const std::string& value) {};
    void setInt(std::size_t column, int value) {};

};

namespace detail {

    //
    // these overloads perform the correct action depending on the argument type
    //
    void parameterise(PreparedStatement& stmt, std::size_t column, std::string const& value) {
        stmt.setString(column, value);
    }

    void parameterise(PreparedStatement& stmt, std::size_t column, const char* value) {
        stmt.setString(column, value);
    }

    void parameterise(PreparedStatement& stmt, std::size_t column, int value) {
        stmt.setInt(column, value);
    }


    //
    // variadic parameteriser
    //
    template<class Tuple, std::size_t...Is>
    void parameterise(PreparedStatement& stmt, Tuple&& tuple, std::index_sequence<Is...>, std::size_t initial_index = 1)
    {
        using expand = int[];
        void(expand { 0,
                 (parameterise(stmt, Is + initial_index, std::get<Is>(std::forward<Tuple>(tuple))),0)...
        });
    };
}

template<class...Args>
auto build_parameterised_query(const std::string sql, Args&&...args)
{
    //
    // in mysqcppconn, this bit would be
    // auto stmt = std::unique_ptr<PreparedStatement>(connection->preparedStatement(sql));
    //
    auto stmt = std::make_unique<PreparedStatement>(sql);

    // but the rest would be the same

    detail::parameterise(*stmt,
                         std::forward_as_tuple(std::forward<Args>(args)...),
                         std::make_index_sequence<sizeof...(Args)>());
    return stmt;

}

int main()
{
    auto stmt = build_parameterised_query("SELECT * from foo where a = ? and b = ? and c = ?",
                                          std::string("bar"),
                                          "baz",
                                          6);
}