代码之家  ›  专栏  ›  技术社区  ›  SamGhatak

在SqLAPIC++中添加多个参数到IN子句

  •  0
  • SamGhatak  · 技术社区  · 6 年前

    我使用SQLAPI从C++代码连接到SQL Server数据库。我需要使用IN子句执行一个简单的select语句,其中子句中的字符串值作为字符串向量接收。我们希望使用参数化查询,所以做了如下操作:

    std::string getSQLQeury(std::vector<std::string> ids){
        std::stringstream sql;
        sql << "SELECT ID, Name, DOB FROM Employees WHERE ID IN (";
        unsigned int counter = 0;
        for each (auto id in ids)
        {
            sql << ":" << counter + 1;
            if (++counter < ids.size())
            {
                sql << ",";
            }
        }
        sql << ")";
        return sql.str();
    }
    

    然后,

        int param_counter = 0;
        for each (auto id in ids) {
            command.Param(++param_counter).setAsString() = id.c_str();
        }
    

    0 回复  |  直到 6 年前
        1
  •  1
  •   cycollins    6 年前

    好吧,我不想削弱你的基本问题,我认为这是“做这件事的好方法”,但是你的C++有一些基本的语法问题。从上面的错误代码可以推断出您的意图,我认为目标是创建一个命令合成器,使用来自任意输入id集的公共SQL select查询。酷。我认为首先创建一个带有插入点的合成模板命令,然后使用它们的参数替换方案是没有任何好处的。不妨一次完成所有的合成。编译时正确的版本看起来像这样(通过一些调整使其更易于重用)-

    std::string getSQLQuery(
        const std::string& columns
      , const std::string& table
      , const std::vector<std::string>& ids
    ){
      // Check for empty strings/arrays here - leads to illegal SQL,
      // so error out or except on empty ids, columns, or "table".
    
      std::stringstream sql("SELECT ", std::ios_base::out | std::ios_base::ate);
      sql << columns << " FROM " << table << " WHERE ID IN ( ";
    
      // Trailing commas are not allowed in SQL, which makes synthesis a little trickier.
      // We checked for empty inputs earlier, so we have at least one ID.
      auto iter = ids.begin();
      sql << *iter++;  // add the first (and possibly only) ID
      for (; iter != ids.end(); ++iter) {  // add the rest (if any) with commas
        sql << ", " << *iter;
      }
      sql << " )";   // <- should this be " );"? Or does SQLAPI++ deal with that?
      return sql.str();  // There's a shrink-to-fit method you may want to use here.
    }
    

    现在你可以做一些像-

    std::vector<std::string> id_array{ "1", "50", "aardvark" };
    SACommand basic_command(connection, getSQLQuery("ID, Name, DOB", "Employees", id_array));
    basic_command.Execute();
    

    std::vector<std::uint64_t> 或者任何适合您的特定应用的东西。事实上,通过生成签名,您可以使用相同的代码体处理这两种情况-

    template<typename T> std::string getSQLQuery(
        const std::string& columns
      , const std::string& table
      , const std::vector<T>& ids
    ){
       ... // rest of the implementation is the same
    }