M
MadBear541May 15, 2017, 9:33 p.m.

Проверка наличия записи в БД при выполнении запроса

Qt, SQL

Есть программа в которой происходит добавление данных в базу SQL. Необходимо реализовать функцию проверки наличия записи при нажатии кнопки "Сохранить", если запись есть должен выполняться запрос Update, в ином случае выполняется запрос Insert. Как это реализовать?

We recommend hosting TIMEWEB
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.

Do you like it? Share on social networks!

27
Evgenii Legotckoi
  • May 16, 2017, 12:35 a.m.

Можно через QSqlQuery и логический оператор EXISTS сделать.

QSqlQuery query;
// Проверка наличия записей по дате
QString str = QString("SELECT EXISTS (SELECT * FROM TableExample WHERE Date = '%1');").arg("2017-08-03");
query.prepare(str);
query.exec();
query.next();

/* Если запись существует, то вызывается
 * информационное сообщение
 * */
if(query.value(0) != 0){
    QMessageBox::information(this, trUtf8("Error"), trUtf8("Record is exists"));
}
else
{
    // ToDo something
}

Также есть статья с проверкой наличия записей в базе данных

    M
    • May 16, 2017, 6:02 a.m.

    Вопрос: есть способ обновить модель QSqlQeuryModel?

      Evgenii Legotckoi
      • May 16, 2017, 10:09 a.m.

      Выполнить заново setQuery() с последней применённой QSqlQuery, с помощью метода query()

      model->setQuery(model->query());
        M
        • May 16, 2017, 9:14 p.m.

        если использовать model->setQuery(model->query().lastQuery()); ? я так понял что в данном случае он вызывает последний запрос

          Evgenii Legotckoi
          • May 17, 2017, 12:04 a.m.

          QSqlQuery всегда содержит только последний запрос, а lastQuery() возвращает этот запрос в виде строки QString, так что, если база данных используется одна, то разницы нет, в каком виде будет передаваться запрос в model->setQuery()

            M
            • May 17, 2017, 5:29 a.m.

            столкнулся с проблемой. приходиться на кнопку дважды нажимать чтоб выполнялся запуск кода приведенного вами. вызов произвожу через connect к данному слоту

              Evgenii Legotckoi
              • May 17, 2017, 5:56 a.m.

              Проблема в том, как вы применили код, который я вам привёл, а не в самом коде.

                M
                • May 17, 2017, 5:59 a.m.

                проблема как я выяснил в том что connect соединение с слотом с первого нажатия не производит. а подключается к слоту только со второго нажатия и запускает нормально слот. connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(tww())); вот так соединяю нажатие и слот

                  Evgenii Legotckoi
                  • May 17, 2017, 6:04 a.m.

                  Вы запихали connect не в то место в коде. Написали некачественный алгоритм, по которому коннект создаётся не в нужное время.

                    M
                    • May 18, 2017, 7:55 a.m.

                    Еще вопрос, с которым не могу разобраться. Есть ComboBox - raspsel, который позволяет выбрать поле из таблицы. Делаю я это следующим образом:

                     rasmd = new QSqlQueryModel(this);
                        QSqlQuery zrs;
                        zrs.exec("SELECT idr, CONCAT(rnumber, ' от ', rdata) FROM op");
                        rasmd->setQuery(zrs);
                        ui->raspsel->setModel(rasmd);
                        ui->raspsel->setModelColumn(1);
                    Теперь вопрос. Как сделать чтобы открыв форму для редактирования я видел выбранное значение и при этом мог поменять значение. через QDataWidgetMapper не получается правильно сделать. Не допонимаю как работает ComboBox
                      Evgenii Legotckoi
                      • May 18, 2017, 7:59 a.m.

                      Начнём с того, что QSqlQueryModel является моделью только для чтения, она не может быть редактируемой. А также, ответьте на вопрос. Зачем Вы выполняете метод exec() у QSqlQuery? Когда потом помещаете этот QSqlQuery в модель QSqlQueryModel? Обращение к базе данных происходит дважды.

                        M
                        • May 18, 2017, 8:04 a.m.

                        я так делаю потому что потом планирую сделать библиотеку sql запросов, потом исправлю, сейчас занимаюсь отладкой. Редактируемая же форма QSqlTableModel и QSqlRelationalTableModel. QSqlQueryModel я использую для извлечения данных из одной таблицы.

                          Evgenii Legotckoi
                          • May 18, 2017, 8:13 a.m.

                          Ну тогда у QComboBox есть методы currentData(), currentText(), currentIndex() с помощью которых можно забрать текущее значение. Передать его в сторону формы редактирования и с помощью этого значения выбрать нужную строку из таблицы базы данных, чтобы отобразить её в форме для редактирования.

                            M
                            • May 21, 2017, 9:11 a.m.

                            Опишу еще раз ситуацию. Есть таблица в которую посредством SQL запроса ложу данные, так как там необходимо в один столбец выводить несколько значений. Теперь встала проблема что при двойном клике по строке и вызове окна для редактирования программа ложится по сигналу полученному от операционки. я реализовал метод с использованием currentIndex()

                            edob = new editobject(ui->obv->selectionModel()->currentIndex().row());
                            edob экземляр формы для редактирования editobject, а obv таблица. при отладке выяснил что как только отрабатывает строка rmap->setCurrentModelIndex(rmod->index(row,0)); в форме редактирования, прилетает сигнал от операционной системы rmap = new QDataWidgetMappe как решить проблему. от QComboBox я на данном этапе отказался. у меня сама форма не отрабатывает
                              Evgenii Legotckoi
                              • May 21, 2017, 12:30 p.m.

                              В смысле программа крашится и выдаёт Segmentation Fault?
                              Ну тогда обращаетесь видимо к объекту, который в данный момент не был инициализирован. Получается, что используете rmap раньше, чем этот объект был создан. Нужно перетряхнуть последовательность действий.

                                M
                                • May 22, 2017, 3:31 a.m.

                                rmap инициализируется после его создания. не знаю что сделал, код не правил, но все заработало. только вот есть косяк о котором ранее не задумался. так как таблица в которой происходит вызов окна редактирования формируется по sql запросу, то индексы актуальны только для одного набора данных, для остальных заполнение происходит не верно. в связи с чем возникает вопрос если для использования QSqlQuery или QSqlQueryModel. Но в первую очередь у меня проблема с тем что сохранение изменений не происходит. Делаю как и всегда mapper->submit() и model->submitAll(). в других случаях все нормально

                                  Evgenii Legotckoi
                                  • May 23, 2017, 1:53 a.m.

                                  Так вы используете model->submitAll() и при этом используете QSqlQueryModel в качестве этой model?

                                  Делаю как и всегда mapper->submit() и model->submitAll(). в других случаях все нормально

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

                                    M
                                    • May 23, 2017, 1:55 a.m.

                                    нет. model = new QSqlTableModel

                                      M
                                      • May 23, 2017, 1:57 a.m.

                                      QSqlQueryModel я использую для формирования визуальной таблицы из которой по двойному клику вызываю форму редактирования. в ней же использую стандартный подход QSqlTableModel и QDataWidgetMapper

                                        Evgenii Legotckoi
                                        • May 23, 2017, 2:36 a.m.

                                        Тогда после применения настроек в форме редактирования, применяйте обновление данных в вашей QSqlQueryModel.

                                          M
                                          • May 23, 2017, 2:38 a.m.

                                          я так и делаю. после редактирования у меня посылается сигнал по которому происходит обращение к слоту обновления. сначала думал не правильно реализовал. но посмотрев через консоль базы, выяснил что данные не обновились

                                            M
                                            • May 23, 2017, 3:47 a.m.

                                            Никак не могу найти способ чтобы обойти проблему с индексами в форме приведенной на скриншоте. в этой форме отображается информация, о которой говорил ранее, ее я и редактирую. заполнение данной формы происходит при помощи QSqlQueryModel и по ряду показателей. проблема в том что если я меняю значение показателя (критерия отбора) то при выводе в таблицу индексы строк обновляются, т.е. они всегда идут с значения "1", что не соответствует индексу строки в sql таблице. Как результат форма редактирования заполняется не верно. Возможно из-за этого и не отрабатывает обновление данных

                                              Evgenii Legotckoi
                                              • May 23, 2017, 4:38 a.m.

                                              Потому, что это не ID, а номера строк самой таблицы. Почитайте вот это сообщение , да и в принципе весь топик.

                                                M
                                                • May 23, 2017, 5:11 a.m.

                                                вообще-то я делаю передачу индекса

                                                edob = new editobject(rrid, rayid, ui->obv->selectionModel()->currentIndex().row());
                                                где obv та самая таблица из которой я дергую информацию. а editobject форма для редактирования. в editobject индекс я использую в
                                                rmap->setCurrentModelIndex(rmod->index(row,0));
                                                rmap = new QDataWidgetMapper.

                                                  Evgenii Legotckoi
                                                  • May 23, 2017, 5:27 a.m.

                                                  И дальше что? То, что вы привели мне две эти строчки ещё не говорит о том, что этот код работает правильно.

                                                  И вообще-то QModelIndex != ID в базе данных, index.row() != ID в базе данных

                                                  Он у Вас работает правильно? Вы получаете обновление данных в базе данных? - НЕТ . Иначе это обсуждение не длилось бы так долго.

                                                  А теперь, я увижу достаточно подробный код или нет? 

                                                    M
                                                    • May 23, 2017, 5:47 a.m.

                                                    Код форм про которые говорил прикрепил. regrdit форма в которой отображается информация отбираемая из базы. editobject форма для редактирования

                                                      Evgenii Legotckoi
                                                      • May 28, 2017, 10:01 a.m.

                                                      Как интересно. У вас используется выборка по условиям везде. Ничего удивительного, что когда создаёте editobject , то получаете не верные данные. Забирая номер строки из одной таблицы, пытаетесь с помощью него получить другие данные в другой таблице. В которой используются совершенно другие условия выборки. Как я и говорил, почитайте топик, что я Вам привёл выше. И забирайте данные не по номеру строки в модели, а по ID записи в базе данных.

                                                      P/S/ Код у Вас отвратительный. Если кто-то после вас будет работать с проектом, то ему проще будет написать программу заново.

                                                        Comments

                                                        Only authorized users can post comments.
                                                        Please, Log in or Sign up
                                                        e
                                                        • ehot
                                                        • March 31, 2024, 2:29 p.m.

                                                        C++ - Тест 003. Условия и циклы

                                                        • Result:78points,
                                                        • Rating points2
                                                        B

                                                        C++ - Test 002. Constants

                                                        • Result:16points,
                                                        • Rating points-10
                                                        B

                                                        C++ - Test 001. The first program and data types

                                                        • Result:46points,
                                                        • Rating points-6
                                                        Last comments
                                                        k
                                                        kmssrFeb. 8, 2024, 6:43 p.m.
                                                        Qt Linux - Lesson 001. Autorun Qt application under Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
                                                        Qt WinAPI - Lesson 007. Working with ICMP Ping in Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
                                                        EVA
                                                        EVADec. 25, 2023, 10:30 a.m.
                                                        Boost - static linking in CMake project under Windows Ошибка LNK1104 часто возникает, когда компоновщик не может найти или открыть файл библиотеки. В вашем случае, это файл libboost_locale-vc142-mt-gd-x64-1_74.lib из библиотеки Boost для C+…
                                                        J
                                                        JonnyJoDec. 25, 2023, 8:38 a.m.
                                                        Boost - static linking in CMake project under Windows Сделал всё по-как у вас, но выдаёт ошибку [build] LINK : fatal error LNK1104: не удается открыть файл "libboost_locale-vc142-mt-gd-x64-1_74.lib" Хоть убей, не могу понять в чём дел…
                                                        G
                                                        GvozdikDec. 18, 2023, 9:01 p.m.
                                                        Qt/C++ - Lesson 056. Connecting the Boost library in Qt for MinGW and MSVC compilers Для решения твой проблемы добавь в файл .pro строчку "LIBS += -lws2_32" она решит проблему , лично мне помогло.
                                                        Now discuss on the forum
                                                        a
                                                        a_vlasovApril 14, 2024, 6:41 a.m.
                                                        Мобильное приложение на C++Qt и бэкенд к нему на Django Rest Framework Евгений, добрый день! Такой вопрос. Верно ли следующее утверждение: Любое Android-приложение, написанное на Java/Kotlin чисто теоретически (пусть и с большими трудностями) можно написать и на C+…
                                                        Павел Дорофеев
                                                        Павел ДорофеевApril 14, 2024, 2:35 a.m.
                                                        QTableWidget с 2 заголовками Вот тут есть кастомный QTableView с многорядностью проект поддерживается, обращайтесь
                                                        f
                                                        fastrexApril 4, 2024, 4:47 a.m.
                                                        Вернуть старое поведение QComboBox, не менять индекс при resetModel Добрый день! У нас много проектов в которых используется QComboBox, в версии 5.5.1, когда модель испускает сигнал resetModel, currentIndex не менялся. В версии 5.15 при resetModel происходит try…
                                                        AC
                                                        Alexandru CodreanuJan. 19, 2024, 11:57 a.m.
                                                        QML Обнулить значения SpinBox Доброго времени суток, не могу разобраться с обнулением значение SpinBox находящего в делегате. import QtQuickimport QtQuick.ControlsWindow { width: 640 height: 480 visible: tr…

                                                        Follow us in social networks