QtSql запрос динамического выбора с несколькими фильтрами WHERE - PullRequest
0 голосов
/ 18 ноября 2018
  • Мне нужно выполнить любой запрос на выборку, используя тот же метод.
  • Итак, запрос my должен отфильтровать выбранные данные, используя одно значение или больше.
  • Фильтры хранятся на карте с именем столбца в качестве ключа и значение фильтрации как значение .
  • Итак, мой вопрос: как динамически добавлять фильтры в оператор Select?
  • Что я пробовал:

    1. QSqlQueryModel Класс: Я мог бы создать QSqlQueryModel объект и установить запрос в получить данные всей таблицы, но я Не удалось найти какие-либо функции в этом классе для фильтрации этих данных:

       QSqlQueryModel *model = new QSqlQueryModel;
       model->setQuery("SELECT * FROM employee");
    

    2. QSqlTableModel: Этот класс используется для просмотра данных таблицы в qtableView , я могу использовать этот класс для чтения данных таблицы, а затем отфильтровать эти данные следующим образом (я еще не пробовал):

     QSqlTableModel *model = new QSqlTableModel
     model->setTable("employee");
     model->setEditStrategy(QSqlTableModel::OnManualSubmit);
     model->select();
     model->setFilter("colum5 > 10");
     // I can use after that data() method to retrieve filtered data. 
    

    3. Для Loop Я думал об использовании цикла for для непосредственного добавления фильтров, но я бы предпочел лучший способ, потому что я считаю, что QT предлагает такую ​​услугу.


Метод должен выглядеть следующим образом:

/**
 * @brief getData executes sql select query.
 * @param query [out] QSqlQuery query object after executing the query.
 * @param queryFilters [in] map of query filters (column-name, filter- 
   value).
 * @param table [in] table name.
 * @return 
 */
bool getData(QSqlQuery &query, std::map<std::string,QVariant> &queryFilters, 
std::string &table){
        bool status = false;
        std::string queryText = "SELECT * from " + table + " WHERE  ";
        // I should apply filters from queryFilters map here.
        return status;
} 

1 Ответ

0 голосов
/ 18 ноября 2018

Есть несколько способов сделать это.

Использование цикла for с std::map.

Используйте цикл for для итерации значений пары ключей.

bool getData(QSqlQuery &query, const std::map<std::string,QVariant> &queryFilters,
             std::string &table)
{
    // ...

    std::string queryText = "SELECT * from " + table + " WHERE";

    for (auto it = queryFilters.begin(); it != queryFilters.end(); )
    {
        queryText += " " + it->first + "='" + it->second.toString().toStdString() + "'";

        it++;
        // check the iterator isn't the last iterator
        if (it != queryFilters.end())
            queryText += " AND";    // separate your "filters" using an AND
    }

    // ...      
}

Использование цикла for с QMap.

Но, черт возьми, это Qt, так почему бы не воспользоваться преимуществами типов QMap, QStringList и QString QTL.

bool getData(QSqlQuery &query, const QMap<QString, QVariant> &queryFilters,
             const QString &table)
{
    //  ...

    QString queryText = "SELECT * from " + table + " WHERE ";
    QStringList filters;
    foreach (const QString &filterKey, queryFilters.keys())
        filters << filterKey + "='" + queryFilters.value(filterKey).toString() + "'";

    queryText += filters.join(" AND ");

    //  ...

}

Обратите внимание, что foreach является определенным Qt макросом. См. ключевое слово foreach .

Информацию о других типах QTL, о которых вы можете знать, см. Containers .


QSqlQueryModel ???

Я не могу сказать по вашему вопросу и комментариям, действительно ли у вас есть модель / представление / виджет таблицы SQL в фоновом режиме или вы используете что-то еще целиком.

Я думал об использовании цикла для этого вопроса. Но я подумал, что есть лучший способ использовать некоторые классы qt, такие как: QSqlQueryModel

Конечно, просто просматривая документацию, QSqlQueryModel не имеет функции фильтра.

Но ... QSqlTableModel имеет эту функцию. Плюс в том, что если у вас уже есть QSqlQueryModel где-то, вы можете повысить его до QSqlTableModel, так как последний наследует первый. Но опять же, у меня недостаточно информации, чтобы выносить суждения, поэтому я просто веду вас сюда в темноте.

Надеюсь, этот ответ проливает некоторый свет на ваше затруднительное положение вместе с напоминанием о том, как вы могли бы задать лучший вопрос, чтобы получить более точные ответы.

...