QtSql Dynamic Select query с несколькими фильтрами WHERE

  • Мне нужно выполнить любой запрос выбора, используя тот же метод.
  • Итак, запрос 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. Для цикла Я думал об использовании цикла 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;
} 

Почему бы не использовать [QMap] (doc.qt.io/qt-5/qmap.html)?

TrebledJ 18.11.2018 01:11

Речь идет не об использовании карты или другого класса stl. Я спрашиваю о том, как динамически добавлять фильтры в оператор запроса.

Samir N Ahmad 18.11.2018 01:13

Вы столкнетесь с большим количеством преобразований между типами STL / QTL. Так что можно начать использовать QString и QMap / QHash. Вы пробовали использовать цикл в этом отношении? :-)

TrebledJ 18.11.2018 01:15

Яп, я упустил этот момент. Благодарность!

Samir N Ahmad 18.11.2018 01:17

Обычно при количестве переменных Переменная можно использовать циклы. Кроме того, просто наблюдая за вашей строкой, "SELECT * from" + table + "WHERE " будьте осторожны, помещайте пробелы до / после table, если вы не можете гарантировать наличие пробелов. «SELECT * frommyTableWHERE ...» не будет выполняться.

TrebledJ 18.11.2018 01:19

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

Samir N Ahmad 18.11.2018 01:20

Спасибо за совет, я думаю, что буду использовать цикл for непосредственно внутри запроса в качестве последнего решения !! :).

Samir N Ahmad 18.11.2018 01:26

Привет еще раз. Если вы думали, что QSqlQueryModel мог бы быть лучшим решением, включите это в свой вопрос, поскольку он рассказывает нам о вашем мыслительном процессе: что сработало, а что не сработало.

TrebledJ 18.11.2018 06:55
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
8
992
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

Использование цикла 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, так почему бы не воспользоваться типами QTL QMap, QStringList и QString.

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, о которых вы, возможно, захотите знать, см. контейнеры.


QSqlQueryModel ???

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

I thought about using loop for this matter.But, I thought that there is a better way using some qt classes like : QSqlQueryModel

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

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

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

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

Samir N Ahmad 18.11.2018 11:17

Я думаю, что использование цикла foreach - лучшее решение на данный момент. Я пометил этот ответ как принятый. Ховервере, я буду обновлять свой вопрос всякий раз, когда найду другой подход.

Samir N Ahmad 18.11.2018 12:12

Рад, что вы нашли это несколько полезным. Циклы for должны быть самыми простыми. :-) Вы, кажется, обеспокоены тем, что петли for не справятся с этим. ? Много фильтров?

TrebledJ 18.11.2018 12:22

Я думаю, что фильтров не так уж и много!. Пока я буду использовать цикл foreach, а также классы QTL вместо STL :).

Samir N Ahmad 18.11.2018 13:00

Другие вопросы по теме