Читаем QT 4: программирование GUI на С++ полностью

Класс QSqlQuery содержит некоторые другие функции для просмотра результирующего набора: first, last, previous и seek. Эти функции удобны, но для некоторых баз данных они могут выполняться медленнее и расходовать памяти больше, чем функция next. При работе с большими наборами данных мы можем осуществить простую оптимизацию, вызывая функцию QSqlQuery::setForwardOnly(true) перед вызовом exec, и только затем использовать next для просмотра результирующего набора.

Ранее мы задавали запрос SQL в аргументе функции QSqlQuery::exec, но, кроме того, мы можем передавать его непосредственно конструктору, который сразу же выполнит его:

QSqlQuery query("SELECT title, year FROM cd WHERE year >= 1998");

Мы можем проверить наличие ошибки, вызывая функцию isActive для запроса:

if (!query.isActive)

QMessageBox::warning(this, tr("Database Error"),

query.lastError.text);

Если ошибки нет, запрос становится «активным» и мы можем использовать next для перемещения по результирующему набору.

Выполнение команды INSERT осуществляется почти так же просто, как и команды SELECT:

QSqlQuery query("INSERT INTO cd (id, artistid, title, year) "

"VALUES (203, 102, 'Living in America', 2002)");

После этого функция numRowsAffected возвращает количество строк, которые были изменены инструкцией SQL (или —1, если возникла ошибка).

Если нам необходимо вставлять много записей или если мы хотим избежать преобразования значений в строковые данные (и правильного преобразования специальных символов), мы можем использовать функцию prepare для указания полей в шаблоне запроса и затем присваивания им необходимых нам значений. Qt поддерживает как стиль Oracle, так и стиль ODBC для всех баз данных, применяя, где возможно, «родной» интерфейс базы данных или имитируя его в противном случае. Ниже приводится пример, в котором используется синтаксис Oracle для представления поименованных полей:

QSqlQuery query;

query.prepare("INSERT INTO cd (id, artistid, title, year) "

"VALUES (:id, :artistid, :title, :year)");

query.bindValue(":id", 203);

query.bindValue(":artistid", 102);

query.bindValue(":title", "Living in America");

query.bindValue(":year", 2002);

query.exec;

Ниже приводится тот же пример позиционного представления полей в стиле ODBC:

QSqlQuery query;

query.prepare("INSERT INTO cd (id, artistid, title, year) "

"VALUES (?, ?, ?, ?)");

query.addBindValue(203);

query.addBindValue(102);

query.addBindValue("Living in America");

query.addBindValue(2002);

query.exec;

После вызова функции exec мы можем вызвать bindValue или addBindValue для присваивания новых значений, затем снова вызвать exec для выполнения запроса уже с новыми значениями.

Такие шаблоны часто используются для задания двоичных строковых данных, содержащих символы не в коде ASCII или Latin-1. Незаметно для пользователя Qt использует Unicode в тех базах данных, которые поддерживают Unicode, а в тех, которые не делают этого, Qt также незаметно для пользователя преобразует строковые данные в соответствующую кодировку.

Qt поддерживает SQL—транзакции в тех базах данных, где они предусмотрены. Для запуска транзакции мы вызываем функцию transaction для объекта QSqlDatabase, представляющего соединение с базой данных. Для завершения транзакции мы вызываем либо функцию commit, либо функцию rollback. Например, ниже показано, как мы можем найти внешний ключ (foreign key) и выполнить команду INSERT внутри транзакции:

QSqlDatabase::database.transaction;

QSqlQuery query;

query.exec("SELECT id FROM artist WHERE name= 'Gluecifer'");

if (query.next) {

int artistId = query.value(0).tolnt;

query.exec("INSERT INTO cd (id, artistid, title, year) "

"VALUES (201, " + QString::number(artistId)

+ ", 'Riding the Tiger', 1997)");

}

QSqlDatabase::database.commit;

Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже