qt生成达梦oci的一个坑

博客讲述了在使用Qt连接达梦数据库时遇到的问题及解决方案。首先,尝试将oci.dll放入qt的sqldrivers目录下,但仍然出现驱动未加载的错误。接着,通过将达梦bin目录引入到Qt工程,错误变为无法登录(3113,创建socket失败)。作者发现需要修改qt源码qsql_oci.cpp,将连接字符串改为只包含IP和端口的格式,并确保达梦默认端口5236已打开。最后,问题得到解决,成功连接达梦数据库。

根据其他人的经验可以成功生成达梦的oci,但是将oci.dll文件放在qt的sqldrivers文件夹内还是会报错,driver not loaded,此时将达梦的bin引入到qt工程中,报错变成了(3113,cannot logon,创建socket失败),
这里就要转到qt的oci工程下,修改qsql_oci.cpp文件,C:\Qt\Qt5.9.6\5.9.6\Src\qtbase\src\plugins\sqldrivers\oci;

修改函数bool QOCIDriver::open(const QString & db,
const QString & user,
const QString & password,
const QString & hostname,
int port,
const QString &opts)
{…
将 QString::fromLatin1(“(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(Host=%1)(Port=%2))(CONNECT_DATA=(SID=%3)))”).arg(hostname).arg((port > -1 ? port : 1521)).arg(db);

修改为QString::fromLatin1(“%1:%2”).arg(hostname).arg((port > -1 ? port : 1521));//用于DM
//
}
参数只写ip:端口号,这里和Oracle是不同。
感谢KingRing的指导,后面查看达梦的手册,就只看到参数只写hostname也是能连上,前提是已经打开了默认端口5236,

<think>好的,我现在需要帮助用户解决在Qt中重新连接达梦数据库的问题。用户之前已经询问过连接方法,现在可能遇到了连接断开或需要重新连接的情况。首先,我得回顾之前的引用内容,看看有没有相关的信息。 根据引用[1]和[3],Qt连接达梦通常使用ODBC方式,配置数据库连接字符串,并确保unixODBC正确安装。引用[4]提到了OCI方式,可能需要动态库的路径配置。用户现在的问题是如何重新连接,可能需要关闭现有连接再重新打开,或者处理连接状态。 可能的解决方案包括: 1. 显式关闭现有连接后再重新初始化。 2. 使用不同的连接名称来创建新连接,避免冲突。 3. 在连接失败时实现自动重连机制,比如定时检查连接状态。 4. 确保每次连接前释放资源,比如删除旧的QSqlDatabase实例。 需要注意Qt的QSqlDatabase连接管理,多个连接需要不同的名称,否则会复用同一连接。用户可能在重新连接时没有正确关闭或清理之前的连接,导致问题。此外,ODBC或OCI的配置是否正确,比如数据库名称、端口、驱动路径等,也需要检查。 可能还需要引用中的内容来支持解决方案,比如引用[2]提到的配置文件和环境设置,确保动态库正确。如果用户的环境有变化,可能需要重新配置unixODBC或者OCI的路径。 另外,代码示例可能会有帮助,比如如何关闭连接,使用新的连接名称,或者处理错误并重试。需要确保用户了解如何正确管理数据库连接的生命周期,避免资源泄漏。 最后,生成相关问题时要围绕重新连接可能涉及的方面,比如连接池、错误处理、多线程环境下的连接管理等。</think>关于Qt中实现达梦数据库重新连接的解决方案,可按照以下步骤操作: ### 一、核心实现方法 1. **显式关闭现有连接** ```cpp QString connectionName = QSqlDatabase::database().connectionName(); QSqlDatabase::removeDatabase(connectionName); // 必须最后执行的操作 QSqlDatabase::closeAllDatabases(); ``` 2. **使用动态连接名重建连接** ```cpp QString newConnName = QString("DM_%1").arg(QDateTime::currentMSecsSinceEpoch()); QSqlDatabase db = QSqlDatabase::addDatabase("QODBC", newConnName); db.setDatabaseName("DM7_5236"); // 对应ODBC配置 if(db.open("SYSDBA", "SYSPASSWORD")) { qDebug() << "Reconnected successfully"; } ``` *注意:Qt要求同一线程内同名连接只能存在一个实例[^3]* ### 二、完整重连流程 1. 检查连接状态 ```cpp bool checkConnection(QSqlDatabase &db) { if(!db.isOpen() || !db.isValid()) { db.close(); QSqlDatabase::removeDatabase(db.connectionName()); return false; } return true; } ``` 2. 带错误处理的重连实现 ```cpp void reconnectDM(QString odbcName) { static int retryCount = 0; QSqlDatabase db = QSqlDatabase::database(); if(!checkConnection(db)) { if(retryCount < 3) { QSqlDatabase newDb = QSqlDatabase::addDatabase("QODBC", QString("DM_RETRY_%1").arg(retryCount++)); newDb.setDatabaseName(odbcName); if(newDb.open("SYSDBA", "SYSPASSWORD")) { // 更新全局数据库引用 QSqlDatabase::setDatabase(newDb); } } else { qCritical() << "Maximum retries exceeded"; } } } ``` ### 三、环境配置要点 1. **ODBC驱动验证** ```bash isql DM7_5236 SYSDBA SYSPASSWORD # 验证ODBC连通性[^3] ``` 2. **动态库配置** 需包含达梦的`dmoci`库文件,在`.pro`文件中添加: ```makefile LIBS += -L$$PWD/dmoci -ldmoci INCLUDEPATH += $$PWD/dmoci/include ``` *路径需根据实际安装位置调整[^4]* ### 四、常见问题处理 | 现象 | 解决方案 | |-------|--------| | QODBC3: Unable to reconnect | 检查ODBC配置文件`/etc/odbc.ini`的DSN配置[^2] | | Driver not loaded | 确认`libodbc.so`和`libdmdpi.so`在LD_LIBRARY_PATH中[^3] | | Connection timeout | 在连接字符串添加`LoginTimeout=30`参数 |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值