crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

> Работа с подготовленными запросами (QSqlQuery::prepare) (Firebird 2.1), оптимизация запросов, кэширование, транзакции
Steklova Olga
  опции профиля:
сообщение 3.2.2014, 19:23
Сообщение #1


Участник
**

Группа: Участник
Сообщений: 198
Регистрация: 27.9.2011
Из: Санкт-Петербург
Пользователь №: 2912

Спасибо сказали: 5 раз(а)




Репутация:   4  


Всем привет :)
Пишу класс для работы с БД.
Написала метод класса, выполняющий подключение к БД.
Написала метод класса, выполняющий вставку записей в таблицу. В таком виде он работает.
QString DBFunctions::insertToDB()
{
    QString squery;
    QSqlQuery queryIns_T_BLOCK;
    squery = "INSERT INTO T_BLOCK (A, B, C) VALUES (:A, :B, :C)";
    if (!queryIns_T_BLOCK.prepare(squery))
        return "QUERY_PREP_ERR: " + QString("'%1' %2")
          .arg("INSERT INTO T_BLOCK").arg(queryIns_T_BLOCK.lastError().text());

    for (int i = 1; i <= 3; i++) {
        queryIns_T_BLOCK.bindValue(":A", 100 * i + 1); //тестовый вариант
        queryIns_T_BLOCK.bindValue(":B", 100 * i + 2);
        queryIns_T_BLOCK.bindValue(":C", 100 * i + 3);
        queryIns_T_BLOCK.exec();
        if (!queryIns_T_BLOCK.isActive())
            return "QUERY_EXEC_ERR: " + QString("'%1' %2")
              .arg("INSERT INTO T_BLOCK").arg(queryIns_T_BLOCK.lastError().text());
        }        

    return "";
}
Метод insertToDB() в процессе работы программы вызывается многократно.
В результате, каждый раз подготавливается один и тот же запрос.
Как сделать так, чтобы запрос подготавливался только один раз?
Я хотела вынести подготовку запроса в другой метод класса, который можно будет вызвать однократно.
Насколько я понимаю, для этого queryIns_T_BLOCK должно быть известно в обоих этих методах.
Еще не написав доп. метод, а только выполнив перенос описания QSqlQuery queryIns_T_BLOCK сюда
class DBFunctions
{
...
private:
    QSqlQuery queryIns_T_BLOCK;
};
у меня перестала работать подготовка запроса.
prepare стал выдавать ошибку Driver not loaded. Не понимаю, в чем дело.
Экземпляры класса QSqlQuery могут быть только локальными переменными?

Сообщение отредактировал Steklova Olga - 7.2.2014, 18:45
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
 
Начать новую тему
Ответов
Steklova Olga
  опции профиля:
сообщение 10.2.2014, 16:34
Сообщение #2


Участник
**

Группа: Участник
Сообщений: 198
Регистрация: 27.9.2011
Из: Санкт-Петербург
Пользователь №: 2912

Спасибо сказали: 5 раз(а)




Репутация:   4  


9)
squery = "INSERT INTO T_BLOCK (A, B, C) VALUES (:A, :B, :C)";
if (!q.prepare(squery))...
Цитата(Litkevich Yuriy @ 8.2.2014, 13:05) *
на мой вгляд это лишнее условие
Обычно я проверяю это условие, чтобы отдельно проверить правильность формирования строки squery. Ведь она не всегда столь тривиальна.

Хотя в доке и сказано, что
bool QSqlQuery::prepare ( const QString & query )
Prepares the SQL query for execution.
Returns true if the query is prepared successfully; otherwise returns false.
Portability note: Some databases choose to delay preparing a query until it is executed the first time.
In this case, preparing a syntactically wrong query succeeds, but every consecutive exec() will fail.


10)
q.exec(squery);
if (!q.isActive())...
Цитата(Litkevich Yuriy @ 8.2.2014, 13:36) *
Если ты хочешь проверить успешность запроса, то смотри что возвращает exec(), а не активность/неактивность. Часто isActive() будет возвращать Ложь

В доке сказано, что
bool QSqlQuery::exec ( const QString & query )
Executes the SQL in query.
Returns true and sets the query state to active if the query was successful; (isActive == true)
otherwise returns false. (здесь нельзя рассчитывать, что isActive == false?)

bool QSqlQuery::exec ()
Executes a previously prepared SQL query.
Returns true if the query executed successfully; (здесь можно рассчитывать, что isActive == true?)
otherwise returns false. (здесь нельзя рассчитывать, что isActive == false?)

bool QSqlQuery::isActive () const
Returns true if the query is active.
An active QSqlQuery is one that has been exec()'d successfully but not yet finished with.
When you are finished with an active query, you can make the query inactive by calling finish() or clear(), or you can delete the QSqlQuery instance.


А если q.exec(squery) вернет true, то разве q.isActive() может при этом вернуть false?
Я ведь не делаю для запроса finish(), clear() или delete.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Сообщений в этой теме


Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 28.4.2024, 5:27