Выполнение инструкций SQLКласс QSqlQuery обеспечивает интерфейс для выполнения SQL запросов и навигации по результирующей выборке. Классы QSqlQueryModel и QSqlTableModel, описанные в следующем разделе, предоставляют высокоуровневый интерфейс для доступа к базам данных. Если вы не знакомы с SQL, вам, возможно, захочется сразу перейти к следующему разделу (Использование классов SQL модели). Выполнение запросаДля выполнения SQL запросов, просто создают объект QSqlQuery и вызывают QSqlQuery::exec(). Например, вот так: QSqlQuery query; query.exec("SELECT name, salary FROM employee WHERE salary > 50000"); Конструктор QSqlQuery принимает необязательный аргумент QSqlDatabase, который указывает, какое соединение с базой данных используется. В нижеприведенном примере мы не указываем соединение, поэтому используется соединение по умолчанию. Если возникает ошибка, exec() возвращает false. Доступ к ошибке можно получить с помощью QSqlQuery::lastError(). Навигация по результирующей выборкеQSqlQuery предоставляет единовременный доступ к результирующей выборке одного запроса. После вызова exec(), внутренний указатель QSqlQuery указывает на позицию перед первой записью. Мы должны вызвать метод QSqlQuery::next() один раз, чтобы переместить указатель к первой записи, затем снова повторять вызов next(), чтобы получать доступ к другим записям, до тех пор пока он не вернет false. Вот типичный цикл, перебирающий все записи по порядку: while (query.next()) { QString name = query.value(0).toString(); int salary = query.value(1).toInt(); qDebug() << name << salary; } Функция QSqlQuery::value() возвращает значение поля текущей записи. Поля задаются индексами, начиная с нуля. Функция QSqlQuery::value() возвращает значение типа QVariant, который может хранить значения различных типов C++ и ядра Qt, такие как int, QString и QByteArray. Различные типы значений базы данных автоматически приводятся к ближайшему эквиваленту в Qt. В данном фрагменте кода мы вызываем QVariant::toString() и QVariant::toInt() для преобразования переменных в QString и int. Для обзора типов, рекомендуемых для использования с поддерживаемыми Qt базами данных, пожалуйста обратитесь к этой таблице. Вы можете перемещаться назад и вперед по выборке, используя функции QSqlQuery::next(), QSqlQuery::previous(), QSqlQuery::first(), QSqlQuery::last() и QSqlQuery::seek(). Текущий номер строки можно получить с помощью QSqlQuery::at(), а общее количество строк в выборке, если это поддерживается базой данных, возвращается функцией QSqlQuery::size(). Определить, поддерживает ли драйвер базы данных определенную особенность можно с помощью вызова функции QSqlDriver::hasFeature(). В следующем примере мы вызываем QSqlQuery::size() для определения размера результирующей выборке, только в том случае, если база данных поддерживает такую возможность; в противном случае мы перемещаемся к последней записи и используем ее позицию в выборке для определения количества записей. QSqlQuery query; int numRows; query.exec("SELECT name, salary FROM employee WHERE salary > 50000"); QSqlDatabase defaultDB = QSqlDatabase::database(); if (defaultDB.driver()->hasFeature(QSqlDriver::QuerySize)) { numRows = query.size(); } else { // это может быть очень медленно query.last(); numRows = query.at() + 1; } Если вы перебираете результирующую выборку только с помощью вызовов next() и seek() с положительными значениями, то можете перед вызовом exec() вызвать QSqlQuery::setForwardOnly(true). Эта небольшая оптимизация сильно ускорит выполнение запросов, возвращающих большие выборки. Вставка, изменение и удаление записейQSqlQuery может выполнять любые SQL выражения, а не просто SELECT'ы. Следующий пример вставляет запись в таблицу, используя INSERT: QSqlQuery query; query.exec("INSERT INTO employee (id, name, salary) " "VALUES (1001, 'Thad Beaumont', 65000)"); Если вы хотите одновременно вставить множество записей, то зачастую эффективней отделить запрос от реально вставляемых значений. Это можно сделать с помощью вставки значений через параметры. Qt поддерживает два синтаксиса вставки значений: поименованные параметры и позиционные параметры. В следующем примере показана вставка с помощью поименованного параметра: QSqlQuery query; query.prepare("INSERT INTO employee (id, name, salary) " "VALUES (:id, :name, :salary)"); query.bindValue(":id", 1001); query.bindValue(":name", "Thad Beaumont"); query.bindValue(":salary", 65000); query.exec(); В этом примере показана вставка с помощью позиционного параметра: QSqlQuery query; query.prepare("INSERT INTO employee (id, name, salary) " "VALUES (?, ?, ?)"); query.addBindValue(1001); query.addBindValue("Thad Beaumont"); query.addBindValue(65000); query.exec(); Оба синтаксиса работают со всеми драйверами баз данных предоставляемыми Qt. Если база данных поддерживает синтаксис, Qt просто пересылает запрос в СУБД; в противном случае, Qt симулирует синтаксис параметров и осуществляет предобработку запроса. Фактический запрос, который поступает на выполнение в СУБД доступен с помощью QSqlQuery::executedQuery(). При вставке множества записей, вам требуется вызвать QSqlQuery::prepare() только однажды. Далее вы можете вызвать bindValue() или addBindValue() с последующим вызовом exec() столько раз, сколько потребуется. Помимо удобства выполнения, вставка через параметры имеет еще и то преимущество, что вы избавлены от необходимости заботиться о преобразовании специальных символов. Изменение записей очень похоже на вставку в таблицу: QSqlQuery query; query.exec("UPDATE employee SET salary = 70000 WHERE id = 1003"); Вы также можете использовать поименованную или позиционную вставку для ассоциирования параметров строки запроса с актуальными значениями. В конце приведем пример выражения DELETE: QSqlQuery query; query.exec("DELETE FROM employee WHERE id = 1007"); ТранзакцииЕсли основной движок базы данных поддерживает транзакции, то QSqlDriver::hasFeature(QSqlDriver::Transactions) возвратит true. Для инициации транзакции вы можете использовать QSqlDatabase::transaction(), затем запустить инструкции SQL, которые вы хотите выполнить в пределах транзакции, а после вызвать QSqlDatabase::commit() или QSqlDatabase::rollback(). При использовании транзакции вы должны начать её, прежде чем создадите свой запрос. Пример: QSqlDatabase::database().transaction(); QSqlQuery query; query.exec("SELECT id FROM employee WHERE name = 'Torild Halvorsen'"); if (query.next()) { int employeeId = query.value(0).toInt(); query.exec("INSERT INTO project (id, name, ownerid) " "VALUES (201, 'Manhattan Project', " + QString::number(employeeId) + ')'); } QSqlDatabase::database().commit(); Транзакции можно использовать для того, чтобы гарантировать атомарность сложного действия (например, просмотр внешних ключей и создание записи) или для возможности отмены сложного действия в процессе его выполнения. |
Попытка перевода Qt документации. Если есть желание присоединиться, или если есть замечания или пожелания, то заходите на форум: Перевод Qt документации на русский язык... Люди внесшие вклад в перевод: Команда переводчиков |