目录

Qt开发-使用-ODBC-连接数据库遇到的坑

Qt开发 - 使用 ODBC 连接数据库遇到的坑

Qt开发 - 使用 ODBC 连接数据库遇到的坑

遇到的问题

学习了 Qt 中,正好学到了数据库的连接,看了点内容挥挥手去编代码,使用 ODBC ,结果连不上数据库。怀疑是驱动的问题,废了老大劲去编译 MySQL 数据库驱动,结果跟这玩意没有关系。归根到底还是 C++ 类的内核本质。

问题代码

这是一段错误代码

这里创建了一个数据库对象指针,然后用数据库对象指针进行数据库的 IP、端口、账号、密码赋值,然后使用 ODBC 连接数据库。

#if 0
    QSqlDatabase *database = new QSqlDatabase();
    database->addDatabase("QODBC");
    database->setHostName("127.0.0.1");
    database->setPort(3306);
    database->setDatabaseName("MySQL");
    database->setUserName("root");
    database->setPassword("@mysql");

    if(database->open()){
    	QMessageBox::information(this,"恭喜","数据库连接成功");
    }else{
    	QMessageBox::warning(this,"提示","数据库连接失败");
    }

#endif
运行结果

database->open() 的结果是 false,弹出了如下窗口,显然我的数据库连接失败。

https://i-blog.csdnimg.cn/blog_migrate/636eac282dfb6de9d7af4bb5897442db.png#pic_center

查找问题

驱动?(否)

这里我使用 database->lastError() 在打开数据库之后,来获取数据库遇到的错误。

此外还使用 QSqlDatabase::drivers() 来获取 Qt 支持的数据库驱动。

代码做出了一点点修改。

 bool is_OK = database->open();
qDebug()<<database->lastError().text()<<endl;
QStringList qsl= QSqlDatabase::drivers();
qDebug()<<qsl.join(",")<<endl;
if(is_OK){
QMessageBox::information(this,"恭喜","数据库连接成功");
}else{
QMessageBox::warning(this,"提示","数据库连接失败");
}

得到的结果:

数据库还是连接不上,这里得到了一些信息。

“Driver not loaded Driver not loaded”

“QSQLITE,QMYSQL,QMYSQL3,QODBC,QODBC3,QPSQL,QPSQL7”

这里说明了一件事情,我用来连接数据库的驱动也许有问题。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dEbMweuO-1688549887898)(C:\Users\UZALWONG\AppData\Roaming\Typora\typora-user-images\image-20230705160917105.png)]

然后我就在互联网上挖呀挖呀,“ODBC 驱动出问题怎么办?”、“Driver not loaded Qt 数据库”。

当然并不是驱动那一回事。

数据库对象的赋值?(对)

我按网上的内容来拷贝驱动、编译驱动,结果还是一样的结果,我开始绝望了。

等等,我的驱动文件夹里有 ODBC 的驱动。

https://i-blog.csdnimg.cn/blog_migrate/8dd28b1dee9910253db45e5b47418b30.png#pic_center

那问题出在哪里呢?

这时我又增加了一段代码

qDebug()<<database->databaseName()<<endl;

我发现这里输出的值竟然为空,感情我给数据库对象的赋值没成功。

https://i-blog.csdnimg.cn/blog_migrate/32593e74bf9c9d3b41e83cff8b680a28.png#pic_center

这时我参考了其他的 Qt 使用 ODBC 连接数据库的案例,好家伙,就我一个用数据库对象指针。

然后,我把原来的数据库对象指针全换成对象标识符了。

解决方法

将数据库对象指针全换成普通的对象标识符。

#if 1
QSqlDatabase database = QSqlDatabase::addDatabase("QODBC");
database.setHostName("127.0.0.1");
database.setPort(3306);
database.setDatabaseName("MySQL");
database.setUserName("root");
database.setPassword("@mysql");

    if(database.open()){
    	QMessageBox::information(this,"恭喜","数据库连接成功");
    }else{
    	QMessageBox::warning(this,"提示","数据库连接失败");
    }
    qDebug()<<database.databaseName()<<endl;

#endif

运行结果:

https://i-blog.csdnimg.cn/blog_migrate/8a4b454469d1c29ce7b5167fc0fcc384.png#pic_center

这里的 database.databaseName() 的内容是我在 ODBC 中设置的 MySQL 的,数据库连接成功了。

为什么?

addDatabase() 是静态方法
[static] QSqlDatabase QSqlDatabase::addDatabase(QSqlDriver *driver, const QString &connectionName = QLatin1String(defaultConnection))

addDatabase() 是一个静态函数,它不属于任何一个 QSqlDatabase 对象 ,而是属于 QSqlDatabase 类 。静态函数只能通过类名来调用,不能通过对象或指针来调用。这里应该把数据库对象定义为一个普通对象而不是对象指针,因为指针操作很复杂。

QSqlDatabase database = QSqlDatabase::addDatabase("QODBC"); // 定义为普通对象
QSqlDatabase database = QSqlDatabase(); // 定义为指针
database = &QSqlDatabase::addDatabase("QODBC");

这里 addDatabase("QODBC") 产生的地址是一个临时变量,到头来 database 指向的是空指针,所以没有调用成功 ODBC 的驱动。