Драйверы баз данных SQL
Модуль Qt SQL использует драйверы плагины для связи с различными API баз данных. Поскольку API модуля Qt SQL независим от базы данных, весь код, специфичный для базы данных, содержится в этих драйверах. В Qt поставляется несколько драйверов, и можно добавлять другие. Исходный код драйвера поставляется и может быть использован в качестве модели для создания собственных драйверов.
Поддерживаемые базы данных
В таблице ниже перечислены драйверы, включенные в Qt:
| Имя драйвера | DBMS |
|---|---|
| QDB2 | IBM DB2 (версия 7.1 и выше) |
| QMYSQL / MARIADB | MySQL или MariaDB (версия 5.6 и выше) |
| QOCI | Драйвер Oracle Call Interface (версия 12.1 и выше) |
| QODBC | Open Database Connectivity (ODBC) — Microsoft SQL Server и другие базы данных, совместимые с ODBC |
| QPSQL | PostgreSQL (версии 7.3 и выше) |
| QSQLITE | SQLite версия 3 |
SQLite — это системa баз данных, выполняемая в процессе, с лучшим покрытием тестами и поддержкой на всех платформах. Oracle через OCI, PostgreSQL и MySQL через ODBC или родной драйвер хорошо протестированы на Windows и Linux. Полная поддержка других систем зависит от наличия и качества клиентских библиотек.
Примечание: Для построения плагина драйвера вам нужна соответствующая клиентская библиотека для вашей системы управления базами данных (DBMS). Она обеспечивает доступ к API, предоставляемому DBMS, и обычно поставляется вместе с ней. Большинство установочных программ также позволяют установить «библиотеки разработки», и именно они вам нужны. Эти библиотеки отвечают за низкоуровневое взаимодействие с DBMS. Также убедитесь, что установлены правильные библиотеки базы данных для вашей архитектуры Qt (32 или 64 бита).
Примечание: При использовании Qt в рамках лицензий с открытым исходным кодом, но с проприетарной базой данных, проверьте совместимость лицензии клиентской библиотеки с LGPL.
Компиляция драйверов
Компиляция Qt с определённым драйвером
Скрипт Qt configure пытается автоматически определить доступные клиентские библиотеки на вашем компьютере. Запустите configure -help для просмотра информации о компилируемых драйверах. Должен быть выведен результат, похожий на этот:
[...]
Database options:
-sql-<driver> ........ Enable SQL <driver> plugin. Supported drivers:
db2 ibase mysql oci odbc psql sqlite
[all auto]
-sqlite .............. Select used sqlite [system/qt]
[...] Скрипт configure не может обнаружить необходимые библиотеки и файлы заголовков, если они не находятся в стандартных путях, поэтому может потребоваться указать эти пути, используя либо переменные путей включения и библиотек, специфичные для драйвера, либо CMAKE_INCLUDE_PATH и CMAKE_LIBRARY_PATH. Например, если ваши файлы MySQL установлены в C:\mysql-connector-c-6.1.11-winx64 на Windows, то передайте указанный параметр в часть configure команды:
C:\Qt\6.0.0\Src\configure.bat -sql-mysql -- -DMySQL_INCLUDE_DIR="C:\mysql-8.0.22-winx64\include" -DMySQL_LIBRARY="C:\mysql-8.0.22-winx64\lib\libmysql.lib"
Configure summary:
...
Qt Sql Drivers:
DB2 (IBM) .............................. no
InterBase .............................. no
MySql .................................. yes
OCI (Oracle) ........................... no
ODBC ................................... yes
PostgreSQL ............................. no
SQLite ................................. yes
Using system provided SQLite ......... no
... Когда вы настраиваете драйверы описанным выше способом, CMake пропускает проверки зависимостей и использует предоставленные пути как есть. Это особенно полезно, если пакет предоставляет свой собственный набор системных библиотек, которые не должны распознаваться процедурой построения.
В некоторых случаях удобнее использовать переменные CMAKE_INCLUDE_PATH и CMAKE_LIBRARY_PATH для поиска необходимых библиотек. Этот метод следует предпочесть, если модулю нужно установить свойства для предоставленных целевых библиотек (например, это необходимо для PostgreSQL и SQLite). Например, так можно найти MySQL:
C:\Qt\6.0.0\Src\configure.bat -sql-mysql -- -DCMAKE_INCLUDE_PATH="C:\mysql-8.0.22-winx64\include" -DCMAKE_LIBRARY_PATH="C:\mysql-8.0.22-winx64\lib"
Configure summary:
...
Qt Sql Drivers:
DB2 (IBM) .............................. no
InterBase .............................. no
MySql .................................. yes
OCI (Oracle) ........................... no
ODBC ................................... yes
PostgreSQL ............................. no
SQLite ................................. yes
Using system provided SQLite ......... no
... Подробности для каждого драйвера описаны ниже.
Примечание: Если что-то пойдёт не так, и вы хотите, чтобы CMake снова проверил доступные драйверы, вам может потребоваться удалить файл CMakeCache.txt из каталога сборки.
Компиляция только определенного драйвера SQL
Типичный запуск qt-cmake (в данном случае для настройки MySQL) выглядит так:
C:\Qt\6.0.0\mingw81_64\bin\qt-cmake -G"Ninja" C:\Qt\6.0.0\Src\qtbase\src\plugins\sqldrivers -DMySQL_INCLUDE_DIR="C:\mysql-8.0.22-winx64\include" -DMySQL_LIBRARY="C:\mysql-8.0.22-winx64\lib\libmysql.lib" -DCMAKE_INSTALL_PREFIX="C:\Qt\6.0.0\mingw81_64"
Configure summary:
Qt Sql Drivers:
DB2 (IBM) .............................. no
InterBase .............................. no
MySql .................................. yes
OCI (Oracle) ........................... no
ODBC ................................... yes
PostgreSQL ............................. no
SQLite ................................. yes
Using system provided SQLite ......... no
-- Configuring done
-- Generating done
-- Build files have been written to: C:/build-qt6-sqldrivers Примечание: Как указано в Компиляция Qt с определенным драйвером, если драйвер не найден или не включен, начните заново, удалив CMakeCache.txt.
Из-за практических аспектов работы с внешними зависимостями, только плагин SQLite поставляется с двоичными сборками Qt. Двоичные сборки Qt для Windows также включают плагин ODBC. Чтобы добавить дополнительные драйверы в установку Qt без пересборки всего Qt, можно настроить и скомпилировать каталог qtbase/src/plugins/sqldrivers вне каталога полной сборки Qt. Обратите внимание, что настроить каждый драйвер по отдельности нельзя, только все сразу. Однако, драйверы можно скомпилировать по отдельности.
Примечание: Вам нужно указать CMAKE_INSTALL_PREFIX, если вы хотите установить плагины после завершения сборки.
Справочная информация по драйверам
QMYSQL для MySQL или MariaDB 5.6 и выше
MariaDB — это вилка MySQL, предназначенная для сохранения статуса свободной и открытой программного обеспечения под лицензией GNU General Public License. MariaDB стремится сохранить высокую совместимость с MySQL, обеспечивая возможность прямого замещения с бинарной эквивалентностью библиотек и точным соответствием API и командам MySQL. Поэтому плагин для MySQL и MariaDB объединены в один плагин Qt.
Поддержка хранимых процедур 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");
if (q.next())
qDebug() << q.value(0) << q.value(1); // outputs "42" and "43" Примечание: @outval1 и @outval2 — переменные, локальные для текущего соединения, и не будут затронуты запросами, отправленными с другого хоста или соединения.
Встроенный сервер MySQL
Встроенный сервер MySQL — это прямое замещение обычной клиентской библиотеки. С встроенным сервером MySQL для использования функциональности MySQL не требуется сервер MySQL.
Для использования встроенного сервера MySQL, просто свяжите плагин Qt с libmysqld вместо libmysqlclient. Это можно сделать, добавив -DMySQL_LIBRARY=<path/to/mysqld/>libmysqld.<so|lib|dylib> в командную строку конфигурации.
Для получения дополнительной информации об встроенном сервере MySQL обратитесь к документации MySQL, раздел «libmysqld, библиотека встроенного сервера MySQL».
Как скомпилировать плагин QMYSQL на Unix и macOS
Вам понадобятся заголовочные файлы MySQL/MariaDB, а также общая библиотека libmysqlclient.<so|dylib> / libmariadb.<so|dylib>. В зависимости от вашей дистрибуции Linux, вам может потребоваться установить пакет, который обычно называется «mysql-devel» или «mariadb-devel».
Укажите qt-cmake местоположение заголовочных файлов и общих библиотек MySQL/MariaDB (здесь предполагается, что MySQL/MariaDB установлен в /usr/local) и выполните компиляцию:
mkdir build-sqldrivers cd build-sqldrivers qt-cmake -G"Ninja" <qt_installation_path>/Src/qtbase/src/plugins/sqldrivers -DCMAKE_INSTALL_PREFIX=<qt_installation_path>/<platform> -DMySQL_INCLUDE_DIR="/usr/local/mysql/include" -DMySQL_LIBRARY="/usr/local/mysql/lib/libmysqlclient.<so|dylib>" qt-cmake --build . qt-cmake --install
Как скомпилировать плагин QMYSQL на Windows
Вам нужны файлы установки MySQL (например, mysql-installer-web-community-8.0.22.0.msi или mariadb-connector-c-3.1.11-win64.msi). Запустите установщик, выберите пользовательскую установку и установите MySQL C Connector, соответствующий вашей установке Qt (x86 или x64). После установки проверьте наличие необходимых файлов:
<MySQL dir>/lib/libmysql.lib<MySQL dir>/lib/libmysql.dll<MySQL dir>/include/mysql.h
и для MariaDB
<MariaDB dir>/lib/libmariadb.lib<MariaDB dir>/lib/libmariadb.dll<MariaDB dir>/include/mysql.h
Примечание: Начиная с MySQL 8.0.19, C Connector больше не предлагается как автономный устанавливаемый компонент. Вместо этого, вы можете получить mysql.h и libmysql.* путем установки полных MySQL Server (только x64) или MariaDB C Connector.
Скомпилируйте плагин следующим образом (здесь предполагается, что <MySQL dir> это C:\mysql-8.0.22-winx64):
mkdir build-sqldrivers cd build-sqldrivers qt-cmake -G"Ninja" <qt_installation_path>\Src\qtbase\src\plugins\sqldrivers -DCMAKE_INSTALL_PREFIX=<qt_installation_path>\<platform> -DMySQL_INCLUDE_DIR="C:\mysql-8.0.22-winx64\include" -DMySQL_LIBRARY="C:\mysql-8.0.22-winx64\lib\libmysql.lib" qt-cmake --build . qt-cmake --install
При распространении вашего приложения, не забудьте включить libmysql.dll/libmariadb.dll в ваш установочный пакет. Он должен быть размещен в той же папке, что и исполняемый файл приложения. libmysql.dll дополнительно требует библиотеки времени выполнения MSVC, которые можно установить с помощью vcredist.exe
QOCI для Oracle Call Interface (OCI)
Плагин Qt OCI поддерживает подключение к базе данных Oracle, как определено используемой версией instant client. Это зависит от того, какую версию поддерживает Oracle. Плагин автоматически определит версию базы данных и включит соответствующие функции.
Возможна работа с базой данных Oracle без файла tnsnames.ora. Это требует, чтобы SID базы данных передавался драйверу в качестве имени базы данных, и указывался хост.
Аутентификация пользователя OCI
Плагин Qt OCI поддерживает аутентификацию с использованием внешних учетных данных (OCI_CRED_EXT). Обычно это означает, что сервер базы данных будет использовать аутентификацию пользователя, предоставленную операционной системой, вместо собственного механизма аутентификации.
Оставьте имя пользователя и пароль пустыми при открытии соединения с QSqlDatabase, чтобы использовать аутентификацию с внешними учетными данными.
Поддержка OCI BLOB/LOB
Двоичные большие объекты (BLOB) могут быть читаемы и записываемы, но имейте в виду, что этот процесс может потребовать большого объёма памяти. Для выбора полей LOB следует использовать запросы с forward-only (см. QSqlQuery::setForwardOnly()).
Вставка BLOB должна выполняться с помощью подготовленного запроса, где BLOB привязаны к заглушкам, или с помощью QSqlTableModel, который внутренне использует подготовленный запрос для этого.
Как скомпилировать плагин OCI на Unix и macOS
Вам понадобятся пакеты " - Basic" и "Instant Client Package - SDK".
Файлы библиотек Oracle, необходимые для компиляции драйвера:
-
libclntsh.<so|dylib>(все версии)
Укажите qt-cmake местоположение заголовочных файлов и общих библиотек Oracle и выполните сборку.
Предполагается, что вы установили пакеты RPM для Instant Client Package SDK (вам необходимо скорректировать номер версии соответственно):
mkdir build-sqldrivers cd build-sqldrivers qt-cmake -G"Ninja" <qt_installation_path>/Src/qtbase/src/plugins/sqldrivers -DCMAKE_INSTALL_PREFIX=<qt_installation_path>/<platform> -DOracle_INCLUDE_DIR="/usr/include/oracle/21/client64" -DOracle_LIBRARY="/usr/lib/oracle/21/client64/lib/libclntsh.<so|dylib>" qt-cmake --build . qt-cmake --install
Примечание: Если вы используете пакет Oracle Instant Client, вам потребуется установить LD_LIBRARY_PATH при компиляции плагина SQL OCI и при запуске приложения, использующего плагин SQL OCI.
Как скомпилировать плагин OCI на Windows
Выбор опции «Программист» в установщике Oracle Client с компакт-диска Oracle Client Installation обычно достаточно для построения плагина. Для некоторых версий Oracle Client, возможно, также потребуется выбрать опцию «Интерфейс вызовов (OCI)», если она доступна.
Соберите плагин следующим образом (здесь предполагается, что Oracle Client установлен в C:\oracle и SDK установлен в C:\oracle\sdk):
mkdir build-sqldrivers cd build-sqldrivers qt-cmake -G"Ninja" <qt_installation_path>\Src\qtbase\src\plugins\sqldrivers -DCMAKE_INSTALL_PREFIX=<qt_installation_path>\<platform> -DOracle_INCLUDE_DIR="C:\oracle\sdk\include" -DOracle_LIBRARY="C:\oracle\oci.lib" qt-cmake --build . qt-cmake --install
При запуске вашего приложения вам также потребуется добавить oci.lib путь к вашей переменной окружения PATH:
set PATH=%PATH%;C:\oracle
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. Некоторые драйверы 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("QODBC");
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 хранимой процедуры, отбрасывается.
Поддержка ODBC Unicode
Плагин 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.
Укажите qt-cmake местоположение заголовочных файлов и общих библиотек unixODBC (здесь предполагается, что unixODBC установлен в /usr/local/unixODBC), и выполните сборку:
mkdir build-sqldrivers cd build-sqldrivers qt-cmake -G"Ninja" <qt_installation_path>/Src/qtbase/src/plugins/sqldrivers -DCMAKE_INSTALL_PREFIX=<qt_installation_path>/<platform> -DODBC_INCLUDE_DIR="/usr/local/unixODBC/include" -DODBC_LIBRARY="/usr/local/unixODBC/lib/libodbc.<so|dylib>" qt-cmake --build . qt-cmake --install
Как собрать плагин ODBC в Windows
Заголовочные и включаемые файлы ODBC должны быть уже установлены в нужных каталогах. Вам просто нужно собрать плагин следующим образом:
mkdir build-sqldrivers cd build-sqldrivers qt-cmake -G"Ninja" <qt_installation_path>\Src\qtbase\src\plugins\sqldrivers -DCMAKE_INSTALL_PREFIX=<qt_installation_path>\<platform> qt-cmake --build . qt-cmake --install
QPSQL для PostgreSQL (версия 7.3 и выше)
Драйвер QPSQL поддерживает версии PostgreSQL сервера 7.3 и выше.
Для получения дополнительной информации о PostgreSQL посетите http://www.postgresql.org.
Поддержка QPSQL Unicode
Драйвер 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()); Поддержка запросов QPSQL в режиме forward-only
Для использования запросов в режиме forward-only необходимо скомпилировать плагин QPSQL с библиотекой клиента PostreSQL версии 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 QMARIADB QODBC QPSQL Could not create database object
При просмотре результатов в режиме forward-only дескриптор QSqlResult может измениться. Приложения, использующие низкоуровневый дескриптор SQL-результата, должны получать новый дескриптор после каждого вызова функций извлечения QSqlResult. Пример:
QSqlQuery query;
QVariant v;
query.setForwardOnly(true);
query.exec("SELECT * FROM table");
while (query.next()) {
// Handle changes in every iteration of the loop
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;
query1.setForwardOnly(true);
query1.exec("select * FROM table1");
while (query1.next()) {
value = query1.value(0).toInt();
if (value == 1) {
QSqlQuery query2;
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.
Для того, чтобы qt-cmake нашел заголовочные файлы и общие библиотеки PostgreSQL, выполните сборку плагина следующим образом (предполагается, что клиент PostgreSQL установлен в /usr/local/pgsql):
mkdir build-psql-driver cd build-psql-driver qt-cmake -G"Ninja" <qt_installation_path>/Src/qtbase/src/plugins/sqldrivers-DCMAKE_INSTALL_PREFIX=<qt_installation_path>/<platform> -DCMAKE_INCLUDE_PATH="/usr/local/pgsql/include" -DCMAKE_LIBRARY_PATH="/usr/local/pgsql/lib" qt-cmake --build . qt-cmake --install
Как собрать плагин QPSQL в Windows
Установите соответствующие библиотеки разработчика PostgreSQL для вашего компилятора. Предполагая, что PostgreSQL был установлен в C:\pgsql, выполните сборку плагина следующим образом:
mkdir build-sqldrivers cd build-sqldrivers qt-cmake -G"Ninja" <qt_installation_path>\Src\qtbase\src\plugins\sqldrivers -DCMAKE_INSTALL_PREFIX=<qt_installation_path>\<platform> -DCMAKE_INCLUDE_PATH="C:\pgsql\include" -DCMAKE_LIBRARY_PATH="C:\pgsql\lib" qt-cmake --build . qt-cmake --install
Пользователи MinGW могут ознакомиться со следующим онлайн-документом: PostgreSQL MinGW/Native Windows.
При распространении вашего приложения не забудьте включить libpq.dll в ваш установочный пакет. Он должен быть помещен в ту же папку, что и исполняемый файл приложения.
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
mkdir build-sqldrivers cd build-sqldrivers qt-cmake -G"Ninja" <qt_installation_path>/Src/qtbase/src/plugins/sqldrivers -DCMAKE_INSTALL_PREFIX=<qt_installation_path>/<platform> -DDB2_INCLUDE_DIR="/usr/local/db2/include" -DDB2_LIBRARY="/usr/local/db2/lib/libdb2.<so|dylib>" qt-cmake --build . qt-cmake --install
Как собрать плагин QDB2 в Windows
Файлы заголовков и включаемые файлы DB2 должны быть уже установлены в соответствующих каталогах. Вам просто нужно собрать плагин следующим образом:
mkdir build-sqldrivers cd build-sqldrivers qt-cmake -G"Ninja" <qt_installation_path>\Src\qtbase\src\plugins\sqldrivers -DCMAKE_INSTALL_PREFIX=<qt_installation_path>\<platform> -DDB2_INCLUDE_DIR="C:\db2\include" -DDB2_LIBRARY="C:\db2\lib\db2.lib" qt-cmake --build . qt-cmake --install
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 в качестве сторонней библиотеки. Его можно скомпилировать, передав параметр -DFEATURE_system_sqlite=OFF в командную строку qt-cmake.
Если вы не хотите использовать библиотеку SQLite, включённую в Qt, вы можете передать -DFEATURE_system_sqlite=ON в командную строку qt-cmake, чтобы использовать библиотеки SQLite операционной системы. Это рекомендуется всякий раз, когда это возможно, так как это уменьшает размер установки и удаляет один компонент, для которого вам нужно отслеживать рекомендации по безопасности.
В Unix и macOS (замените $SQLITE на каталог, где находится SQLite):
mkdir build-sqldrivers cd build-sqldrivers qt-cmake -G"Ninja" <qt_installation_path>/Src/qtbase/src/plugins/sqldrivers -DCMAKE_INSTALL_PREFIX=<qt_installation_path>/<platform> -DFEATURE_system_sqlite=ON -DCMAKE_INCLUDE_PATH="$SQLITE/include" -DCMAKE_LIBRARY_PATH="$SQLITE/lib" qt-cmake --build . qt-cmake --install
В Windows (предполагая, что SQLite установлен в C:\SQLITE):
mkdir build-sqldrivers cd build-sqldrivers qt-cmake -G"Ninja" <qt_installation_path>\Src\qtbase\src\plugins\sqldrivers -DCMAKE_INSTALL_PREFIX=<qt_installation_path>\<platform> -DFEATURE_system_sqlite=ON -DCMAKE_INCLUDE_PATH="C:\SQLITE\include" -DCMAKE_LIBRARY_PATH="C:\SQLITE\lib" qt-cmake --build . qt-cmake --install
Включить оператор 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_DEFAULT_FILE_FORMAT при компиляции SQLite.
QIBASE для Borland InterBase
Плагин Qt InterBase позволяет получить доступ к базам данных InterBase и Firebird. InterBase может использоваться как клиент-сервер или без сервера, в этом случае он работает с локальными файлами. Файл базы данных должен существовать перед установлением подключения. Firebird должен использоваться с конфигурацией сервера.
Обратите внимание, что InterBase требует указать полный путь к файлу базы данных, независимо от того, хранится ли он локально или на другом сервере.
QSqlDatabase db;
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");
if (db.open())
qDebug("The database connection is open."); Если Qt не поддерживает заданную кодировку текста, драйвер выведет сообщение об ошибке и подключится к базе данных с использованием UNICODE_FSS.
Обратите внимание, что если кодировка текста, установленная при подключении к базе данных, не совпадает с кодировкой в базе данных, могут возникнуть проблемы с транслитерацией.
Хранимые процедуры QIBASE
InterBase/Firebird возвращают значения OUT в виде набора результатов, поэтому при вызове хранимой процедуры необходимо привязывать только значения IN через QSqlQuery::bindValue(). Значения RETURN/OUT можно получить с помощью QSqlQuery::value(). Пример:
QSqlQuery q;
q.exec("execute procedure my_procedure");
if (q.next())
qDebug() << q.value(0); // outputs the first RETURN/OUT value Как скомпилировать плагин QIBASE в Unix и macOS
Ниже предполагается, что InterBase или Firebird установлены в /opt/interbase:
Если вы используете InterBase:
mkdir build-sqldrivers cd build-sqldrivers qt-cmake -G"Ninja" <qt_installation_path>/Src/qtbase/src/plugins/sqldrivers -DCMAKE_INSTALL_PREFIX=<qt_installation_path>/<platform> -DInterbase_INCLUDE_DIR="/opt/interbase/include" -DInterbase_LIBRARY="/opt/interbase/lib/libgds.<so|dylib>" qt-cmake --build . qt-cmake --install
Если вы используете Firebird, библиотеку Firebird необходимо явно указать:
mkdir build-sqldrivers cd build-sqldrivers qt-cmake -G"Ninja" <qt_installation_path>/Src/qtbase/src/plugins/sqldrivers -DCMAKE_INSTALL_PREFIX=<qt_installation_path>/<platform> -DInterbase_INCLUDE_DIR="/opt/interbase/include" -DInterbase_LIBRARY="/opt/interbase/lib/libfbclient.<so|dylib>" qt-cmake --build . qt-cmake --install
Как скомпилировать плагин QIBASE в Windows
Ниже предполагается, что InterBase или Firebird установлены в C:\interbase:
Если вы используете InterBase:
mkdir build-sqldrivers cd build-sqldrivers qt-cmake -G"Ninja" <qt_installation_path>\Src\qtbase\src\plugins\sqldrivers -DCMAKE_INSTALL_PREFIX=<qt_installation_path>\<platform> -DInterbase_INCLUDE_DIR="C:\interbase\include" -DInterbase_LIBRARY="C:\interbase\gds.lib" qt-cmake --build . qt-cmake --install
Если вы используете Firebird:
mkdir build-sqldrivers cd build-sqldrivers qt-cmake -G"Ninja" <qt_installation_path>\Src\qtbase\src\plugins\sqldrivers -DCMAKE_INSTALL_PREFIX=<qt_installation_path>\<platform> -DInterbase_INCLUDE_DIR="C:\interbase\include" -DInterbase_LIBRARY="C:\interbase\lib\fbclient_ms.lib" qt-cmake --build . qt-cmake --install
Обратите внимание, что C:\interbase\bin должен находиться в PATH.
Отладка
Вы всегда должны использовать клиентские библиотеки, скомпилированные тем же компилятором, что и ваш проект. Если вы не можете получить исходное распространение для самостоятельной компиляции клиентских библиотек, вы должны убедиться, что предварительно скомпилированная библиотека совместима с вашим компилятором, в противном случае у вас будет много ошибок «неопределенных символов». Некоторые компиляторы имеют инструменты для преобразования библиотек, например, Borland поставляет инструмент COFF2OMF.EXE для преобразования библиотек, сгенерированных с помощью Microsoft Visual C++.
Если компиляция плагина завершается успешно, но его нельзя загрузить, убедитесь, что выполнены следующие требования:
- Убедитесь, что плагин находится в правильном каталоге. Вы можете использовать QApplication::libraryPaths() для определения того, где Qt ищет плагины.
- Убедитесь, что клиентские библиотеки СУБД доступны в системе. В Unix выполните команду
lddи передайте имя плагина в качестве параметра, напримерldd libqsqlmysql.so. Вы получите сообщение об ошибке, если какая-либо из клиентских библиотек не найдена. В Windows вы можете использовать средство отладки зависимостей Visual Studio. В Qt Creator вы можете обновить переменную средыPATHв разделе «Запуск» панели «Проект», чтобы включить путь к папке, содержащей клиентские библиотеки. - Скомпилируйте Qt с определением
QT_DEBUG_COMPONENTдля получения очень подробного отладочного вывода при загрузке плагинов.
Убедитесь, что вы выполнили руководство по развёртыванию плагинов.
Как написать свой собственный драйвер базы данных
QSqlDatabase отвечает за загрузку и управление плагинами драйверов баз данных. При добавлении базы данных (см. QSqlDatabase::addDatabase()), соответствующий плагин драйвера загружается (с использованием QSqlDriverPlugin). QSqlDatabase полагается на плагин драйвера для предоставления интерфейсов для QSqlDriver и QSqlResult.
QSqlDriver — это абстрактный базовый класс, который определяет функциональность драйвера СУБД. Это включает функции, такие как QSqlDriver::open() и QSqlDriver::close(). QSqlDriver отвечает за подключение к базе данных, установку соответствующей среды и т. д. Кроме того, QSqlDriver может создавать объекты QSqlQuery, подходящие для конкретного API базы данных. QSqlDatabase перенаправляет многие вызовы функций непосредственно в QSqlDriver, который предоставляет конкретную реализацию.
QSqlResult — это абстрактный базовый класс, который определяет функциональность запроса к СУБД. Это включает операторы, такие как 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() override {}
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-6.1/sql-driver.html