
- •Работа №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.5Выполнение параметрических sql-запросов Select
Как известно, SQL-сервер БД обладает средствами для предварительного разбора и оптимизации запросов, причем с кэшированием просчитанных сценариев. К оптимизации относится построение плана запроса, профилировка, фоновое создание дополнительных индексов и т.д. Этот процесс называется загрузкой, или подготовкой запроса. Для загрузки запроса в QT служит метод QtSqlQuery::prepare().
Передаваемая строка-запрос может содержать ряд параметров для последующей параметризации запроса (нужно понимать, что каждый параметр потенциально снижает уровень оптимизации). Параметры могут быть заданы в двух форматах: именованные в стиле Oracle (:parameter) и вопросительные знаки ODBC (как в MS Access). Смешивание двух форматов не допускается.
В зависимости от техники задания параметров, можно подставлять их по имени или по позиции. Подстановка производится в подготовленный запрос. Для подстановки по имени используется один из перегруженных методов, из категории
QSqlQuery::bindValue(QString, QVariant, QSql::ParameterType). Имя переменной указывается вместе с двоеточием, т.е. так же, как она была задана в запросе.
Для подстановки по порядковому номеру используются методы
bindValue(int, QVariant)
или
addBindValue(QVariant, QSql::ParameterType).
Последний метод просто формирует список параметров, добавляя по одному за раз – при этом нелегко понять, какой параметр добавляется в данный момент. Метод именованных параметров дает значительно более читабельный код. Ниже приводятся примеры использования именованной подстановки параметров, и подстановки параметров по номеру.
Для именованных параметров
QSqlQuery query();
query.prepare("SELECT author, name FROM \"Books\"
WHERE price >= :param");
query.bindValue(":param", 50);
query.exec();
Подстановка параметров по номеру
QSqlQuery query();
query.prepare("SELECT author, name FROM \"Books\"
WHERE price >= ?");
query.addBindValue(50);
query.exec();
Ниже приводится пример функции выполнения простого параметрического SQL-запроса «Получить список книг издательства Х, поставляемых поставщиком У».
bool doQueryWithParam (QString param1, QString param2, QSqlQuery *query)
{
query->prepare("SELECT author, name_book, price FROM \"Books\","
"\"Deliveries\",\"Suppliers\" "
"WHERE \"Books\".id_book = \"Deliveries\".id_book and"
"\"Deliveries\".id_supplier =\"Suppliers\".id_supplier and"
"\"Books\".publish = :X and \"Suppliers\".name_sup = :Y");
query->bindValue(":X", param1);
query->bindValue(":Y", param2);
return query->exec();
}
На рисунке 5.8 показан простой пример интерфейса приложения для выполнения параметрического запроса.
Рисунок 5.8 – Пример интерфейса приложения для выполнения параметрических SQL-запросов Select
5.1.6Выполнение параметрических sql-запросов Insert, Update, Delete
Помимо простых запросов на выборку данных, можно также выполнять запросы на их модификацию (Insert, Update, Delete). Ниже приводятся примеры запросов для добавления, удаления и изменения информации о заказчиках (таблица “Customers” БД “BookShop”).
«Добавить данные о заказчике»
bool addCustomer (int id, QString name, QString addr, QString telephone)
{
QSqlQuery query;
query.prepare("INSERT INTO \”Customers\”(id_customer, name_cust,
address, tel) VALUES (:p1, :p2, :p3, :p4)");
query.bindValue(":p1", id);
query.bindValue(":p2", name);
query.bindValue(":p3", addr);
query.bindValue(":p4", telephone);
if((!query.exec()) || (query.numRowsAffected() == 0))
{
qDebug()<< "ERROR in INSERT command";
return false;
}
else
{
return true;
}
}
«Удалить данные о заказчике».
bool delCustomerById (int id)
{
QSqlQuery query;
query.prepare("DELETE FROM \”Customers\” WHERE id_customer= :p1");
query.bindValue(":p1", id);
if((!query.exec()) || (query.numRowsAffected() == 0))
{
qDebug()<< "ERROR in DELETE command";
return false;
}
else
{
return true;
}
}
В качестве параметра в функцию передается идентификатор заказчика, которого нужно удалить из БД.
«Изменить данные о заказчике»
bool updateCustomer (int id, int newId, QString newName, QString newAddr, QString newTel)
{
QSqlQuery query;
query.prepare("UPDATE \”Customers\” SET id_customer = :new_id, name_cust=
:new_name, address= :new_addr, tel = :new_tel WHERE
id_customer= :p1");
query.bindValue(":new_id", newId);
query.bindValue(":new_name", newName);
query.bindValue(":new_addr", newAddr);
query.bindValue(":new_tel", newTel);
query.bindValue(":p1", id);
if((!query.exec()) || (query.numRowsAffected() == 0))
{
qDebug()<< "ERROR in UPDATE command";
return false;
}
else
{
return true;
}
}
В качестве параметра в функцию передается идентификатор заказчика, информацию о котором нужно изменить, и новые данные.
Из приведенных выше примеров следует обратить внимание на метод QSqlQuery::numRowsAffected(). При выполнении SQL-запросов INSERT, UPDATE или DELETE этот метод возвращает число успешно добавленных, обновленных или удаленных записей.