
- •Работа №5 Создание программного приложения для работы с базой данных
- •5.1Теоретические сведения
- •5.1.1Система Interview Framework в sdk Qt 4
- •5.1.2Использование odbc для подключения источника данных
- •5.1.3Соединение с базой данных
- •5.1.4Выполнение непараметрического sql-запроса Select
- •5.1.5Выполнение параметрических sql-запросов Select
- •5.1.6Выполнение параметрических sql-запросов Insert, Update, Delete
- •5.1.7Выполнение транзакций
- •5.1.8Разработка форм для просмотра таблиц в режиме «главный-детальный»
- •5.2Порядок выполнения работы
- •5.3Требования к отчету
- •5.4Контрольные вопросы
5.1.4Выполнение непараметрического sql-запроса Select
После успешного соединения с БД можно выполнять запросы SQL и обрабатывать их результаты. Для этого используется класс QSqlQuery. Ниже приводится пример функции выполнения команды SELECT и обработки ее результатов:
void doSqlQuery(QString queryStr, QListWidget *listWidget)
{
QSqlQuery query;
if (!query.exec(queryStr))
{
qDebug()<< "Can`t do query!";
}
else
{
QSqlRecord rec = query.record();
qDebug() << "Number of columns: " << rec.count();
QString str;
for (int i = 0; i < rec.count(); i++)
{
str = str+"\t"+rec.fieldName(i);
}
listWidget->addItem(str);
while (query.next())
{
int i=0;
QString strField;
while (query.value(i).isValid())
{
strField = strField+"\t"+ query.value(i).toString();
i++;
}
listWidget->addItem(strField);
}
}
}
Для выполнения запросов к БД используется метод exec(), которому в качестве параметра передается строка SQL-запроса. После его вызова можно просмотреть результат команды SELECT. Метод next() вызывается один раз для позиционирования объекта QSqlQuery на первую запись полученного набора данных (под набором данных понимается группа записей из одной или нескольких таблиц физической БД, полученная в результате выполнения SQL-запроса). Последующие вызовы next() продвигают указатель записи на одну позицию дальше, пока не будет достигнут конец набора данных и метод next() вернет false. Если результирующий набор данных (result set) пустой (или запрос завершается неудачей), первый вызов метода next() возвратит false.
Метод value(номер_столбца) возвращает значение поля типа QVariant, которое надо преобразовать к нужному типу с помощью методов QVariant::toInt, QVariant::toLongLong, QVariant::toString, QVariant::toDouble, QVariant::toDate, QVariant::toDateTime и т.д. Поля пронумерованы начиная с 0 в порядке их указания в команде SELECT. Поскольку доступ по имени поля не предусмотрен, следует избегать запросов типа SELECT *, так как порядок полей в результирующем наборе не очевиден.
Кроме next(), для навигации по набору данных можно использовать методы first(), last(), previous(), seek(int index, bool relative=false). Для увеличения быстродействия набор данных лучше сделать однонаправленным, вызвав метод QSqlQuery::setForwardOnly(true) до выполнения запроса, после этого можно использовать только метод next().
Вывод результата запроса происходит в компонент ListWidget, указатель на который передается в функцию (также можно выводить данные в компонент TableWidget). Ниже приводится пример вызова функции doSqlQuery():
void MainWindow::on_pushButton_clicked()
{
QString str = “Select * From \”Books\””;
doSqlQuery(str, ui->listWidget);
}
На рисунке 5.7 показан пример интерфейса приложения для выполнения непараметрического запроса.
Рисунок 5.7 – Пример интерфейса приложения для выполнения непараметрических SQL-запросов Select
Кроме метода QSqlQuery::ехес() SQL-запрос можно передавать в качестве аргумента в конструктор, который сразу же выполнит его. Например:
QSqlQuery query("SELECT author, name FROM \"Books\"
WHERE price >= 50").
Чтобы проверить наличие ошибки в результате выполнения запроса, вызывается метод isActive():
if (! query.isActive())
QMessageBox::warning(this,tr("Database Error"),
query.lastError().text());
Если ошибки нет, запрос становится активным и можно использовать метод next() для перемещения по результирующему набору данных.