Драйверы баз данных SQL
Модуль Qt SQL использует драйверы плагины для связи с различными API баз данных. Поскольку API модуля SQL Qt независим от базы данных, весь код, специфичный для базы данных, содержится в этих драйверах. Qt поставляется с несколькими драйверами, и можно добавить другие. Исходный код драйвера предоставляется и может использоваться в качестве модели для создания собственных драйверов.
Поддерживаемые базы данных
В таблице ниже перечислены драйверы, включенные в Qt:
| Имя драйвера | DBMS |
|---|---|
| QDB2 | IBM DB2 (версия 7.1 и выше) |
| QIBASE | Borland InterBase |
| QMYSQL | MySQL (версия 5.0 и выше) |
| QOCI | Драйвер Oracle Call Interface |
| QODBC | Open Database Connectivity (ODBC) — Microsoft SQL Server и другие базы данных, совместимые с ODBC |
| QPSQL | PostgreSQL (версии 7.3 и выше) |
| QSQLITE2 |
SQLite версия 2 Примечание: устарел начиная с Qt 5.14 |
| QSQLITE | SQLite версия 3 |
| QTDS | Sybase Adaptive Server Примечание: устарел начиная с Qt 4.7 |
SQLite — это системная база данных в процессе выполнения с наилучшим покрытием тестов и поддержкой на всех платформах. Oracle через OCI, PostgreSQL и MySQL через ODBC или родной драйвер хорошо протестированы на Windows и Linux. Полнота поддержки других систем зависит от доступности и качества клиентских библиотек.
Примечание: для построения плагина драйвера необходимо иметь соответствующую клиентскую библиотеку для вашей системы управления базами данных (DBMS). Это обеспечивает доступ к API, предоставляемому DBMS, и обычно поставляется с ней. Большинство программ установки также позволяют установить «библиотеки разработки», и именно они вам нужны. Эти библиотеки отвечают за низкоуровневое взаимодействие с DBMS. Также убедитесь, что установлены правильные библиотеки базы данных для вашей архитектуры Qt (32 или 64 бита).
Примечание: при использовании 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:/Program Files/MySQL/MySQL Connector C 6.1 в Windows), передайте следующую параметр в конфигурацию: MYSQL_PREFIX=/usr/local/mysql (или MYSQL_PREFIX="C:/Program Files/MySQL/MySQL Connector C 6.1" для Windows). Подробности для каждого драйвера описаны ниже.
Если что-то пойдет не так, и вы хотите, чтобы qmake повторно проверил доступные драйверы, удалите config.cache в <QTDIR>/qtbase/src/plugins/sqldrivers — в противном случае qmake не будет искать доступные драйверы снова. Если у вас возникла ошибка на этапе qmake, откройте config.log, чтобы увидеть, что пошло не так.
Типичный запуск qmake (в данном случае для конфигурации MySQL) выглядит так:
C:\Qt5\5.13.2\Src\qtbase\src\plugins\sqldrivers>qmake -version
QMake version 3.1
Using Qt version 5.13.2 in C:/Qt5/5.13.2/mingw73_64/lib
C:\Qt5\5.13.2\Src\qtbase\src\plugins\sqldrivers>qmake -- MYSQL_INCDIR="C:/Program Files/MySQL/MySQL Connector C 6.1/include" MYSQL_LIBDIR="C:/Program Files/MySQL/MySQL Connector C 6.1/lib"
Info: creating stash file C:\Qt5\5.13.2\Src\qtbase\src\plugins\sqldrivers\.qmake.stash
Running configuration tests...
Checking for DB2 (IBM)... no
Checking for InterBase... no
Checking for MySQL... yes
Checking for OCI (Oracle)... no
Checking for ODBC... yes
Checking for PostgreSQL... no
Checking for SQLite (version 2)... no
Checking for TDS (Sybase)... no
Done running configuration tests.
Configure summary:
Qt Sql Drivers:
DB2 (IBM) .............................. no
InterBase .............................. no
MySql .................................. yes
OCI (Oracle) ........................... no
ODBC ................................... yes
PostgreSQL ............................. no
SQLite2 ................................ no
SQLite ................................. yes
Using system provided SQLite ......... no
TDS (Sybase) ........................... no
Qt is now configured for building. Just run 'mingw32-make'.
Once everything is built, you must run 'mingw32-make install'.
Qt will be installed into 'C:\Qt5\5.13.2\mingw73_64'.
Prior to reconfiguration, make sure you remove any leftovers from the previous build. Из-за практических соображений, связанных с внешними зависимостями, только плагин SQLite3 поставляется с бинарными сборками Qt. Чтобы иметь возможность добавлять дополнительные драйверы в установку Qt без перекомпиляции всего Qt, можно настроить и скомпилировать директорию qtbase/src/plugins/sqldrivers вне директории полной сборки Qt. Обратите внимание, что нельзя настраивать каждый драйвер отдельно, только все сразу. Однако драйверы можно компилировать отдельно. Если сборка Qt настроена с -prefix, необходимо установить плагины после их компиляции. Например:
cd $QTDIR/qtbase/src/plugins/sqldrivers/mysql make install
Подробности драйверов
QMYSQL для MySQL 5 и выше
Поддержка хранимых процедур 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, встроенная библиотека сервера MySQL».
Как скомпилировать плагин 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 (например, mysql-installer-web-community-8.0.18.0.msi). Запустите установщик, выберите «Пользовательская» установка и установите MySQL C Connector, соответствующий вашей установке Qt (x86 или x64). После установки проверьте наличие необходимых файлов:
<MySQL dir>/lib/libmysql.lib<MySQL dir>/lib/libmysql.dll<MySQL dir>/include/mysql.h
Примечание: начиная с MySQL 8.0.19, C Connector больше не предлагается как автономный устанавливаемый компонент. Вместо этого вы можете получить mysql.h и libmysql.*, установив полный сервер MySQL (только x64) или MariaDB C Connector.
Скомпилируйте плагин следующим образом (здесь предполагается, что <MySQL dir> это C:/Program Files/MySQL/MySQL Connector C 6.1):
cd %QTDIR%\qtbase\src\plugins\sqldrivers qmake -- MYSQL_INCDIR="C:/Program Files/MySQL/MySQL Connector C 6.1/include" MYSQL_LIBDIR="C:/Program Files/MySQL/MySQL Connector C 6.1/lib" nmake sub-mysql nmake install
Если вы не используете компилятор Microsoft, замените nmake на mingw32-make выше.
При распространении вашего приложения не забудьте включить libmysql.dll в ваш установочный пакет. Он должен быть помещен в ту же папку, что и исполняемый файл приложения. libmysql.dll дополнительно требует библиотеки времени выполнения MSVC, которые можно установить с помощью vcredist.exe
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) могут быть считываются и записываются, но имейте в виду, что этот процесс может потребовать большого объёма памяти. Вы должны использовать запросы с forward-only для выбора полей 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 при компиляции плагина SQL OCI и при запуске приложения, использующего плагин SQL OCI. Вы можете избежать этой необходимости, установив 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 для открытой базы данных (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.
Для 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.
Регистрозависимость QPSQL
Базы данных PostgreSQL будут учитывать регистр только если имя таблицы или поля заключено в кавычки при создании таблицы. Например, SQL-запрос:
CREATE TABLE "testTable" ("id" INTEGER); обеспечит доступ к таблице с тем же регистром, который использовался при создании. Если имя таблицы или поля не заключено в кавычки при создании, фактическое имя таблицы или поля будет в нижнем регистре. Когда QSqlDatabase::record() или QSqlDatabase::primaryIndex() обращаются к таблице или полю, которые не были заключены в кавычки при создании, имя, переданное функции, должно быть в нижнем регистре, чтобы оно было найдено. Например:
QString tableString("testTable");
QSqlQuery q;
// Create table query is not quoted, therefore it is mapped to lower case
q.exec(QString("CREATE TABLE %1 (id INTEGER)").arg(tableString));
// Call toLower() on the string so that it can be matched
QSqlRecord rec = database.record(tableString.toLower()); Поддержка запросов в режиме 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 nmake install
Пользователям MinGW может быть полезен следующий онлайн-документ: PostgreSQL MinGW/Native Windows.
При распространении вашего приложения не забудьте включить libpq.dll в пакет установки. Он должен быть помещен в ту же папку, что и исполняемый файл приложения.
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 nmake install
По умолчанию на 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-данных.
Рекомендуется использовать запросы только для чтения при вызове хранимых процедур в 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 nmake install
Если вы не используете компилятор 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 nmake install
Включение оператора REGEXP
SQLite поставляется с операцией REGEXP. Однако необходимую реализацию должен предоставить пользователь. Для удобства можно включить реализацию по умолчанию, установив параметр подключения QSQLITE_ENABLE_REGEXP перед открытием подключения к базе данных. Затем SQL-запрос типа "столбец REGEXP 'шаблон'" по сути расширяется до кода 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 может использоваться как клиент/сервер или без сервера, в этом случае он работает с локальными файлами. Файл базы данных должен существовать перед установлением соединения. Firebird должен использоваться с конфигурацией сервера.
Обратите внимание, что 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 nmake install
Если вы используете Firebird, библиотека Firebird должна быть установлена явно:
cd %QTDIR%\qtbase\src\plugins\sqldrivers qmake -- IBASE_INCDIR=C:/interbase/include IBASE_LIBS=-lfbclient nmake sub-ibase nmake install
Если вы не используете компилятор 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.14/sql-driver.html