Russian Qt Forum
Ноябрь 24, 2024, 09:35 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: QSqlDatabase (prepare и exec)  (Прочитано 6909 раз)
dnc2rt
Гость
« : Март 05, 2010, 10:24 »

Доброе утро!
Не удается выполнить запрос используя:

Код:
QSqlQuery query(QSqlDatabase::database("localdb"));

QString sql = "SELECT * FROM users;";

query.prepare( sql );
if( !query.exec() )
{
  QMessageBox::critical( this, QObject::tr("Fatal Error"), query.lastError().text() );
  QMessageBox::critical( this, QObject::tr("query"), query.lastQuery() );
  return;
}

В итоге, на prepare возвращает true, а вот на exec в первом сообщении выдает пустое окно (пустое окно уже обсуждалось на форуме), а во втором наш sql запрос.

Но если опустить prepare и выполнить:

Код:
QSqlQuery query(QSqlDatabase::database("localdb"));
QString sql = "SELECT * FROM users;";
if( !query.exec(sql) )
{
  QMessageBox::critical( this, QObject::tr("Fatal Error"), query.lastError().text() );
  QMessageBox::critical( this, QObject::tr("query"), query.lastQuery() );
  return;
}

То все работает, но хотелось бы, чтобы в будущем можно было использовать prepare...
Записан
MoPDoBoPoT
Гость
« Ответ #1 : Март 05, 2010, 16:36 »

Странно, такого не должно быть (только что даже проверил).
Может где-то у тебя все-таки ошибка в коде?
Записан
dnc2rt
Гость
« Ответ #2 : Март 06, 2010, 20:12 »

Спасибо! Значит либо ошибка в подключении mysql к Qt, может не правильно подключил, хотя exec() работает верно.
Попробую наверно переставить на другой машине все и установить mysql последний, а то сейчас он 5.0 и собирал не совсем под него...
Еще раз спасибо, попробую копнуть в другую сторону!
Записан
dnc2rt
Гость
« Ответ #3 : Март 09, 2010, 09:21 »

Все, разобрался, спасибо  Веселый!
Записан
dnc2rt
Гость
« Ответ #4 : Март 09, 2010, 11:59 »

Добрый день, похоже я с этим долго буду воевать...

Код:
QSqlQuery query(QSqlDatabase::database("localdb"));
QString sql = "SELECT name FROM users;";
query.prepare( sql );
if( !query.exec() )
{
  ***
}
int i = query.size();
while( query.next() )
{
   // Сюда не заходит, в то время как в переменную i возвращается правильное значение. (Например "4")
}

Код:
QSqlQuery query(QSqlDatabase::database("localdb"));
QString sql = "SELECT name FROM users;";
if( !query.exec(sql) )
{
  ***
}
int i = query.size();
while( query.next() )
{
   // Сюда заходит на ура, выдает наш любимый cp1251
}

Подскажите, что я делаю не так?! Вроде все правильно, и оба варианта возвращают количество результирующих записей, но ...
Записан
break
Гипер активный житель
*****
Offline Offline

Сообщений: 846


Просмотр профиля
« Ответ #5 : Март 09, 2010, 14:47 »

наверное query.first(); перед циклом...
Записан
dnc2rt
Гость
« Ответ #6 : Март 09, 2010, 16:39 »

Вроде как перед циклом ставить смысла хорошего нет, ибо в документации по поводу QSqlQuery::next(), написано следующее:
Цитировать
if the result is currently located before the first record, e.g. immediately after a query is executed, an attempt is made to retrieve the first record
Насколько я понимаю, в данном случае QSqlQuery::first() пользы не принесет... могу ошибаться...

Кстати, prepare и последующее использование bindValue не дает необходимых результатов, т.е. если в

***.prepare( "SELECT name FROM ? ;" );
***.bindValue( 0, "groups" );
***.exec();

в ***.lastQuery() будет выдано "SELECT name FROM ? ;"... перепробовал все примеры в документации, не могу понять, в чем проблема....

Пока приходится пользоваться ***.exec( "код запроса" ); Но это очень не удобно... и QDateTime::currentDateTime я так вставить не смогу...
« Последнее редактирование: Март 09, 2010, 17:35 от dnc2rt » Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #7 : Март 09, 2010, 17:41 »

lastQuery выдает запрос без биндов. Чтобы увидеть бинды, есть boundValues. К сожалению, конечный запрос (с подставленными значениями) увидеть не получится. Грустный
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
break
Гипер активный житель
*****
Offline Offline

Сообщений: 846


Просмотр профиля
« Ответ #8 : Март 09, 2010, 18:41 »

Цитировать
Насколько я понимаю, в данном случае QSqlQuery::first() пользы не принесет... могу ошибаться...
Пробовал? В документации действительно сказано что вроде как не надо, но вдруг баг...
Записан
MoPDoBoPoT
Гость
« Ответ #9 : Март 09, 2010, 18:52 »

наверное query.first(); перед циклом...
Только не забыть про первую запись, а то можно и перепрыгнуть (while (query.next()) )...

***.prepare( "SELECT name FROM ? ;" );
***.bindValue( 0, "groups" );
***.exec();
Вообще говоря, здесь допущена ошибка. Бинды предназначены только для значений переменных, используемых в части WHERE. Подготовка запроса и связывание переменных, это целый механизм, а не тупо подстановка/замена текста в запросе. Но в твоем случае запрос прошел, потому что используемая тобой СУБД (или драйвер к ней) не поддерживает позиционное связывание (именно позиционное, т.к. bindValue(0,...)) и поэтому произошла обычная подстановка.
Записан
dnc2rt
Гость
« Ответ #10 : Март 09, 2010, 19:58 »

Все, надеюсь теперь буду внимательнее!

Спасибо Пантер, буду знать этот нюанс.
break, спасибо за помощь. Спасибо тебе за ответ в топике про QDateTime и prepare! Полезная новость для меня.
MoPDoBoPoT, спасибо за исчерпывающую информацию!!!

PS: еще оказалось огромную роль в том что работало не как надо даже если писать корректно - не верная сборка mysql... со старой сборкой 5.0 у меня работает не так как надо, в то время как с последней нет проблем.
« Последнее редактирование: Март 10, 2010, 08:04 от dnc2rt » Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.054 секунд. Запросов: 23.