Russian Qt Forum

Qt => Вопросы новичков => Тема начата: olejOK17 от Март 04, 2015, 17:54



Название: query.next()
Отправлено: olejOK17 от Март 04, 2015, 17:54
Первый раз работаю, точнее пытаюсь работать с SQL в Qt. Подскажите почему query.next() может постоянно false возвращать. Соединение с сервером устанавливается, а вот query.next() снова и снова false. Не ругайтесь если что. Молодой, криворукий.
Код:
{
    ui->setupUi(this);

    QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL", QString("mydb"));
    db.setPort(3306);
    db.setHostName("***");
    db.setDatabaseName("***");
    db.setUserName("***");
    db.setPassword("***");
    db.setConnectOptions();

    QStandardItemModel *model = new QStandardItemModel;
    QStandardItem *item;

    //Заголовки столбцов
    QStringList horizontalHeader;
    horizontalHeader.append("1");
    horizontalHeader.append("2");

    //Заголовки строк
    QStringList verticalHeader;
    verticalHeader.append("1");
    verticalHeader.append("2");
    verticalHeader.append("3");
    verticalHeader.append("4");

    model->setHorizontalHeaderLabels(horizontalHeader);
    model->setVerticalHeaderLabels(verticalHeader);

    QSqlQuery query;
    query.exec("SELECT * FROM Theme");

    for(int i=0; i<3; i++) {
      for(int j=0; j<3; j++) {
        if (query.next()) {
          QString name = query.value(0).toString();
          item = new QStandardItem(name);
          model->setItem(i, j, item);
        }
      }
    }

    ui->tableView->setModel(model);

    ui->tableView->resizeRowsToContents();
    ui->tableView->resizeColumnsToContents();
}


Название: Re: query.next()
Отправлено: Hrundel от Март 04, 2015, 17:59
Сам пока ни разу не писал для SQL, но мне кажется немного не логично, что базы не существует, а ты пытаешься делать к ней запросы.
Лично мне все это кажется странным:

Код
C++ (Qt)
db.setHostName("***");
db.setDatabaseName("***");
db.setUserName("***");
db.setPassword("***");
 



Название: Re: query.next()
Отправлено: olejOK17 от Март 04, 2015, 18:01
Сам пока ни разу не писал для SQL, но мне кажется немного не логично, что базы не существует, а ты пытаешься делать к ней запросы.
Лично мне все это кажется странным:

Код
C++ (Qt)
db.setHostName("***");
db.setDatabaseName("***");
db.setUserName("***");
db.setPassword("***");
 



 Там все прописано, я же говорю - соединение устанавливается. db.open(); - true


Название: Re: query.next()
Отправлено: Hrundel от Март 04, 2015, 18:18
Ааааа, теперь понял, это ты звездочки только здесь указываешь, а в реальном коде нормальные имена хоста и базы прописаны.
Ок, тогда понятно. А есть возможность проверить, что возвращает

Код
C++ (Qt)
query.exec("SELECT * FROM Theme");

?

В доках написано, что  query должен быть в активном состоянии, и isSelect должен возвращать true перед вызовом.
Попробуй проверить на соответствие.


Название: Re: query.next()
Отправлено: Hrundel от Март 04, 2015, 18:25
И, кстати, попробуй для начала установить query.first() и получить его значение.


Название: Re: query.next()
Отправлено: olejOK17 от Март 04, 2015, 18:44
И, кстати, попробуй для начала установить query.first() и получить его значение.
QSqlQuery::exec: database not open
Вот такие дела... А db.open() возвращает true. Где косяк...


Название: Re: query.next()
Отправлено: Hrundel от Март 04, 2015, 19:01
В хосте скорее всего. С хостами всегда геморой.


Название: Re: query.next()
Отправлено: Old от Март 04, 2015, 19:54
И, кстати, попробуй для начала установить query.first() и получить его значение.
QSqlQuery::exec: database not open
Вот такие дела... А db.open() возвращает true. Где косяк...
Вы создали и открыли соединение с именем mydb, а в query используете дефолтное.
Либо уберите из addDatabase имя соединения, или в query указывайте правильное соединение.


Название: Re: query.next()
Отправлено: Hrundel от Март 04, 2015, 20:19
Вы создали и открыли соединение с именем mydb, а в query используете дефолтное.
Либо уберите из addDatabase имя соединения, или в query указывайте правильное соединение.

Ну вот, слова про хост беру обратно.  ;)


Название: Re: query.next()
Отправлено: kai666_73 от Март 05, 2015, 12:14
Как сказал Old
Код:
QSqlQuery query(db);
спасет отца русской демократии...
Ну и
Код:
db.open()
никто не отменял (в коде из первого поста не нашел)


Название: Re: query.next()
Отправлено: olejOK17 от Март 05, 2015, 13:34
Как сказал Old
Код:
QSqlQuery query(db);
спасет отца русской демократии...
Ну и
Код:
db.open()
никто не отменял (в коде из первого поста не нашел)
Не спасло. Таже проблема


Название: Re: query.next()
Отправлено: kai666_73 от Март 05, 2015, 17:33
Как сказал Old
Код:
QSqlQuery query(db);
спасет отца русской демократии...
Ну и
Код:
db.open()
никто не отменял (в коде из первого поста не нашел)
Не спасло. Таже проблема
То есть query.exec(...) возвращает false, а в сообщении об ошибке Db not opened?
Выложите ка минимальный компилируемый проект... а то гадать можно долго )


Название: Re: query.next()
Отправлено: torwig от Март 05, 2015, 17:41
Может нет данных в таблице?


Название: Re: query.next()
Отправлено: kai666_73 от Март 05, 2015, 17:47
Может нет данных в таблице?
Не... query.exec(...) не true однако, то есть до выборки еще не добрались


Название: Re: query.next()
Отправлено: Bepec от Март 05, 2015, 19:13
Глупый будет гадать, умный скажет - лови sqlerror и выводи :D


Название: Re: query.next()
Отправлено: olejOK17 от Март 09, 2015, 14:34
Может нет данных в таблице?
Не... query.exec(...) не true однако, то есть до выборки еще не добрались
.open() забыл. Теперь проблема в том что if (query.next()) только первый раз true. Только первая ячейка в таблице заполняется, а до остальных не доходит дело...


Название: Re: query.next()
Отправлено: olejOK17 от Март 09, 2015, 16:08
По какой причине может не переходить ко второй записи?


Название: Re: query.next()
Отправлено: PinkPanther от Март 09, 2015, 16:51
По какой причине может не переходить ко второй записи?

А кто сказал, что query.next() == false? :D

Код оформлен так, что ошибка может возникнуть в любом месте, а предсказать его работу сможет лишь телепат. Думаю, query.next() исправно выдает true, а ячейки не заполняются по другой причине.

Лично мне в коде бросается в глаза две вещи:
1) Запрос к базе "SELECT *", а читается value(0). Отличный повод для сбоя - читаем нулевой столбец, как будто на 100% знаем, какой столбец в таблице нулевой. Если выбирается вся строка, делается запрос к ячейке по имени, value("имя_столбца"), а если нужен конкретный столбец, следует выбирать "SELECT имя_столбца" (и читать потом хоть по имени, хоть value(0));
2) QStandartItem *item объявляется до цикла, а в цикле переменной присваиваются все новые и новые значения, которые потом отдаются наружу... А если указатель передается по ссылке, если функция работает не с содержимым указателя, а с самим указателем? Зачем вообще нужна эта переменная? Следует либо каждый раз объявлять новый указатель внутри тела цикла, QStandartItem *item = new ... , либо вызывать model->setItem(i, j, new QStandartItem(text));


Название: Re: query.next()
Отправлено: olejOK17 от Март 09, 2015, 21:24
По какой причине может не переходить ко второй записи?

А кто сказал, что query.next() == false? :D

Код оформлен так, что ошибка может возникнуть в любом месте, а предсказать его работу сможет лишь телепат. Думаю, query.next() исправно выдает true, а ячейки не заполняются по другой причине.

Лично мне в коде бросается в глаза две вещи:
1) Запрос к базе "SELECT *", а читается value(0). Отличный повод для сбоя - читаем нулевой столбец, как будто на 100% знаем, какой столбец в таблице нулевой. Если выбирается вся строка, делается запрос к ячейке по имени, value("имя_столбца"), а если нужен конкретный столбец, следует выбирать "SELECT имя_столбца" (и читать потом хоть по имени, хоть value(0));
2) QStandartItem *item объявляется до цикла, а в цикле переменной присваиваются все новые и новые значения, которые потом отдаются наружу... А если указатель передается по ссылке, если функция работает не с содержимым указателя, а с самим указателем? Зачем вообще нужна эта переменная? Следует либо каждый раз объявлять новый указатель внутри тела цикла, QStandartItem *item = new ... , либо вызывать model->setItem(i, j, new QStandartItem(text));

Код:
for(int i=0; i<3; i++) {
      if (query.next()) {
        QString name = query.value("ThemeID").toString();
        model->setItem(i, 0, new QStandardItem(name));
        name = query.value("Name").toString();
        model->setItem(i, 1, new QStandardItem(name));
      }
    }
  Теперь так. Но почему же все-таки я не могу перейти к следующей записи после первой?


Название: Re: query.next()
Отправлено: PinkPanther от Март 09, 2015, 22:00
В таблице точно больше одной строки? Проверьте количество записей в таблице

query.clear();
if(!query.exec("SELECT COUNT(*) FROM Theme"))
  qDebug() << "Ошибка запроса: " << query.lastError().text();
else
{
  query.next();
  qDebug() << "Число строк в таблице: " << query.value(0).toInt();
}

Если выдает верное число строк, тогда затрудняюсь ответить.
Если неверное, ошибка в подключении к БД.

PS "ThemeID" - это текст? Если все-таки INT, логичнее выглядит QString::number(query.value("ThemeID").toInt());