本页内容

SQL 数据库驱动程序

Qt SQL 模块通过驱动程序插件与不同的数据库API进行通信。由于Qt的SQL模块API与数据库无关,因此所有与数据库相关的代码都包含在这些驱动程序中。Qt随附了多个驱动程序,用户还可以添加其他驱动程序。驱动程序的源代码已提供,可作为编写自定义驱动程序的参考模板。

支持的数据库

下表列出了 Qt 随附的驱动程序:

驱动程序名称数据库管理系统
QDB2IBM DB2(7.1 及以上版本)
QIBASEBorland InterBase / Firebird
QMYSQL / MARIADBMySQL 或 MariaDB(5.6 及以上版本)
QOCIOracle 调用接口驱动程序(12.1 及以上版本)
QODBC开放数据库连接(ODBC)——Microsoft SQL Server 及其他符合 ODBC 标准的数据库
QPSQLPostgreSQL(7.3 及以上版本)
QSQLITESQLite 3 版
QMIMERMimer SQL(11 及以上版本)

SQLite 是一款具有最佳测试覆盖率且在所有平台上均受支持的进程内数据库系统。通过 OCI 访问的 Oracle、PostgreSQL,以及通过 ODBC 或原生驱动程序访问的 MySQL,均已在 Windows 和 Linux 系统上经过充分测试。对其他系统的支持程度取决于客户端库的可用性和质量。

注意:要构建 驱动程序插件,您需要拥有适用于您所用数据库管理系统(DBMS)的相应客户端库。该库可提供对 DBMS 公开的 API 的访问,通常随 DBMS 一起提供。 大多数安装程序还允许您安装“开发库”,而这些正是您所需要的。这些库负责与 DBMS 之间的底层通信。此外,请确保安装与您的 Qt 架构(32 位或 64 位)相匹配的数据库库。

注意:当在 开源许可下使用 Qt 但搭配专有数据库时 ,请验证客户端库的许可证是否与 LGPL 兼容。

构建驱动程序

使用特定驱动程序编译 Qt

Qt XML 的 `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 文件在 Windows 上安装在C:\mysql-connector-c-6.1.11-winx64 目录下,请在 configure 命令行中的双破折号部分传递以下参数:

C:\Qt\6.0.0\Src\configure.bat -sql-mysql -- -DMySQL_ROOT="C:\mysql-8.0.22-winx64"
Configure summary:

...
Qt Sql Drivers:
  DB2 (IBM) .............................. no
  InterBase .............................. no
  Mimer SQL .............................. yes
  MySql .................................. yes
  OCI (Oracle) ........................... no
  ODBC ................................... yes
  PostgreSQL ............................. no
  SQLite ................................. yes
    Using system provided SQLite ......... no
...

当您按照上述方式配置驱动程序时,CMake 会跳过任何依赖性检查,并直接使用提供的路径。如果软件包提供了自己的系统库集,而这些库不应被构建例程识别,则此方法特别有用。

下面将详细说明每个驱动程序的具体情况。

注意:如果 出现问题,且您希望 CMake 重新检查可用的驱动程序,可能需要从构建目录中删除CMakeCache.txt 文件。

仅编译特定的 SQL 驱动程序

当 Qt 已构建完成或已安装为二进制版本时,可以仅编译特定的 SQL 驱动程序。 但您必须确保安装的 Qt 源代码版本完全一致(例如通过Qt Maintenance Tool 获取)——否则可能会因 API 变更而导致编译错误。此外,请务必通过在 Windows “开始”菜单中执行相应的 Qt 命令提示符来正确设置构建环境。

典型的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
  Mimer SQL .............................. yes
  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-cmake 配置完成后,请运行ninja 来构建驱动程序。

注意:如 《使用特定驱动程序编译 Qt》一文中所述,如果无法找到驱动程序或驱动程序未启用,请删除CMakeCache.txt 文件后重新开始。

出于处理外部依赖关系的实际考虑,Qt 的二进制构建版本中仅包含 SQLite 插件。Windows 版的 Qt 二进制构建还包含 ODBC 和 PostgreSQL 插件。 为了在不重新构建整个 Qt 的情况下向 Qt 安装中添加其他驱动程序,可以在完整的 Qt 构建目录之外配置并构建 `qtbase/src/plugins/sqldrivers ` 目录。请注意,无法单独配置每个驱动程序,只能一次性配置所有驱动程序。不过,驱动程序可以单独构建。

注意: 若要在构建完成后安装插件,则需要 指定 `CMAKE_INSTALL_PREFIX`。

驱动程序的具体说明

适用于 MySQL 或 MariaDB 5.6 及更高版本的 QMYSQL

MariaDB 是 MySQL 的一个分支,旨在作为遵循 GNU 通用公共许可证的免费开源软件继续发展。MariaDB 致力于与 MySQL 保持高度兼容性,确保能够直接替代原版,实现库二进制一致性,并与 MySQL 的 API 和命令完全匹配。因此,针对 MySQL 和 MariaDB 的插件被合并为一个 Qt 插件。

时间戳支持

自 Qt 6.8 起,QDateTime 的值在插入前会转换为 UTC,在检索时则会从 UTC 转换回原始值。 为实现这一功能,驱动程序会在调用 open() 时将连接时区设置为 UTC(SET time_zone = '+00:00')。由于 MySQL 不存储任何时区信息,因此该信息会丢失,所有检索到的QDateTime 值均为 UTC 时间。

QMYSQL 对存储过程的支持

MySQL 在 SQL 层面上支持存储过程,但没有用于控制 IN、OUT 和 INOUT 参数的 API。因此,必须使用 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`。这可以通过在 `configure` 命令行中添加 `-DMySQL_LIBRARY=<path/to/mysqld/>libmysqld.<so|lib|dylib> ` 来实现。

有关 MySQL 嵌入式服务器的更多信息,请参阅 MySQL 文档中的“libmysqld,嵌入式 MySQL 服务器库”一章。

连接选项

Qt MySQL/MariaDB 插件支持以下连接选项:

属性可能的值
CLIENT_COMPRESS如果设置此选项,则在身份验证成功后切换到压缩协议
CLIENT_FOUND_ROWS如果设置此选项,则发送找到的行,而不是受影响的行
CLIENT_IGNORE_SPACE若设置此选项,则忽略 '(' 前的空格
CLIENT_NO_SCHEMA若设置此选项,则不允许使用 database.table.column 格式
CLIENT_INTERACTIVE若设置此选项,则将客户端视为交互式客户端
MYSQL_OPT_PROTOCOL显式指定要使用的协议:
MYSQL_PROTOCOL_TCP:使用 TCP 连接(通过 setHostname() 指定的 IP/主机名) MYSQL_PROTOCOL_SOCKET: 通过 UNIX_SOCKET 中指定的套接字连接 MYSQL_PROTOCOL_PIPE:通过 UNIX_SOCKET 中指定的命名管道连接 MYSQL_PROTOCOL_MEMORY:通过 MYSQL_SHARED_MEMORY_BASE_NAME 中指定的共享内存连接
UNIX_SOCKET指定要使用的套接字或命名管道,尽管名为 UNIX_SOCKET,但在 Windows 上同样可以使用
MYSQL_SHARED_MEMORY_BASE_NAME指定要使用的共享内存段名称
MYSQL_OPT_RECONNECTTRUE 或 1:连接中断后自动重新连接
FALSE 或 0:连接中断后不自动重新连接(默认)
请参阅“自动重新连接控制”
MYSQL_OPT_CONNECT_TIMEOUT连接超时时间(以秒为单位)
MYSQL_OPT_READ_TIMEOUT每次从服务器读取数据的尝试超时时间(以秒为单位)
MYSQL_OPT_WRITE_TIMEOUT每次向服务器写入数据的超时时间(以秒为单位)
MYSQL_OPT_LOCAL_INFILE设置为 1 以启用对本地LOAD_DATA 的支持;若未设置或设置为 0,则禁用
MYSQL_OPT_SSL_MODE连接到服务器时使用的安全状态:SSL_MODE_DISABLED、SSL_MODE_PREFERRED、SSL_MODE_REQUIRED、SSL_MODE_VERIFY_CA、SSL_MODE_VERIFY_IDENTITY。 仅在链接到 MySQL 5.7.10 或更高版本时可用。
MYSQL_OPT_TLS_VERSION客户端允许用于加密连接的协议列表。该值可以是“TLSv1”、“TLSv1.1”、“TLSv1.2”或“TLSv1.3”的组合,具体取决于所使用的MySQL 服务器版本。 仅在链接到 MySQL 5.7.11 或更高版本,或 MariaDB C Connector 3.1.10 时可用。
MYSQL_OPT_SSL_KEY / SSL_KEY(已弃用)客户端私钥文件的路径名称
MYSQL_OPT_SSL_CERT / SSL_CERT(已弃用)客户端公钥证书文件的路径名
MYSQL_OPT_SSL_CA / SSL_CA(已弃用)证书颁发机构(CA)证书文件的路径名
MYSQL_OPT_SSL_CAPATH / SSL_CAPATH(已弃用)包含受信任的 SSL CA 证书文件的目录的路径名
MYSQL_OPT_SSL_CIPHER / SSL_CIPHER(已弃用)SSL 加密允许使用的密码套件列表
MYSQL_OPT_SSL_CRL包含证书撤销列表 (CRL) 的文件的路径名
MYSQL_OPT_SSL_CRLPATH包含证书撤销列表文件的目录的路径名
MYSQL_OPT_SSL_VERIFY_SERVER_CERTTRUE 或 1:启用对服务器“通用名称”(Common Name)身份的验证(默认)
FALSE 或 0:启用对服务器“通用名称”(Common Name)身份的验证
仅在与 MySQL 5.7.11 或 MariaDB 链接时可用,已于 MySQL 8.0 中移除。

有关连接选项的更多详细信息,请参阅mysql_options()的 MySQL 文档。

如何在 Unix 和 macOS 上构建 QMYSQL 插件

您需要 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_source_directory>/qtbase/src/plugins/sqldrivers -DCMAKE_INSTALL_PREFIX=<qt_installation_path>/<platform> -DMySQL_ROOT="/usr/local/mysql"
cmake --build .
cmake --install .

如何在 Windows 上构建 QMYSQL 插件

您需要获取 MySQL 安装文件(例如MySQL 网页安装程序或MariaDB C 连接器)。运行安装程序,选择“自定义安装”,并安装与您的 Qt 安装版本(x86 或 x64)匹配的 MySQL C 连接器。安装完成后,请检查所需文件是否已存在:

  • <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 连接器不再作为独立的可安装组件提供。取而代之的是,您可以通过安装完整的 MySQL 服务器(仅限 x64 版本)或MariaDB C 连接器来获取mysql.h 和libmysql.* 。

请按以下步骤构建插件(此处假设<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_ROOT="C:\mysql-8.0.22-winx64"
cmake --build .
cmake --install .

在分发应用程序时,请务必将libmysql.dll/libmariadb.dll包含在安装包中。这些文件必须放置在与应用程序可执行文件相同的文件夹中。此外,libmysql.dll还需要 MSVC 运行时库,可通过vcredist.exe进行安装。

Oracle 调用接口(OCI)的 QOCI

Qt OCI 插件支持根据所用 Instant Client 的版本连接到 Oracle 数据库。这取决于 Oracle 官方声明的支持范围。该插件将自动检测数据库版本,并据此启用相应功能。

即使没有 tnsnames.ora 文件,也可以连接到 Oracle 数据库。这要求将数据库 SID 作为数据库名称传递给驱动程序,并提供主机名。

OCI 用户身份验证

Qt OCI 插件支持使用外部凭据(OCI_CRED_EXT)进行身份验证。通常,这意味着数据库服务器将使用操作系统提供的用户身份验证,而不是其自身的身份验证机制。

使用 `QSqlDatabase ` 建立连接时,请将用户名和密码留空,以启用外部凭据身份验证。

OCI BLOB/LOB 支持

可以读取和写入二进制大对象(BLOB),但请注意,此过程可能需要大量内存。应使用仅向前查询来选择 LOB 字段(参见QSqlQuery::setForwardOnly())。

插入 BLOB 时,应使用将 BLOB 绑定到占位符的预编译查询,或者使用QSqlTableModel ,后者会在内部使用预编译查询来完成此操作。

连接选项

Qt OCI 插件支持以下连接选项:

属性可能的值
OCI_ATTR_PREFETCH_ROWS将 OCI 属性OCI_ATTR_PREFETCH_ROWS设置为指定的值
OCI_ATTR_PREFETCH_MEMORY将 OCI 属性OCI_ATTR_PREFETCH_MEMORY设置为指定值
OCI_AUTH_MODEOCI_SYSDBA:进行身份验证以获取 SYSDBA 访问权限
OCI_SYSOPER:进行身份验证以获取 SYSOPER 访问权限
OCI_DEFAULT:进行身份验证并以普通权限访问
有关访问模式的更多信息,请参阅OCISessionBegin

如何在 Unix 和 macOS 上构建 OCI 插件

您只需准备“ - Basic”和“Instant Client Package - SDK”即可。

构建驱动程序所需的 Oracle 库文件:

  • libclntsh.<so|dylib> (所有版本)

告知qt-cmake 在何处查找Oracle头文件和共享库,并进行构建。

我们假设您已安装了 Instant Client Package SDK 的 RPM 软件包(您需要相应调整版本号):

mkdir build-sqldrivers
cd build-sqldrivers
qt-cmake -G Ninja <qt_source_directory>/qtbase/src/plugins/sqldrivers -DCMAKE_INSTALL_PREFIX=<qt_installation_path>/<platform> -DOracle_ROOT="/usr/include/oracle/21/client64"
cmake --build .
cmake --install .

注意:如果您 使用的是 Oracle Instant Client 软件包,则 在构建 OCI SQL 插件时,以及在运行使用 OCI SQL 插件的应用程序时,都需要设置 LD_LIBRARY_PATH。

如何在 Windows 上构建 OCI 插件

通常只需在 Oracle 客户端安装光盘中的 Oracle 客户端安装程序中选择“程序员”选项,即可构建该插件。对于某些版本的 Oracle 客户端,如果“调用接口 (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_ROOT="C:\oracle"
cmake --build .
cmake --install .

运行应用程序时,您还需要将oci.dll 路径添加到PATH 环境变量中:

set PATH=%PATH%;C:\oracle

用于开放数据库连接(ODBC)的 QODBC

ODBC 是一个通用接口,允许您通过统一接口连接到多种数据库管理系统(DBMS)。QODBC 驱动程序使您能够连接到 ODBC 驱动程序管理器,并访问可用的数据源。 请注意,您还需要为系统上已安装的 ODBC 驱动程序管理器安装并配置相应的 ODBC 驱动程序。随后,QODBC 插件将允许您在 Qt 应用程序中使用这些数据源。

注意: 如果可用,应 使用原生驱动程序,而非 ODBC 驱动程序。如果没有原生驱动程序,则可将 ODBC 支持作为符合规范的数据库的备用方案。

在 Windows 系统上,ODBC 驱动程序管理器默认已安装。对于 Unix 系统,则需要先安装某些实现。请注意,您的应用程序的每个最终用户都必须安装 ODBC 驱动程序管理器,否则 QODBC 插件将无法正常工作。

连接到 ODBC 数据源时,应将 ODBC 数据源名称(DSN)传递给 `QSqlDatabase::setDatabaseName()` 函数,而非实际的数据库名称。也可以传递 FILEDSN (*.dsn) 文件名或完整的 ODBC 驱动程序字符串。 传递驱动程序字符串时,必须确保所有参数(用户名、密码等)均已正确转义。若通过QSqlDatabase 函数传递用户名或密码,则由QODBC插件自动完成转义。

QODBC 插件需要符合 ODBC 标准的 2.0 版或更高版本的驱动程序管理器。有些 ODBC 驱动程序虽声称符合 2.0 版标准,但并未提供所有必要的功能。 因此,QODBC 插件会在建立连接后检查数据源是否可用,若检查失败则拒绝运行。如果您不希望出现这种行为,可以从qsql_odbc.cpp 文件中删除#define ODBC_CHECK_DRIVER 这一行。请注意,此操作风险自负!

默认情况下,Qt 会指示 ODBC 驱动程序以 ODBC 2.x 驱动程序的方式运行。 然而,对于某些驱动程序管理器/ODBC 3.x 驱动程序的组合(例如unixODBC/MaxDB ODBC),指示 ODBC 驱动程序以 2.x 驱动程序的方式工作可能会导致驱动程序插件出现意外行为。 为避免此问题,请在执行 `open your database connection` 之前,通过 `setting the connect option "SQL_ATTR_ODBC_VERSION=SQL_OV_ODBC3" ` 指示 ODBC 驱动程序以 3.x 驱动程序的方式运行。请注意,这将影响 ODBC 驱动程序行为的多个方面,例如 SQLSTATE 状态。在设置此连接选项之前,请查阅您的 ODBC 文档,了解可能出现的行为差异。

如果遇到 ODBC 数据源访问速度极慢的情况,请确保在 ODBC 数据源管理器中已关闭 ODBC 调用跟踪。

某些驱动程序不支持可滚动光标。在这种情况下,只有以QSqlQuery::setForwardOnly()模式执行的查询才能成功。

时间戳支持

ODBC 使用的是 TIMESTAMP_STRUCT,该结构不包含任何时区或类似信息。因此,QDateTime 的使用完全不考虑时区因素。

注意: 此情况未来可能会发生变化。

ODBC 存储过程支持

在 Microsoft SQL Server 中,如果存储过程使用了 return 语句或返回多个结果集,则只有当您通过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 的支持

如果定义了 UNICODE,QODBC 插件将使用 Unicode API。在基于 Windows 的系统上,这是默认设置。请注意,ODBC 驱动程序和数据库管理系统(DBMS)也必须支持 Unicode。

对于 Oracle 9 ODBC 驱动程序(Windows 版),必须在 ODBC 驱动程序管理器中勾选“SQL_WCHAR 支持”,否则 Oracle 会将所有 Unicode 字符串转换为本地 8 位表示形式。

连接选项

Qt ODBC 插件支持以下连接选项:

属性可能的值
SQL_ATTR_ACCESS_MODESQL_MODE_READ_ONLY:以只读模式打开数据库
SQL_MODE_READ_WRITE:以读写模式打开数据库(默认)
SQL_ATTR_LOGIN_TIMEOUT登录时等待数据库连接的秒数(值为 0 表示无限期等待)
SQL_ATTR_CONNECTION_TIMEOUT等待任何数据库请求的时间(以秒为单位)(值为 0 表示无限期等待)
SQL_ATTR_CURRENT_CATALOG此连接要使用的目录(数据库)
SQL_ATTR_METADATA_IDSQL_TRUE:将目录函数的字符串参数视为标识符
SQL_FALSE:不将目录函数的字符串参数视为标识符
SQL_ATTR_PACKET_SIZE指定网络数据包的大小(以字节为单位)
SQL_ATTR_TRACEFILE包含跟踪文件名称的字符串
SQL_ATTR_TRACESQL_OPT_TRACE_ON:启用数据库查询跟踪
SQL_OPT_TRACE_OFF:禁用数据库查询跟踪(默认)
SQL_ATTR_CONNECTION_POOLING在环境级别启用或禁用连接池。
SQL_CP_DEFAULT、SQL_CP_OFF:连接池已关闭(默认)
SQL_CP_ONE_PER_DRIVER:每个驱动程序支持一个连接池
SQL_CP_ONE_PER_HENV:每个环境支持一个连接池
SQL_ATTR_ODBC_VERSIONSQL_OV_ODBC3:驱动程序应作为 ODBC 3.x 驱动程序运行
SQL_OV_ODBC2:驱动程序应作为 ODBC 2.x 驱动程序运行(默认)
SQL_ATTR_CP_MATCH可以是 SQL_CP_STRICT_MATCH、SQL_CP_RELAXED_MATCH 或 SQL_CP_MATCH_DEFAULT。有关更多信息,请参阅SQLConnect()ODBC 文档
SQL_PERCENT_ENCODE_PASSWORD这是一个自定义的 Qt ODBC 驱动程序选项,用于支持那些需要将特殊字符采用百分号编码(而非 ODBC 标准定义的花括号编码)的驱动程序(如 Oracle、PostgreSQL)。

有关连接选项的更多详细信息,请参阅SQLSetConnectAttr()ODBC 文档。

如何在 Unix 和 macOS 上构建 ODBC 插件

建议您使用 unixODBC。您可以在http://www.unixodbc.org 上找到最新版本和 ODBC 驱动程序。您需要 unixODBC 的头文件和共享库。

告诉 `qt-cmake ` 该在何处查找 unixODBC 的头文件和共享库(此处假设 unixODBC 安装在 `/usr/local/unixODBC` 目录下),然后进行编译:

mkdir build-sqldrivers
cd build-sqldrivers
qt-cmake -G Ninja <qt_source_directory>/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 .

如何在 Windows 上构建 ODBC 插件

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 .

适用于 PostgreSQL 的 QPSQL(7.3 及以上版本)

QPSQL 驱动程序支持 7.3 及以上版本的 PostgreSQL 服务器。

有关 PostgreSQL 的更多信息,请访问http://www.postgresql.org。

时间戳支持

自 Qt 6.8 起,QDateTime 值在插入前会转换为 UTC,在检索时则会从 UTC 转换回原值。 为了实现这一功能,驱动程序会在调用 open() 时将连接时区设置为 UTC(SET TIME ZONE 'UTC')。尽管 PostgreSQL 提供了 `timestamptz` 列类型,但插入时使用的时区不会被保留,因此所有检索到的QDateTime 值均为 UTC。

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 对仅向前查询的支持

要使用仅前向查询,必须使用 PostgreSQL 客户端库 9.2 及以上版本构建 QPSQL 插件。如果插件是使用较旧版本构建的,则无法使用仅前向模式——调用QSqlQuery::setForwardOnly() 并传入true 将没有任何效果。

警告:如果您使用 PostgreSQL 9.2 或更高版本构建 QPSQL 插件,则必须随应用程序分发 libpq 9.2 或更高版本。否则,加载 QPSQL 插件时将失败,并显示以下消息:

QSqlDatabase: QPSQL driver not loaded
QSqlDatabase: available drivers: QSQLITE QMYSQL QMARIADB QODBC QPSQL
Could not create database object

在仅前向模式下遍历结果时,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...
        }
    }
}

在使用 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 使用不同的数据库连接,或者在 while 循环之后执行 query2,则不会出现此问题。

注意: QSqlDatabase 中的某些 方法(如 tables()、primaryIndex())会隐式执行 SQL 查询,因此在遍历仅前向查询的结果集时,这些方法也不能使用。

注意: 如果QPSQL 检测到查询结果丢失,将输出以下警告:

QPSQLDriver::getResult: Query results lost - probably discarded on executing another SQL query.

连接选项

Qt PostgreSQL 插件支持 PostgreSQL 文档中connect()函数所指定的所有连接选项。

如何在 Unix 和 macOS 上构建 QPSQL 插件

您需要安装 PostgreSQL 客户端库和头文件。

为了让qt-cmake 能够找到PostgreSQL的头文件和共享库,请按以下方式构建插件(假设PostgreSQL客户端安装在/usr/local/pgsql 目录下):

mkdir build-psql-driver
cd build-psql-driver

qt-cmake -G Ninja <qt_source_directory>/qtbase/src/plugins/sqldrivers-DCMAKE_INSTALL_PREFIX=<qt_installation_path>/<platform> -DPostgreSQL_ROOT="/usr/local/pgsql"
cmake --build .
cmake --install .

如何在 Windows 上构建 QPSQL 插件

安装适合您编译器的 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> -DPostgreSQL_ROOT="C:\pgsql"
cmake --build .
cmake --install .

MinGW 用户可参考以下在线文档:PostgreSQL MinGW/Native Windows。

在分发应用程序时,请务必将 libpq.dll 包含在安装包中。该文件必须放置在与应用程序可执行文件相同的文件夹中。

适用于 IBM DB2 的 QDB2(7.1 及以上版本)

Qt DB2 插件支持访问 IBM DB2 数据库。该插件已在 IBM DB2 v7.1 和 7.2 版本上经过测试。您必须安装 IBM DB2 开发客户端库,其中包含编译 QDB2 插件所需的头文件和库文件。

QDB2 驱动程序支持预编译查询、Unicode 字符串的读写以及 BLOB 的读写。

我们建议在 DB2 中调用存储过程时使用“仅向前”查询(参见QSqlQuery::setForwardOnly())。

连接选项

Qt IBM DB2 插件支持以下连接选项:

属性可能的值
SQL_ATTR_ACCESS_MODESQL_MODE_READ_ONLY:以只读模式打开数据库
SQL_MODE_READ_WRITE:以读写模式打开数据库(默认)
SQL_ATTR_LOGIN_TIMEOUT登录时等待数据库连接的秒数(最大值:32767,值为 0 表示无限期等待)

如何在 Unix 和 macOS 上构建 QDB2 插件

mkdir build-sqldrivers
cd build-sqldrivers
qt-cmake -G Ninja <qt_source_directory>/qtbase/src/plugins/sqldrivers -DCMAKE_INSTALL_PREFIX=<qt_installation_path>/<platform> -DDB2_ROOT="/usr/local/db2"
cmake --build .
cmake --install .

如何在 Windows 上构建 QDB2 插件

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_ROOT="C:\db2"
cmake --build .
cmake --install .

适用于 SQLite 的 QSQLITE(3 版及以上)

Qt SQLite 插件支持访问 SQLite 数据库。SQLite 是一种进程内数据库,这意味着无需数据库服务器。SQLite 基于单个文件运行,在建立连接时必须将该文件设置为数据库名称。如果该文件不存在,SQLite 会尝试创建它。 SQLite 还支持内存数据库和临时数据库。只需分别将 “:memory:” 或空字符串作为数据库名称传入即可。

QSqlDatabase::setConnectOptionsSQLite 在多用户和多事务方面存在一些限制。若尝试从不同事务中读写同一资源,应用程序可能会冻结,直到其中一个事务提交或回滚为止。Qt SQLite 驱动程序会不断重试向被锁定的资源写入数据,直到超时为止(参见QSQLITE_BUSY_TIMEOUT 中的 ())。

在 SQLite 中,除 INTEGER PRIMARY KEY 列外,任何列均可用于存储任意类型的值。例如,一个声明为 INTEGER 的列,在一行中可能包含整数值,而在下一行中可能包含文本值。 这是因为 SQLite 将值的类型与值本身关联,而非与其存储的列相关联。由此产生的后果是,QSqlField::metaType() 返回的类型仅表示该字段的推荐类型。不应据此推断实际类型,而应检查各个值的具体类型。

在执行 SELECT 语句期间,驱动程序会被锁定,禁止更新。这在使用QSqlTableModel 时可能会引发问题,因为 Qt 的项目视图会按需获取数据(对于 `QSqlTableModel`,则通过 `QSqlQuery::fetchMore()` 实现)。

有关 SQLite 的信息,请访问http://www.sqlite.org。

时间戳支持

SQLite 没有专门的时间戳列类型。QDateTime 会被作为字符串存储,格式为Qt::ISODateWithMs ,因此QDateTime 的时区信息在插入和查询过程中得以保留。

连接选项

Qt SQLite 插件支持以下连接选项:

属性可能的值
QSQLITE_BUSY_TIMEOUT忙状态处理程序的超时时间(单位为毫秒,val <= 0 表示禁用),更多信息请参阅SQLite 文档
QSQLITE_USE_QT_VFS若设置此属性,则使用 Qt 的 VFS 打开数据库,这允许通过 `QFile` 打开数据库。这样既可以从任何可读写的位置(例如 Android 共享存储)打开数据库,也可以从只读资源(例如 qrc 或 Android 资源)中打开。 请注意,从只读资源打开数据库时,务必同时添加 QSQLITE_OPEN_READONLY 属性。否则将无法打开数据库。
QSQLITE_OPEN_READONLY如果设置此属性,数据库将以只读模式打开;若数据库不存在,操作将失败。否则,数据库将以读写模式打开,并在数据库文件尚不存在时自动创建(默认行为)
QSQLITE_OPEN_URI给定的文件名将被解释为 URI,详见SQLITE_OPEN_URI
QSQLITE_ENABLE_SHARED_CACHE如果设置此选项,则以共享缓存模式打开数据库;否则以私有缓存模式打开
QSQLITE_ENABLE_REGEXP若设置此选项,插件将定义一个名为“regex”的函数,该函数可在查询中使用;使用QRegularExpression 来评估正则表达式查询
QSQLITE_NO_USE_EXTENDED_RESULT_CODES禁用 SQLite 中扩展结果代码功能的使用
QSQLITE_ENABLE_NON_ASCII_CASE_FOLDING如果设置此选项,插件将用QString 函数替换 'lower' 和 'upper' 函数,以便正确折叠非 ASCII 字符的大小写
QSQLITE_OPEN_NOFOLLOW若设置此选项,则数据库文件名不允许包含符号链接

如何构建 QSQLITE 插件

SQLite 3.0 作为第三方库已包含在 Qt 中。可通过在qt-cmake 命令行中传入-DFEATURE_system_sqlite=OFF 参数来构建该插件。

如果您不想使用 Qt 自带的 SQLite 库,可以在qt-cmake 命令行中传入-DFEATURE_system_sqlite=ON 参数,以使用操作系统的 SQLite 库。建议在可能的情况下采用此方法,因为这样可以减小安装体积,并减少一个需要跟踪其安全公告的组件。

在 Unix 和 macOS 上(将$SQLITE 替换为 SQLite 所在的目录):

mkdir build-sqldrivers
cd build-sqldrivers
qt-cmake -G Ninja <qt_source_directory>/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 运算符。但所需的实现必须由用户提供。为方便起见,可以在执行the database connection is opened 之前通过setting the connect option QSQLITE_ENABLE_REGEXP 启用默认实现。这样,类似于“column REGEXP 'pattern'”的 SQL 语句基本上会展开为 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 宏来强制其写入特定文件格式。

适用于 Mimer SQL 11 及更高版本的 QMIMER

Qt Mimer SQL 插件支持与 Mimer SQL 关系型数据库管理系统(RDBMS)进行交互。Mimer SQL 提供占用资源少、可扩展且稳健的关系型数据库解决方案,符合国际 ISO SQL 标准。 Mimer SQL 支持 Windows、Linux、macOS 和 OpenVMS 系统,以及 QNX、Android 和嵌入式 Linux 等多种嵌入式平台。

Mimer SQL 完全支持 Unicode。若要处理 Unicode 数据,必须使用“国家字符”(NCHAR)、“可变长度国家字符”(NVARCHAR)或“大型国家字符对象”(NCLOB)列类型。 有关 Mimer SQL 和 Unicode 的更多信息,请访问https://developer.mimer.com/features/multilingual-support

时间戳支持

Mimer SQL 不支持时区,且在调用 `QDateTime ` 时完全不考虑时区。

注意: 此情况未来可能会发生变化。

QMIMER 对存储过程的支持

Mimer SQL 具备符合 SQL 标准(PSM)的存储过程,该插件完全支持 IN、OUT、INOUT 参数以及结果集存储过程。

包含 INOUT 和 OUT 参数的存储过程示例:

create procedure inout_proc (INOUT param1 INT, OUT param2 INT)
BEGIN
    set param1 = param1 * 2;
    set param2 = param1 * param1;
END

访问 INOUT 和 OUT 值的源代码:

    QSqlDatabase db;
    QSqlQuery query;
    int i1 = 10, i2 = 0;
    query.prepare("call qtestproc(?, ?)");
    query.bindValue(0, i1, QSql::InOut);
    query.bindValue(1, i2, QSql::Out);
    query.exec();

如何在 Unix 和 macOS 上构建 QMIMER 插件

您需要 Mimer SQL 的头文件和共享库。请访问https://developer.mimer.com,安装任意一个 Mimer SQL 版本即可获取这些文件。

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> -DMimer_INCLUDE_DIR="/usr/include" -DMimer_LIBRARIES="/usr/lib/libmimer.so"
cmake --build .
cmake --install .

如何在 Windows 上构建 QMIMER 插件

您需要 Mimer SQL 的头文件和共享库。请通过安装https://developer.mimer.com 上提供的任意一种 Mimer SQL 版本来获取它们。

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> -DMimer_INCLUDE_DIR="C:\Program Files\Mimer SQL Experience 11.0\dev\include" -DMimer_LIBRARIES="C:\Program Files\Mimer SQL Experience 11.0\dev\lib\amd64\mimapi64.lib|C:\Program Files\Mimer SQL Experience 11.0\dev\lib\x86\mimapi32.lib"
cmake --build .
cmake --install .

适用于 Borland InterBase 的 QIBASE

Qt InterBase 插件支持访问 InterBase 和 Firebird 数据库。InterBase 既可以作为客户端/服务器模式使用,也可以在不使用服务器的情况下运行,此时它将操作本地文件。必须先存在数据库文件,才能建立连接。Firebird 必须采用服务器配置模式使用。

请注意,无论数据库文件是存储在本地还是其他服务器上,InterBase 都要求您指定该文件的全路径。

时间戳支持

InterBase 将时间戳以 UTC 格式存储,不包含任何时区信息。因此,QDateTime 的使用完全不考虑时区因素。

自 Firebird 4.0 起,该数据库支持带时区的时间戳。时区信息与时间戳分开存储,以便日后能够正确检索。有关时间戳处理的更多信息,请参阅 Firebird文档。

连接选项

Qt Borland InterBase 插件支持以下连接选项:

属性可能的值
ISC_DPB_SQL_ROLE_NAME指定登录角色名称

如何构建 QIBASE 插件

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

您需要 InterBase/Firebird 的开发头文件和库才能构建此插件。

由于与 GPL 许可证存在兼容性问题,Qt 开源版用户不得将此插件链接到 InterBase 的商业版本。请使用 Firebird 或 InterBase 的免费版。

QIBASE 存储过程

InterBase/Firebird 将 OUT 值作为结果集返回,因此调用存储过程时,只需通过 `QSqlQuery::bindValue()` 绑定 IN 值。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

如何在 Unix 和 macOS 上构建 QIBASE 插件

以下内容假设已将 InterBase 或 Firebird 安装在/opt/interbase 目录下:

如果您使用的是 InterBase:

mkdir build-sqldrivers
cd build-sqldrivers
qt-cmake -G Ninja <qt_source_directory>/qtbase/src/plugins/sqldrivers -DCMAKE_INSTALL_PREFIX=<qt_installation_path>/<platform> -DInterbase_ROOT="/opt/interbase/"
cmake --build .
cmake --install .

可选地,使用 CMake 变量Interbase_INCLUDE_DIR 和Interbase_LIBRARY 来直接指定头文件路径和库路径。

如何在 Windows 上构建 QIBASE 插件

以下内容假设 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_ROOT="C:\interbase"
cmake --build .
cmake --install .

可选地,使用 CMake 变量Interbase_INCLUDE_DIR 和Interbase_LIBRARY 来直接指定头文件路径和库。

请注意,C:\interbase\bin 必须位于PATH 中。

故障排除

您应始终使用与项目所用编译器相同的编译器编译而成的客户端库。如果您无法获取源代码分发包以自行编译客户端库,则必须确保预编译的库与您的编译器兼容,否则会出现大量“未定义符号”错误。

如果插件编译成功但随后无法加载,请按照以下步骤排查原因:

  1. 确保插件位于正确的目录中。您可以使用 QApplication::libraryPaths() 来确定 Qt 搜索插件的位置。
  2. 确保系统上已安装该数据库管理系统的客户端库。在 Unix 系统上,运行命令 `ldd ` 并将插件名称作为参数传入,例如 `ldd libqsqlmysql.so`。如果任何客户端库无法找到,系统会发出警告。 在 Windows 系统上,您可以使用 Visual Studio 的依赖关系分析器(Dependency Walker)或Dependencies GUI来查找依赖的库。通过Qt Creator ,您可以在“项目”面板的“运行”部分更新PATH 环境变量,以包含客户端库所在文件夹的路径。
  3. 使用 MSVC 时,还请确保插件采用正确的构建类型进行构建。由于 MSVC 的调试版和发布版运行时不同,Qt 调试版构建无法加载 Qt 发布版插件,反之亦然。
  4. 在运行已编译的 Qt 可执行文件时,请设置QT_DEBUG_PLUGINS环境变量,以便在加载插件时获得非常详细的调试输出。
  5. 若要获取来自 SQL 子系统的可能调试消息,请将环境变量QT_LOGGING_RULES 设置为qt.sql.*.debug=true 以启用输出。在 Windows 上工作时,请勿忘记启用控制台。有关如何设置日志规则的更详细说明,请参阅Logging Rules 。

请确保您已按照《插件部署指南》进行操作。

如何编写自己的数据库驱动程序

QSqlDatabase 负责加载和管理数据库驱动程序插件。当添加数据库时(参见QSqlDatabase::addDatabase()),系统会加载相应的驱动程序插件(使用QSqlDriverPlugin )。QSqlDatabase 依赖于驱动程序插件来提供QSqlDriver 和QSqlResult 的接口。

QSqlDriver 是一个抽象基类,定义了 SQL 数据库驱动程序的功能。这包括QSqlDriver::open() 和QSqlDriver::close() 等函数。QSqlDriver 负责连接数据库、建立适当的环境等。此外,QSqlDriver 可以创建适合特定数据库 API 的QSqlQuery 对象。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 插件》。您还可以参考 Qt 随附的 SQL 插件(位于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); }
};

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.