当前位置:   article > 正文

QSqlDatabase类学习笔记_qsqlquery::exec: database not open

qsqlquery::exec: database not open
QSqlDatabase类学习笔记
参考
http://blog.csdn.net/Lutx/article/details/7262123
http://blog.csdn.net/reborntercel/article/details/6991147


 #include <QtSql>
QT += sql
QSqlDatabase类实现了数据库连接的操作
QSqlQuery类执行SQL语句
QSqlRecord类封装数据库所有记录

QSqlDatabase类

如下代码:

  1. //! testMYSQLs
  2. void MainWindow::on_testMYSQL_clicked()
  3. {
  4. QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL", "localhost@3306");
  5. db.setHostName("localhost"); //数据库主机名
  6. db.setDatabaseName("databasex"); //数据库名
  7. db.setUserName("root"); //数据库用户名
  8. db.setPassword("123456"); //数据库密码
  9. bool bisOpenn = db.open(); //打开数据库连接
  10. qDebug()<<"bisOpenn="<<bisOpenn;
  11. //db.close(); //释放数据库连接
  12. }
此时出现如下错误:

  1. QSqlDatabase: QMYSQL driver not loaded
  2. QSqlDatabase: available drivers: QSQLITE QODBC3 QODBC QPSQL7 QPSQL
  3. bisOpenn= false

下面是对此问题的解决:

用qt打开  C:\Qt\4.8.5\src\plugins\sqldrivers\mysql\mysql.pro 工程,在此工程中链接  C:\Program Files (x86)\MySQL\MySQL Server 5.5\lib\libmysql.lib 库及对应的MYSQL的头文件,具体PRO代码如下 :备注:我在工程中是把 MySQL 相关文件放在桌面的 mysqlinclude 文件夹下面,原因是我的MYSQL安装路径:C:\Program Files (x86)\MySQL\MySQL Server 5.5\include\ 里面有空格,不能有空格 ,故 mysql.pro 内容如下:

  1. TARGET = qsqlmysql
  2. SOURCES = main.cpp
  3. include(../../../sql/drivers/mysql/qsql_mysql.pri)
  4. include(../qsqldriverbase.pri)
  5. win32:CONFIG(release, debug|release): LIBS += -L$$PWD/../../../../../mysqlinclude/lib/ -llibmysql
  6. else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/../../../../../mysqlinclude/lib/ -llibmysql
  7. INCLUDEPATH += $$PWD/../../../../../mysqlinclude
  8. DEPENDPATH += $$PWD/../../../../../mysqlinclude
QMAKE,编译,生成,如下图所示: -- 网上很多人都用的QMAKE之类的,在这里,其实用QT工程来编译,是最好最快最方便的一种办法 如下图所示:

生成好后,把生成好的输入COPY至 C:\Qt\4.8.5\plugins\sqldrivers 下面,即可。如下图所示:



接下来我就开始 写代码,代码如下:

  1. //! testMYSQLs
  2. void MainWindow::on_testMYSQL_clicked()
  3. {
  4. QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL", "localhost@3306");
  5. db.setHostName("localhost"); //数据库主机名
  6. db.setPort(3306);
  7. db.setDatabaseName("xdatabase"); //数据库名
  8. db.setUserName("root"); //数据库用户名
  9. db.setPassword("123456"); //数据库密码
  10. bool bisOpenn = db.open(); //打开数据库连接
  11. //db.close();
  12. if(bisOpenn==true)
  13. {
  14. QSqlQuery query;
  15. query.exec("create table test_student(id INTEGER PRIMARY KEY autoincrement,name nvarchar(20), age int)"); //id自动增加
  16. query.exec("insert into test_student values(1,'小明', 14)");
  17. query.exec("insert into student values(2,'小王',15)");
  18. }
  19. //qDebug()<<"bisOpenn="<<bisOpenn;
  20. db.close(); //释放数据库连接
  21. }
结果报错信息如下:

  1. F:\zip\testCode\debug\testCode.exe 启动中...
  2. [wificommon]开始进入....QSqlQuery::exec: database not open
  3. QSqlQuery::exec: database not open
  4. QSqlQuery::exec: database not open

解决如下:

原因:QSqlQuery 没有与 db 数据库联系起来,正确代码如下:

  1. bool MainWindow::initDataBase()
  2. {
  3. m_db = QSqlDatabase::addDatabase("QMYSQL", "localhost@3306");
  4. m_db.setHostName("localhost"); //数据库主机名
  5. m_db.setPort(3306);
  6. m_db.setDatabaseName("ljtdatabase"); //数据库名
  7. m_db.setUserName("root"); //数据库用户名
  8. m_db.setPassword("123456"); //数据库密码
  9. //bool bisOpenn = db.open(); //打开数据库连接
  10. m_bisOpenn = m_db.open(); //打开数据库连接
  11. return m_bisOpenn;
  12. }
  13. MainWindow::~MainWindow()
  14. {
  15. m_db.close();
  16. delete ui;
  17. }
  1. void MainWindow::createTable()
  2. {
  3. QSqlQuery query(m_db);
  4. QString ssql = "CREATE TABLE test_table2(id int(11) NOT NULL,Name varchar(255) DEFAULT NULL, age int(3) DEFAULT NULL,PRIMARY KEY (id)) ;";
  5. query.exec(ssql);
  6. }
上面为创建表的代码,结果如下:


下面为对SQL进行操作的一些代码及结果说明:


代码如下:

  1. //! SELECT * FROM test_table2
  2. void MainWindow::queryResTable()
  3. {
  4. QSqlQuery query(m_db);
  5. QString sel = "SELECT * FROM test_table2";
  6. query.exec(sel);
  7. while (query.next()) {
  8. qDebug()<<query.size()<<query.value(0).toInt()<<" "<<query.value(1).toString()<<" "<<query.value(2).toInt();
  9. }
  10. }
  11. //! testMYSQLs
  12. void MainWindow::on_testMYSQL_clicked()
  13. {
  14. if(m_bisOpenn==false) return;
  15. queryResTable();
  16. }
执行结果:

  1. [wificommon]开始进入....
  2. 4 1 "Name1" 10
  3. 4 2 "Name2" 20
  4. 4 3 "Name3" 30
  5. 4 4 "Name4" 40
同样的情况,代码如下:

  1. //! SELECT * FROM test_table2
  2. void MainWindow::queryResTable()
  3. {
  4. QSqlQuery query(m_db);
  5. QString sel = "SELECT * FROM test_table2";
  6. query.exec(sel);
  7. int fieldNo = query.record().indexOf("age");
  8. int fieldName = query.record().indexOf("Name");
  9. while (query.next()) {
  10. int country = query.value(fieldNo).toInt();
  11. QString sName = query.value(fieldName).toString();
  12. qDebug()<<country<<" "<<sName;
  13. }
  14. }
结果如下:

  1. 10 "Name1"
  2. 20 "Name2"
  3. 30 "Name3"
  4. 40 "Name4"

下面给表INSERT数据:代码如下:

  1. void MainWindow::bindValue1()
  2. {
  3. QSqlQuery query(m_db);
  4. query.prepare("INSERT INTO test_table2 (id, Name, age) "
  5. "VALUES (:id, :Name, :age)");
  6. query.bindValue(":id", 5);
  7. query.bindValue(":Name", "Name5");
  8. query.bindValue(":age", 50);
  9. query.exec();
  10. }
图:

另一种方法:

  1. void MainWindow::bindValue2()
  2. {
  3. QSqlQuery query(m_db);
  4. query.prepare("INSERT INTO test_table2 (id, Name, age) "
  5. "VALUES (:id, :Name, :age)");
  6. query.bindValue(0, 6);
  7. query.bindValue(1, "Name6");
  8. query.bindValue(2, 60);
  9. query.exec();
  10. }

另外一种方法:

  1. void MainWindow::bindValue3()
  2. {
  3. QSqlQuery query(m_db);
  4. query.prepare("INSERT INTO test_table2 (id, Name, age) "
  5. "VALUES (?, ?, ?)");
  6. query.bindValue(0, 7);
  7. query.bindValue(1, "Name7");
  8. query.bindValue(2, 70);
  9. query.exec();
  10. }
图:


另外一种方法:

  1. void MainWindow::bindValue4()
  2. {
  3. QSqlQuery query(m_db);
  4. query.prepare("INSERT INTO test_table2 (id, Name, age) "
  5. "VALUES (?, ?, ?)");
  6. query.addBindValue(8);
  7. query.addBindValue("Name8");
  8. query.addBindValue(80);
  9. query.exec();
  10. }
图:


下面是对存储过程的一个处理: ---- 没有验证

  1. // AsciiToInt() -- 是一个存储过程,可以把它的输入输出参数带回来
  2. void MainWindow::bindValue5()
  3. {
  4. QSqlQuery query(m_db);
  5. query.prepare("CALL AsciiToInt(?, ?)");
  6. query.bindValue(0, "A");
  7. query.bindValue(1, 0, QSql::Out);
  8. query.exec();
  9. int i = query.boundValue(1).toInt(); // i is 65
  10. }

下面这个是验证过的:创建语句

  1. create procedure qtestproc (OUT param1 INT, OUT param2 INT)
  2. BEGIN
  3. set param1 = 42;
  4. set param2 = 43;
  5. END
代码语句:

  1. void MainWindow::bindValue5()
  2. {
  3. // QSqlQuery query(m_db);
  4. // query.prepare("CALL AsciiToInt(?, ?)");
  5. // query.bindValue(0, "A");
  6. // query.bindValue(1, 0, QSql::Out);
  7. // query.exec();
  8. // int i = query.boundValue(1).toInt(); // i is 65
  9. // qDebug()<<"i="<<i;
  10. QSqlQuery q(m_db);
  11. q.exec("call qtestproc (@outval1, @outval2)");
  12. q.exec("select @outval1, @outval2");
  13. q.next();
  14. qDebug() << q.value(0) << q.value(1); // outputs "42" and "43"
  15. }
执行结果:

[wificommon]开始进入....QVariant(qlonglong, 42) QVariant(qlonglong, 43) 

下面是insert值:

  1. void MainWindow::insertValue()
  2. {
  3. QSqlQuery query(m_db);
  4. query.exec("INSERT INTO test_table2 (id, Name, age) "
  5. "VALUES (9, 'Name9', 90)");
  6. query.exec();
  7. }


insert的另外一种方法:

  1. void MainWindow::insertValue2()
  2. {
  3. QSqlQuery q(m_db);
  4. q.prepare("insert into test_table2 values (?, ?, ?)");
  5. QVariantList ints1;
  6. ints1 << 10 << 11 << 12 << 13;
  7. q.addBindValue(ints1);
  8. QVariantList names;
  9. names << "Name10" << QVariant(QVariant::String) << "Name12" << QVariant(QVariant::String);
  10. q.addBindValue(names);
  11. QVariantList ints2;
  12. ints2 << 100 << 110 << 120 << 130;
  13. q.addBindValue(ints2);
  14. if (!q.execBatch())
  15. qDebug() << q.lastError();
  16. }
图:


对事务操作:因为不支持,所以没法进行校验,如果哪种数据库支持,可以校验一下

  1. void MainWindow::transaction()
  2. {
  3. if (QSqlDatabase::database().driver()->hasFeature(QSqlDriver::Transactions))
  4. {
  5. QSqlDatabase::database().transaction();
  6. QSqlQuery query(m_db);
  7. query.exec("SELECT id FROM test_table2 WHERE age=30");
  8. if (query.next())
  9. {
  10. query.exec("UPDATE test_table2 SET Name = \"tx\" ");
  11. //query.exec("UPDATE test_table2 SET Name = \"tx\" WHERE id = 4 ");
  12. }
  13. QSqlDatabase::database().commit();
  14. }
  15. }
关于MYSQL的重连,在 void QSqlDatabase::setConnectOptions ( const QString & options = QString() ) 中有一个选项 MYSQL_OPT_RECONNECT ,还可以参考 http://stackoverflow.com/questions/6984804/mysql-reconnect-c 大体意思就是,新建一个线程,每隔1S监视数据库的情况,如果断开 ,则进行重连,然后新线程和旧线程之间通信。或者看源码介绍:https://bugreports.qt.io/browse/QTBUG-4510  https://dev.mysql.com/doc/search/?d=12&p=1&q=MYSQL_OPT_RECONNECT


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/699852
推荐阅读
相关标签
  

闽ICP备14008679号