Драйверы баз данных SQL
Модуль Qt SQL использует драйверы плагины для взаимодействия с различными API баз данных. Поскольку API модуля Qt SQL независим от базы данных, весь код, специфичный для базы данных, находится внутри этих драйверов. Qt поставляется с несколькими драйверами, и можно добавить другие. Исходный код драйвера предоставляется и может быть использован в качестве модели для создания собственных драйверов.
Поддерживаемые базы данных
В таблице ниже перечислены драйверы, включенные в Qt:
| Название драйвера | Система управления базами данных (СУБД) |
|---|---|
| QDB2 | IBM DB2 (версия 7.1 и выше) |
| QIBASE | Borland InterBase |
| QMYSQL | MySQL |
| QOCI | Драйвер Oracle Call Interface |
| QODBC | Open Database Connectivity (ODBC) — Microsoft SQL Server и другие базы данных, совместимые с ODBC |
| QPSQL | PostgreSQL (версии 7.3 и выше) |
| QSQLITE2 | SQLite версия 2 |
| QSQLITE | SQLite версия 3 |
| QTDS | Sybase Adaptive Server Примечание: устарел начиная с Qt 4.7 |
SQLite — это системa баз данных в процессе, с наилучшим охватом тестов и поддержкой на всех платформах. Oracle через OCI, PostgreSQL и MySQL через ODBC или родной драйвер хорошо протестированы на Windows и Linux. Полнота поддержки других систем зависит от наличия и качества клиентских библиотек.
Примечание: Для построения плагина драйвера необходимо наличие соответствующей клиентской библиотеки для вашей системы управления базами данных (СУБД). Это обеспечивает доступ к API, экспонированному СУБД, и обычно поставляется вместе с ней. Большинство установочных программ также позволяют устанавливать «библиотеки разработки», и именно они вам нужны. Эти библиотеки отвечают за низкоуровневое взаимодействие с СУБД.
Примечание: При использовании Qt в рамках условий открытого исходного кода, но с проприетарной базой данных, проверьте совместимость лицензии клиентской библиотеки с LGPL.
Компиляция драйверов
Qt configure скрипт пытается автоматически определить доступные клиентские библиотеки на вашем компьютере. Запустите configure -help для просмотра драйверов, которые можно скомпилировать. Вы должны получить вывод, похожий на этот:
[...]
Database options:
-sql-<driver> ........ Enable SQL <driver> plugin. Supported drivers:
db2 ibase mysql oci odbc psql sqlite2 sqlite tds
[all auto]
-sqlite .............. Select used sqlite3 [system/qt]
[...] Скрипт configure не может определить необходимые библиотеки и файлы заголовков, если они не находятся в стандартных путях, поэтому может потребоваться указать эти пути с помощью *_INCDIR=, *_LIBDIR=, или *_PREFIX= командных параметров. Например, если ваши файлы MySQL установлены в /usr/local/mysql (или в C:\mysql в Windows), то передайте следующий параметр для настройки: MYSQL_PREFIX=/usr/local/mysql (или MYSQL_PREFIX=C:\mysql для Windows). Подробные сведения для каждого драйвера описаны ниже.
В связи с практическими сложностями работы с внешними зависимостями, только плагин SQLite3 поставляется с двоичными сборками Qt. Чтобы добавить дополнительные драйверы в установку Qt без перекомпиляции всего Qt, можно настроить и скомпилировать каталог qtbase/src/plugins/sqldrivers вне каталога полной сборки Qt. Обратите внимание, что настроить каждый драйвер отдельно нельзя, можно только все сразу. Однако драйверы можно компилировать по отдельности. Если сборка Qt настроена с -prefix, после компиляции плагины необходимо установить тоже. Например:
cd $QTDIR/qtbase/src/plugins/sqldrivers/mysql make install
Подробности о драйверах
QMYSQL для MySQL 4 и выше
Поддержка хранимых процедур QMYSQL
MySQL 5 вводит поддержку хранимых процедур на уровне SQL, но не предоставляет API для управления параметрами IN, OUT и INOUT. Поэтому параметры необходимо устанавливать и считывать с помощью команд SQL вместо QSqlQuery::bindValue().
Пример хранимой процедуры:
create procedure qtestproc (OUT param1 INT, OUT param2 INT)
BEGIN
set param1 = 42;
set param2 = 43;
END Исходный код для доступа к значениям OUT:
QSqlQuery q;
q.exec("call qtestproc (@outval1, @outval2)");
q.exec("select @outval1, @outval2");
q.next();
qDebug() << q.value(0) << q.value(1); // outputs "42" and "43" Примечание: @outval1 и @outval2 — переменные, локальные для текущего соединения, и они не будут затронуты запросами, отправленными с другого хоста или соединения.
Встроенный сервер MySQL
Встроенный сервер MySQL — это замена обычной клиентской библиотеки. С встроенным сервером MySQL не требуется сервер MySQL для использования функциональности MySQL.
Для использования встроенного сервера MySQL просто подключите плагин Qt к libmysqld вместо libmysqlclient. Это можно сделать, добавив MYSQL_LIBS=-lmysqld в командную строку конфигурации.
Для получения дополнительной информации об встроенном сервере MySQL обратитесь к документации MySQL, глава "libmysqld, the Embedded MySQL Server Library".
Как скомпилировать плагин QMYSQL на Unix и macOS
Вам потребуются файлы заголовков MySQL, а также общая библиотека libmysqlclient.so. В зависимости от вашей дистрибуции Linux, вам может потребоваться установить пакет, который обычно называется «mysql-devel».
Укажите qmake, где найти файлы заголовков и общие библиотеки MySQL (здесь предполагается, что MySQL установлен в /usr/local) и запустите make.
cd $QTDIR/qtbase/src/plugins/sqldrivers qmake -- MYSQL_PREFIX=/usr/local make sub-mysql
Как скомпилировать плагин QMYSQL на Windows
Вам необходимо получить файлы установки MySQL. Запустите SETUP.EXE и выберите «Custom Install». Установите модуль «Libs & Include Files». Скомпилируйте плагин следующим образом (здесь предполагается, что MySQL установлен в C:\MySQL):
cd %QTDIR%\qtbase\src\plugins\sqldrivers qmake -- MYSQL_INCDIR=C:/MySQL/include "MYSQL_LIBDIR=C:/MYSQL/MySQL Server <version>/lib/opt" nmake sub-mysql
Если вы не используете компилятор Microsoft, замените nmake на mingw32-make в строке выше.
QOCI для Oracle Call Interface (OCI)
Плагин Qt OCI поддерживает Oracle 9i, 10g и выше. После подключения к серверу Oracle плагин автоматически определит версию базы данных и активирует функции соответственно.
Можно подключиться к базе данных Oracle без файла tnsnames.ora. Для этого необходимо передать SID базы данных в драйвер в качестве имени базы данных и указать имя хоста.
Аутентификация пользователя OCI
Плагин Qt OCI поддерживает аутентификацию с использованием внешних учетных данных (OCI_CRED_EXT). Обычно это означает, что сервер базы данных будет использовать аутентификацию пользователя, предоставленную операционной системой, вместо собственного механизма аутентификации.
Оставьте имя пользователя и пароль пустыми при открытии соединения с QSqlDatabase, чтобы использовать аутентификацию по внешним учетным данным.
Поддержка OCI BLOB/LOB
Двоичные большие объекты (BLOB) могут быть читаемы и записываемы, но имейте в виду, что этот процесс может потребовать много памяти. Для выбора полей LOB следует использовать запросы с односторонним чтением (см. QSqlQuery::setForwardOnly()).
Вставка BLOB должна выполняться с помощью подготовленного запроса, где BLOB привязаны к маркерам, или QSqlTableModel, который использует подготовленный запрос для этого внутренне.
Как скомпилировать плагин OCI на Unix и macOS
Для Oracle 10g вам потребуется только «Instant Client Package - Basic» и «Instant Client Package - SDK». Для Oracle версии ниже 10g требуется стандартный клиент Oracle и пакеты SDK.
Файлы библиотек Oracle, необходимые для компиляции драйвера:
-
libclntsh.so(все версии) -
libwtc9.so(только Oracle 9)
Укажите qmake, где найти файлы заголовков и общие библиотеки Oracle, и выполните make:
Для версии Oracle 9:
cd $QTDIR/qtbase/src/plugins/sqldrivers qmake -- "OCI_INCDIR=$ORACLE_HOME/rdbms/public" OCI_LIBDIR=$ORACLE_HOME/lib "OCI_LIBS=-lclntsh -lwtc9" make sub-oci
Для Oracle версии 10, предполагается, что вы установили пакеты RPM для Instant Client Package SDK (вам необходимо скорректировать номер версии соответственно):
cd $QTDIR/qtbase/src/plugins/sqldrivers qmake -- OCI_INCDIR=/usr/include/oracle/10.1.0.3/client OCI_LIBDIR=/usr/lib/oracle/10.1.0.3/client/lib make sub-oci
Примечание: Если вы используете пакет Oracle Instant Client, вам потребуется установить LD_LIBRARY_PATH при компиляции плагина OCI SQL и при запуске приложения, использующего плагин OCI SQL. Вы можете избежать этой необходимости, установив RPATH и указав все библиотеки для линковки. Вот пример:
configure OCI_INCDIR=/usr/include/oracle/10.1.0.3/client OCI_LIBDIR=/usr/lib/oracle/10.1.0.3/client/lib -R /usr/lib/oracle/10.1.0.3/client/lib "OCI_LIBS=-lclntsh -lnnz10" make
Если вы хотите скомпилировать плагин OCI вручную с помощью этого метода, процедура выглядит следующим образом:
cd $QTDIR/qtbase/src/plugins/sqldrivers qmake -- OCI_INCDIR=/usr/include/oracle/10.1.0.3/client OCI_LIBDIR=/usr/lib/oracle/10.1.0.3/client/lib "OCI_LIBS=-Wl,-rpath,/usr/lib/oracle/10.1.0.3/client/lib -lclntsh -lnnz10" make sub-oci
Как скомпилировать плагин OCI на Windows
Выбор варианта «Разработчик» в установщике Oracle Client с компакт-диска Oracle Client, как правило, достаточно для компиляции плагина. Для некоторых версий Oracle Client, вам также может потребоваться выбрать опцию «Интерфейс вызова (OCI)», если она доступна.
Скомпилируйте плагин следующим образом (здесь предполагается, что Oracle Client установлен в C:\oracle):
cd %QTDIR%\qtbase\src\plugins\sqldrivers qmake -- OCI_INCDIR=c:/oracle/oci/include OCI_LIBDIR=c:/oracle/oci/lib/msvc nmake sub-oci
Если вы не используете компилятор Microsoft, замените nmake на mingw32-make в строке выше.
При запуске приложения вам также необходимо добавить путь oci.dll в переменную среды PATH:
set PATH=%PATH%;c:\oracle\bin
QODBC для Open Database Connectivity (ODBC)
ODBC — это общий интерфейс, который позволяет подключаться к нескольким СУБД с использованием общего интерфейса. Драйвер QODBC позволяет подключаться к менеджеру драйверов ODBC и получать доступ к доступным источникам данных. Обратите внимание, что вам также необходимо установить и настроить драйверы ODBC для менеджера драйверов ODBC, установленного в вашей системе. Плагин QODBC затем позволит вам использовать эти источники данных в ваших приложениях Qt.
Примечание: Следует использовать родной драйвер, если он доступен, вместо драйвера ODBC. Поддержка ODBC может использоваться как резервный вариант для совместимых баз данных, если родной драйвер недоступен.
В Windows менеджер драйверов ODBC должен устанавливаться по умолчанию. Для систем Unix существуют некоторые реализации, которые необходимо установить в первую очередь. Обратите внимание, что каждый конечный пользователь вашего приложения должен иметь установленный менеджер драйверов ODBC, иначе плагин QODBC не будет работать.
При подключении к источнику данных ODBC следует передать имя источника данных ODBC в функцию QSqlDatabase::setDatabaseName(), а не фактическое имя базы данных.
Плагину QODBC нужен менеджер драйверов ODBC версии 2.0 или выше. Некоторые драйверы ODBC заявляют о совместимости с версией 2.0, но не предлагают всей необходимой функциональности. Поэтому плагин QODBC проверяет, можно ли использовать источник данных после установления подключения, и отказывается работать, если проверка завершается неудачно. Если вам не нравится такое поведение, вы можете удалить строку #define ODBC_CHECK_DRIVER из файла qsql_odbc.cpp. Делайте это на свой страх и риск!
По умолчанию Qt указывает драйверу ODBC на поведение как драйверу ODBC 2.x. Однако для некоторых комбинаций драйвер-менеджер/ODBC 3.x-драйвер (например, unixODBC/MaxDB ODBC) указание драйверу ODBC вести себя как драйверу 2.x может привести к неожиданному поведению плагина драйвера. Чтобы избежать этой проблемы, укажите драйверу ODBC вести себя как драйверу 3.x, установив параметр подключения настройки параметра подключения "SQL_ATTR_ODBC_VERSION=SQL_OV_ODBC3" перед установлением соединения с базой данных. Обратите внимание, что это повлияет на множество аспектов поведения драйвера ODBC, например, на значения SQLSTATE. Перед установкой этого параметра подключения обратитесь к документации вашего ODBC по поводу различий в поведении.
При использовании базы данных SAP HANA подключение должно быть установлено с помощью параметра "SCROLLABLERESULT=TRUE", так как драйвер HANA ODBC по умолчанию не предоставляет прокручиваемые результаты, например:
QSqlDatabase db = QSqlDatabase::addDatabase("QODBC3");
QString connectString = QStringLiteral(
"DRIVER=/path/to/installation/libodbcHDB.so;"
"SERVERNODE=hostname:port;"
"UID=USER;"
"PWD=PASSWORD;"
"SCROLLABLERESULT=true");
db.setDatabaseName(connectString); Если вы столкнулись с очень медленным доступом к источнику данных ODBC, убедитесь, что отслеживание вызовов ODBC выключено в менеджере источников данных ODBC.
Некоторые драйверы не поддерживают прокручиваемые курсоры. В этом случае можно успешно использовать только запросы в режиме forwardOnly.
Поддержка хранимых процедур ODBC
В Microsoft SQL Server набор результатов, возвращаемый хранимой процедурой, использующей оператор return или возвращающей несколько наборов результатов, будет доступен только если вы установите режим запроса forward-only в forward, используя QSqlQuery::setForwardOnly().
// STORED_PROC uses the return statement or returns multiple result sets
QSqlQuery query;
query.setForwardOnly(true);
query.exec("{call STORED_PROC}"); Примечание: Значение, возвращаемое оператором return хранимой процедуры, игнорируется.
Поддержка Unicode ODBC
Плагин QODBC будет использовать API Unicode, если определен UNICODE. В системах Windows NT это значение по умолчанию. Обратите внимание, что драйвер ODBC и СУБД также должны поддерживать Unicode.
Некоторые менеджеры драйверов и драйверы не поддерживают UNICODE. Для использования плагина QODBC с такими драйверами он должен быть скомпилирован с определенным Q_ODBC_VERSION_2.
Для драйвера Oracle 9 ODBC (Windows) необходимо проверить "Поддержка SQL_WCHAR" в менеджере драйверов ODBC, иначе Oracle преобразует все строки Unicode в локальные 8-битные.
Как скомпилировать плагин ODBC на Unix и macOS
Рекомендуется использовать unixODBC. Вы можете найти последнюю версию и драйверы ODBC по адресу http://www.unixodbc.org. Вам потребуются заголовочные файлы и общие библиотеки unixODBC.
Укажите qmake местоположение заголовочных файлов и общих библиотек unixODBC (здесь предполагается, что unixODBC установлен в /usr/local/unixODBC) и выполните make.
cd $QTDIR/qtbase/src/plugins/sqldrivers qmake -- ODBC_PREFIX=/usr/local/unixODBC make sub-odbc
Как скомпилировать плагин ODBC на Windows
Заголовочные и включаемые файлы ODBC должны быть установлены в правильных каталогах. Вам просто нужно скомпилировать плагин следующим образом:
cd %QTDIR%\qtbase\src\plugins\sqldrivers qmake nmake sub-odbc
Если вы не используете компилятор Microsoft, замените nmake на mingw32-make в строке выше.
QPSQL для PostgreSQL (Версия 7.3 и выше)
Драйвер QPSQL поддерживает версию 7.3 и выше сервера PostgreSQL.
Дополнительную информацию о PostgreSQL вы найдете на сайте http://www.postgresql.org.
Поддержка Unicode QPSQL
Драйвер QPSQL автоматически определяет, поддерживает ли база данных PostgreSQL, к которой вы подключаетесь, Unicode или нет. Unicode автоматически используется, если сервер его поддерживает. Обратите внимание, что драйвер поддерживает только кодировку UTF-8. Если ваша база данных использует другую кодировку, сервер должен быть скомпилирован с поддержкой преобразования Unicode.
Поддержка Unicode была добавлена в PostgreSQL версии 7.1 и будет работать только в том случае, если сервер и библиотека клиента были скомпилированы с поддержкой многобайтовых символов. Более подробную информацию о настройке многобайтового сервера PostgreSQL вы найдете в руководстве администратора PostgreSQL, глава 5.
Поддержка BLOB QPSQL
Двоичные большие объекты поддерживаются с помощью типа поля BYTEA в версиях сервера PostgreSQL >= 7.1.
Поддержка запросов forward-only QPSQL
Для использования запросов forward-only необходимо скомпилировать плагин QPSQL с библиотекой клиента PostgreSQL версии 9.2 или выше. Если плагин скомпилирован со старой версией, то режим forward-only будет недоступен — вызов QSqlQuery::setForwardOnly() со значением true не будет иметь никакого эффекта.
Предупреждение: Если вы скомпилируете плагин QPSQL с PostgreSQL версии 9.2 или выше, то вы должны распространять свое приложение с libpq версии 9.2 или выше. В противном случае загрузка плагина QPSQL завершится ошибкой с сообщением:
QSqlDatabase: QPSQL driver not loaded QSqlDatabase: available drivers: QSQLITE QMYSQL QMYSQL3 QODBC QODBC3 QPSQL QPSQL7 Could not create database object
При навигации по результатам в режиме forward-only дескриптор QSqlResult может измениться. Приложения, использующие низкоуровневый дескриптор SQL результата, должны получить новый дескриптор после каждого вызова функций извлечения QSqlResult. Пример:
QSqlQuery query(db);
query.setForwardOnly(true);
query.exec("SELECT * FROM table");
while (query.next()) {
// Handle changes in every iteration of the loop
QVariant v = query.result()->handle();
if (qstrcmp(v.typeName(), "PGresult*") == 0) {
PGresult *handle = *static_cast<PGresult **>(v.data());
if (handle) {
// Do something...
}
}
} При чтении результатов запроса forward-only с PostgreSQL база данных не может быть использована для выполнения других запросов. Это ограничение библиотеки libpq. Пример:
int value;
QSqlQuery query1(db);
query1.setForwardOnly(true);
query1.exec("select * FROM table1");
while (query1.next()) {
value = query1.value(0).toInt();
if (value == 1) {
QSqlQuery query2(db);
query2.exec("update table2 set col=2"); // WRONG: This will discard all results of
} // query1, and cause the loop to quit
} Эта проблема не возникнет, если запросы query1 и query2 используют разные подключения к базе данных или если мы выполняем запрос query2 после цикла while.
Примечание: Некоторые методы QSqlDatabase, такие как tables(), primaryIndex(), неявно выполняют SQL-запросы, поэтому их также нельзя использовать во время навигации по результатам запроса forward-only.
Примечание: QPSQL выведет следующее предупреждение, если обнаружит потерю результатов запроса:
QPSQLDriver::getResult: Query results lost - probably discarded on executing another SQL query.
Как скомпилировать плагин QPSQL на Unix и macOS
Вам потребуется установленная библиотека и заголовочные файлы клиента PostgreSQL.
Чтобы qmake найти заголовочные файлы и общие библиотеки PostgreSQL, выполните qmake следующим образом (предполагается, что клиент PostgreSQL установлен в /usr):
cd $QTDIR/qtbase/src/plugins/sqldrivers qmake -- PSQL_INCDIR=/usr/include/pgsql make sub-psql
Как скомпилировать плагин QPSQL на Windows
Установите соответствующие библиотеки разработчика PostgreSQL для вашего компилятора. Предполагая, что PostgreSQL установлен в C:\psql, скомпилируйте плагин следующим образом:
cd %QTDIR%\qtbase\src\plugins\sqldrivers qmake -- PSQL_INCDIR=C:/psql/include PSQL_LIBDIR=C:/psql/lib/ms nmake sub-psql
Пользователи MinGW могут ознакомиться со следующей онлайн-документацией: PostgreSQL MinGW/Native Windows.
QTDS для Sybase Adaptive Server
Примечание: TDS больше не используется MS Sql Server и заменен на ODBC. QTDS устарел начиная с Qt 4.7.
Невозможно установить порт с помощью QSqlDatabase::setPort() из-за ограничений в библиотеке клиента Sybase. Обратитесь к документации Sybase за информацией о настройке файла конфигурации клиента Sybase для подключения к базам данных на нестандартных портах.
Как скомпилировать плагин QTDS на Unix и macOS
В Unix доступны две библиотеки, поддерживающие протокол TDS:
- FreeTDS, бесплатная реализация протокола TDS (http://www.freetds.org).
- Sybase Open Client, доступен по адресу https://support.sap.com.
Независимо от используемой библиотеки, требуется общий файл объекта libsybdb.so. Установите переменную среды SYBASE для указания каталога, в котором установлена библиотека клиента, и выполните qmake:
cd $QTDIR/qtbase/src/plugins/sqldrivers qmake -- TDS_PREFIX=$SYBASE make sub-tds
Как скомпилировать плагин QDTS на Windows
Вы можете использовать библиотеку DB-Library, предоставленную Microsoft, или Sybase Open Client (https://support.sap.com). Configure попытается найти NTWDBLIB.LIB для компиляции плагина:
cd %QTDIR%\qtbase\src\plugins\sqldrivers qmake nmake sub-tds
По умолчанию на Windows используется библиотека Microsoft. Если вы хотите принудительно использовать Sybase Open Client, необходимо определить Q_USE_SYBASE в %QTDIR%\qtbase\src\plugins\sqldrivers\tds\qsql_tds.cpp.
Если вы не используете компилятор Microsoft, замените nmake на mingw32-make в строке выше.
QDB2 для IBM DB2 (Версия 7.1 и выше)
Плагин Qt DB2 позволяет получить доступ к базам данных IBM DB2. Он был протестирован с IBM DB2 v7.1 и 7.2. Вам необходимо установить клиентскую библиотеку разработки IBM DB2, которая содержит заголовочные и библиотечные файлы, необходимые для компиляции плагина QDB2.
Драйвер QDB2 поддерживает подготовленные запросы, чтение/запись строк Unicode и чтение/запись BLOB.
Рекомендуется использовать запрос forward-only при вызове хранимых процедур в DB2 (см. QSqlQuery::setForwardOnly()).
Как скомпилировать плагин QDB2 на Unix и macOS
cd $QTDIR/qtbase/src/plugins/sqldrivers qmake -- DB2_PREFIX=$DB2DIR make sub-db2
Как скомпилировать плагин QDB2 на Windows
Заголовочные и включаемые файлы DB2 должны быть установлены в правильных каталогах. Вам просто нужно скомпилировать плагин следующим образом:
cd %QTDIR%\qtbase\src\plugins\sqldrivers qmake -- "DB2_PREFIX=<DB2 home>/sqllib" nmake sub-db2
Если вы не используете компилятор Microsoft, замените nmake на mingw32-make в строке выше.
QSQLITE2 для SQLite Версия 2
Плагин Qt SQLite 2 предлагается для совместимости. В случае возможности используйте плагин версии 3 вместо него. Инструкции по сборке для версии 3 также применяются к версии 2.
QSQLITE для SQLite (Версия 3 и выше)
Плагин Qt SQLite позволяет получить доступ к базам данных SQLite. SQLite — это база данных в процессе, что означает, что вам не нужен сервер базы данных. SQLite работает с одним файлом, который должен быть установлен как имя базы данных при открытии соединения. Если файл не существует, SQLite попытается его создать. SQLite также поддерживает базу данных в памяти и временные базы данных. Просто передайте соответственно ":memory:" или пустую строку в качестве имени базы данных.
SQLite имеет некоторые ограничения по поводу нескольких пользователей и нескольких транзакций. Если вы попытаетесь читать/записывать ресурс из разных транзакций, ваше приложение может зависнуть до тех пор, пока одна транзакция не будет подтверждена или отменена. Драйвер Qt SQLite будет повторно пытаться записать в заблокированный ресурс до тех пор, пока не столкнется с таймаутом (см. QSQLITE_BUSY_TIMEOUT в QSqlDatabase::setConnectOptions()).
В SQLite любой столбец, за исключением столбца INTEGER PRIMARY KEY, может использоваться для хранения любого типа значения. Например, столбец, объявленный как INTEGER, может содержать целое число в одной строке и текстовое значение в следующей. Это связано с тем, что SQLite ассоциирует тип значения с самим значением, а не со столбцом, в котором оно хранится. Следствием этого является то, что тип, возвращаемый QSqlField::type(), указывает только рекомендуемый тип поля. Не следует делать предположений о фактическом типе, и необходимо проверять тип отдельных значений.
Драйвер заблокирован для обновлений во время выполнения запроса select. Это может вызвать проблемы при использовании QSqlTableModel, потому что виджеты Qt извлекают данные по мере необходимости (с помощью QSqlQuery::fetchMore() в случае QSqlTableModel).
Вы можете найти информацию о SQLite на http://www.sqlite.org.
Как создать плагин QSQLITE
SQLite версия 3 включена как библиотека сторонних разработчиков в Qt. Она может быть скомпилирована, передав параметр -qt-sqlite скрипту конфигурации.
Если вы не хотите использовать библиотеку SQLite, включённую в Qt, вы можете передать -system-sqlite скрипту конфигурации, чтобы использовать библиотеки SQLite операционной системы. Это рекомендуется, когда это возможно, так как это уменьшает размер установки и удаляет один компонент, за которым вам нужно отслеживать рекомендации по безопасности.
В Unix и macOS (замените $SQLITE на каталог, где находится SQLite):
cd $QTDIR/qtbase/src/plugins/sqldrivers qmake -- -system-sqlite SQLITE3_PREFIX=$SQLITE make sub-sqlite
В Windows:
cd %QTDIR%\qtbase\src\plugins\sqldrivers qmake -- -system-sqlite SQLITE3_PREFIX=C:/SQLITE nmake sub-sqlite
Включить оператор REGEXP
SQLite поставляется с операцией REGEXP. Однако необходимую реализацию должен предоставить пользователь. Для удобства можно включить реализацию по умолчанию, установив параметр подключения QSQLITE_ENABLE_REGEXP перед открытием подключения к базе данных. Тогда оператор SQL типа "column REGEXP 'pattern'" в основном расширяется до Qt-кода
column.contains(QRegularExpression("pattern")); Для повышения производительности регулярные выражения кэшируются внутри. По умолчанию размер кэша равен 25, но его можно изменить с помощью значения параметра. Например, передача "QSQLITE_ENABLE_REGEXP=10" уменьшает размер кэша до 10.
Совместимость формата файла QSQLITE
SQLite незначительные версии иногда нарушают обратную совместимость формата файлов. Например, SQLite 3.3 может читать файлы баз данных, созданные с SQLite 3.2, но базы данных, созданные с SQLite 3.3, не могут быть прочитаны SQLite 3.2. Обратитесь к документации SQLite и журналам изменений для получения информации о совместимости формата файлов между версиями.
Незначительные версии Qt обычно следуют за незначительными версиями SQLite, а незначительные версии Qt — за незначительными версиями SQLite. Исправления выпуска совместимы как в обратном, так и в прямом направлении.
Для принудительного использования SQLite определённого формата файла, необходимо создать и использовать собственный плагин базы данных со собственной библиотекой SQLite, как показано выше. Некоторые версии SQLite можно принудить к записи определённого формата файла, задав SQLITE_DEFAULT_FILE_FORMAT при компиляции SQLite.
QIBASE для Borland InterBase
Плагин Qt InterBase позволяет получить доступ к базам данных InterBase и Firebird. InterBase может использоваться как клиент-сервер или без сервера, в этом случае он работает с локальными файлами. Файл базы данных должен существовать до установления соединения.
Обратите внимание, что InterBase требует указания полного пути к файлу базы данных, независимо от того, хранится ли он локально или на другом сервере.
db.setHostName("MyServer");
db.setDatabaseName("C:\\test.gdb"); Для компиляции этого плагина вам потребуются заголовочные файлы и библиотеки InterBase/Firebird.
Из-за несовместимости лицензий с GPL пользователям Qt Open Source Edition запрещается связывать этот плагин с коммерческими версиями InterBase. Используйте Firebird или бесплатную версию InterBase.
Поддержка Юникода QIBASE и кодировка текста
По умолчанию драйвер подключается к базе данных с использованием UNICODE_FSS. Это можно переопределить, задав параметр ISC_DPB_LC_CTYPE с помощью QSqlDatabase::setConnectOptions() перед открытием соединения.
// connect to database using the Latin-1 character set
db.setConnectOptions("ISC_DPB_LC_CTYPE=Latin1");
db.open(); Если Qt не поддерживает заданную кодировку текста, драйвер выведет сообщение об ошибке и подключится к базе данных с использованием UNICODE_FSS.
Обратите внимание, что если кодировка текста, установленная при подключении к базе данных, отличается от кодировки в базе данных, могут возникнуть проблемы с транслитерацией.
QIBASE хранимые процедуры
InterBase/Firebird возвращают значения OUT в виде набора результатов, поэтому при вызове хранимой процедуры необходимо привязать только значения IN с помощью QSqlQuery::bindValue(). Значения RETURN/OUT можно получить с помощью QSqlQuery::value(). Пример:
QSqlQuery q;
q.exec("execute procedure my_procedure");
q.next();
qDebug() << q.value(0); // outputs the first RETURN/OUT value Как создать плагин QIBASE в Unix и macOS
Предполагается, что InterBase или Firebird установлены в /opt/interbase.
Если вы используете InterBase:
cd $QTDIR/qtbase/src/plugins/sqldrivers qmake -- IBASE_PREFIX=/opt/interbase make sub-ibase
Если вы используете Firebird, библиотека Firebird должна быть установлена явно:
cd $QTDIR/qtbase/src/plugins/sqldrivers qmake -- IBASE_PREFIX=/opt/interbase IBASE_LIBS=-lfbclient make sub-ibase
Как создать плагин QIBASE в Windows
Предполагается, что InterBase или Firebird установлены в C:\interbase.
Если вы используете InterBase:
cd %QTDIR%\qtbase\src\plugins\sqldrivers qmake -- IBASE_INCDIR=C:/interbase/include nmake sub-ibase
Если вы используете Firebird, библиотека Firebird должна быть установлена явно:
cd %QTDIR%\qtbase\src\plugins\sqldrivers qmake -- IBASE_INCDIR=C:/interbase/include IBASE_LIBS=-lfbclient nmake sub-ibase
Если вы не используете компилятор Microsoft, замените nmake на mingw32-make в строке выше.
Обратите внимание, что C:\interbase\bin должен находиться в PATH.
Поиск и устранение неполадок
Вы всегда должны использовать клиентские библиотеки, скомпилированные с тем же компилятором, что и ваш проект. Если вы не можете скомпилировать клиентские библиотеки самостоятельно, вы должны убедиться, что предварительно скомпилированная библиотека совместима с вашим компилятором, в противном случае у вас будут многочисленные ошибки «неопределённых символов». Некоторые компиляторы имеют инструменты для преобразования библиотек, например, Borland поставляет инструмент COFF2OMF.EXE для преобразования библиотек, сгенерированных с помощью Microsoft Visual C++.
Если компиляция плагина завершилась успешно, но он не загружается, убедитесь, что выполнены следующие требования:
- Убедитесь, что плагин находится в правильном каталоге. Вы можете использовать QApplication::libraryPaths(), чтобы определить, где Qt ищет плагины.
- Убедитесь, что клиентские библиотеки СУБД доступны в системе. В Unix выполните команду
lddи передайте имя плагина в качестве параметра, напримерldd libqsqlmysql.so. Вы получите сообщение об ошибке, если какая-либо из клиентских библиотек не найдена. В Windows вы можете использовать программу Visual Studio Dependency Walker. С помощью Qt Creator вы можете обновить переменную средыPATHв разделе **Запуск** панели **Проект**, чтобы добавить путь к папке, содержащей клиентские библиотеки. - Скомпилируйте Qt с определённым
QT_DEBUG_COMPONENTдля получения очень подробных сообщений об ошибках при загрузке плагинов.
Убедитесь, что вы выполнили руководство по развёртыванию плагинов.
Как создать собственный драйвер базы данных
QSqlDatabase отвечает за загрузку и управление плагинами драйверов баз данных. При добавлении базы данных (см. QSqlDatabase::addDatabase()), загружается соответствующий плагин драйвера (с помощью QSqlDriverPlugin). QSqlDatabase полагается на плагин драйвера для предоставления интерфейсов для QSqlDriver и QSqlResult.
QSqlDriver — это абстрактный базовый класс, который определяет функциональность драйвера базы данных SQL. Это включает функции, такие как QSqlDriver::open() и QSqlDriver::close(). QSqlDriver отвечает за подключение к базе данных, установку соответствующей среды и т. д. Кроме того, QSqlDriver может создавать объекты QSqlQuery, подходящие для конкретного API базы данных. QSqlDatabase перенаправляет многие вызовы функций напрямую в QSqlDriver, который предоставляет конкретную реализацию.
QSqlResult — это абстрактный базовый класс, который определяет функциональность запроса базы данных SQL. Это включает в себя такие операторы, как SELECT, UPDATE, и ALTER TABLE. QSqlResult содержит функции, такие как QSqlResult::next() и QSqlResult::value(). QSqlResult отвечает за отправку запросов в базу данных, возвращение данных результата и т. д. QSqlQuery перенаправляет многие вызовы функций напрямую в QSqlResult, который предоставляет конкретную реализацию.
QSqlDriver и QSqlResult тесно связаны. При реализации драйвера Qt SQL необходимо наследоваться от обоих классов, и нужно реализовать все абстрактные виртуальные методы каждого класса.
Для реализации плагина драйвера Qt SQL (чтобы он был распознан и загружен библиотекой Qt во время выполнения), необходимо использовать макрос Q_PLUGIN_METADATA(). Подробнее об этом см. Как создать плагины Qt. Вы также можете посмотреть, как это сделано в плагинах SQL, поставляемых с Qt в QTDIR/qtbase/src/plugins/sqldrivers.
Следующий код может использоваться в качестве шаблона для драйвера SQL:
class XyzResult : public QSqlResult
{
public:
XyzResult(const QSqlDriver *driver)
: QSqlResult(driver) {}
~XyzResult() {}
protected:
QVariant data(int /* index */) override { return QVariant(); }
bool isNull(int /* index */) override { return false; }
bool reset(const QString & /* query */) override { return false; }
bool fetch(int /* index */) override { return false; }
bool fetchFirst() override { return false; }
bool fetchLast() override { return false; }
int size() override { return 0; }
int numRowsAffected() override { return 0; }
QSqlRecord record() const override { return QSqlRecord(); }
};
class XyzDriver : public QSqlDriver
{
public:
XyzDriver() {}
~XyzDriver() {}
bool hasFeature(DriverFeature /* feature */) const override { return false; }
bool open(const QString & /* db */, const QString & /* user */,
const QString & /* password */, const QString & /* host */,
int /* port */, const QString & /* options */) override
{ return false; }
void close() {}
QSqlResult *createResult() const override { return new XyzResult(this); }
};
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-5.12/sql-driver.html