繁体   English   中英

最佳SQL参数的STL容器

[英]Best stl container for sql parameters

我必须建立一个动态的SQL查询。 为了正确执行它,我必须分3个步骤进行操作:

  1. 准备陈述
  2. 将参数与函数绑定:bindString(string value,int index); bindInt(int值,int索引);
  3. 执行它

由于这个事实,该查询是动态构建的,因此我必须在某个地方存储给定索引的适当值。

例如:

  1. SELECT * FROM Table WHERE A =吗? AND E ='?';

  2. SELECT * FROM Table WHERE A =吗? 与B =? AND E ='?';

在构建查询期间,我必须将存储在以下位置:

在第一种情况下:

  • 索引0代表int A,
  • 索引1用于字符串E

在第二种情况下:

  • 索引0用于int A
  • 索引1用于int B
  • 索引2用于字符串E

我最好的主意是创建两个映射:<int,string>,<int,int>,并在创建查询集的第一位索引和第二位值的过程中,然后创建两个循环,一个循环用于字符串,第二个循环用于整数,在其中绑定参数,效果很好。

但是,我想知道是否有可能使用后续索引和类型安全方式在一个循环中完成所有操作。

谢谢。

我会考虑创建一个包装SQL参数的类。

实际上,我将创建一个抽象类,例如:

SQLParameterBase
{

   std::string toString() = 0;
   void print()
   {
     std::cout << toString();
   }
}

然后是一个模板类:

template<class ParamType>
SQLParameter : public SQLParameterBase
{
private:
    ParamType value;
public:
    std::string toString()
    {
       // You can use std::ostringstream to convert to string,
       // or create another class (derivated from SQLParameterBase) with very specific values
    }
}

您可以像这样使用它:

SQLParameterBase * params[10];
maps[0] = new SQLParameter<int>();

希望会有所帮助

实际上是修改后的AMDG解决方案。 多亏他!

class SQLParam {
public:
   virtual ~SqlParam(){}
   void bind(DatabaseHandler &db, int index) = 0;
};

class SQLParamInt {
private:
   int value;
public:
   SqlParamInt(int p_value) : value(p_value) {
   }
   ~SqlParamInt() {}
   int bind(DatabaseHandler &db, int index) {
       return db.bindInt(value, index);
   }
};

class SQLParamString {
private:
   string value;
public:
   SqlParamString(std::string p_value) : value(p_value) {
   }
   ~SqlParamString() {}
   int bind(DatabaseHandler &db, int index) {
       return db.bindString(value, index);
   }
};

typedef std::vector<std::unique_ptr<SqlParam>> SqlParamsContainer;
typedef std::unique_ptr<SqlParamInt> SqlParamIntPtr;
typedef std::unique_ptr<SqlParamString> SqlParamStringPtr;

在我的函数中,构建查询:

int buildQuery(RequestHandler &request) {
    SqlParamsContainer params;
    stringstream query << "SELECT * FROM Table WHERE A = ?";

    params.push_back(SqlParamIntPtr(new SqlParamInt(request.A())));
    if(request.has_B()) {
         params.push_back(SqlParamIntPtr(new SqlParamInt(request.B())));
         query << " AND B = ?";
    }
    if(request.has_C()) {
         params.push_back(SqlParamStringPtr(new SqlParamString(request.C())));
         query << " AND C = ?";
    }
    query << ";";
    db.prepare(query.str());

    for(int i = 0; i < v_container.size(); i++)
        v_container.at(i)->bind(db,i);
}

还有Boost :: Any,尽管它比您想要的更通用,并且不会阻止用户存储不受支持的类型,您无需担心创建相应的子类。

如果您也想从DB Boost ::返回结果,那么任何一个也可能是答案。

我建议限制绑定函数而不是存储中的类型。 如果您使用可变参数绑定函数,则无论如何都需要这样做。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM