Spec-Zone.ru › Qt

Драйверы баз данных SQL

Модуль Qt SQL использует драйверы плагины для взаимодействия с различными API баз данных. Так как API модуля SQL Qt независим от базы данных, весь код, специфичный для базы данных, содержится в этих драйверах. Qt поставляется с несколькими драйверами, и можно добавить другие. Исходный код драйвера предоставляется и может быть использован в качестве модели для создания собственных драйверов.

Поддерживаемые базы данных

В таблице ниже перечислены драйверы, включенные в Qt:

Имя драйвера Система управления базами данных (СУБД)
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 — это встроенная система баз данных с наилучшим покрытием тестами и поддержкой на всех платформах. Oracle через OCI, PostgreSQL и MySQL через ODBC или родной драйвер хорошо протестированы на Windows и Linux. Полнота поддержки других систем зависит от наличия и качества клиентских библиотек.

Примечание: Для построения плагина драйвера необходимо иметь соответствующую клиентскую библиотеку для вашей системы управления базами данных (СУБД). Она предоставляет доступ к API, экспонированному СУБД, и обычно поставляется вместе с ней. Большинство установочных программ также позволяют установить «библиотеки разработки», и именно они вам нужны. Эти библиотеки отвечают за низкоуровневое взаимодействие с СУБД. Также убедитесь, что установлены правильные библиотеки базы данных для вашей архитектуры 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, передайте следующий параметр в двойную черту части строки конфигурации:

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>"
cmake --build .
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 (только 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"
cmake --build .
cmake --install .

При распространении вашего приложения не забудьте включить libmysql.dll / libmariadb.dll в пакет установки. Он должен быть помещён в ту же папку, что и исполняемый файл приложения. libmysql.dll дополнительно требует библиотек времени выполнения MSVC, которые можно установить с помощью vcredist.exe

QOCI для Oracle Call Interface (OCI)

Плагин Qt OCI поддерживает подключение к базе данных Oracle, как определено используемой версией клиента. Это зависит от того, какую версию поддерживает 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

Все, что вам нужно, — это « - 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>"
cmake --build .
cmake --install .
END_OF_DOCUMENT_MARKER

Примечание: Если вы используете пакет Oracle Instant Client, вам необходимо установить LD_LIBRARY_PATH при сборке плагина OCI SQL и при запуске приложения, использующего плагин OCI SQL.

Как собрать плагин OCI на Windows

Обычно достаточно выбрать опцию "Программист" в установщике Oracle Client с компакт-диска Oracle Client для сборки плагина. Для некоторых версий 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"
cmake --build .
cmake --install .

При запуске приложения также необходимо добавить путь oci.lib к переменной среды PATH.

set PATH=%PATH%;C:\oracle

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. Некоторые 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 с помощью 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>"
cmake --build .
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>
cmake --build .
cmake --install .

QPSQL для PostgreSQL (Версия 7.3 и выше)

Драйвер QPSQL поддерживает версию 7.3 и выше сервера PostgreSQL.

Дополнительную информацию о 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 с 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 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"
cmake --build .
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"
cmake --build .
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>"
cmake --build .
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"
cmake --build .
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.

id="how-to-build-the-qsqlite-plugin">Как скомпилировать плагин 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"
cmake --build .
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"
cmake --build .
cmake --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 может использоваться как клиент-сервер или без сервера, в этом случае он работает с локальными файлами. Файл базы данных должен существовать до установления соединения.

Обратите внимание, что InterBase требует указания полного пути к файлу базы данных, независимо от того, хранится ли он локально или на другом сервере.

QSqlDatabase db;
db.setHostName("MyServer");
db.setDatabaseName("C:\\test.gdb");

Для сборки этого плагина вам потребуются заголовки и библиотеки разработки InterBase/Firebird.

Из-за несовместимости лицензий с GPL пользователи Qt Open Source Edition не имеют права связывать этот плагин с коммерческими версиями InterBase. Используйте Firebird или бесплатную версию InterBase.

Поддержка Unicode и кодировка текста 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>"
cmake --build .
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>"
cmake --build .
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"
cmake --build .
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"
cmake --build .
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 — это абстрактный базовый класс, который определяет функциональность драйвера 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() 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.2/sql-driver.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API