数据库SQLite在Qt5+VS2012使用规则总结---中文乱码

  VS2012默认格式为 "GB2312-80",而有时我们用到字符串需要显示中文时,就会出现乱码。下面仅就Qt5和VS2012中使用数据库SQLite时,做一个简单的备忘录

  1 #include <QtWidgets/QApplication>
  2 #include <QtCore>
  3 #include <QTextCodec>
  4 #include <QSqlDatabase>
  5 #include <QMessageBox>
  6 #include <QSqlQuery>
  7 #include <QTime>
  8 #include <QSqlError>
  9 #include <QSqlDriver>
 10 #include <QSqlRecord>
 11 #include <QtDebug>
 12 
 13 
 14 int main(int argc, char *argv[])
 15 {
 16     QApplication a(argc, argv);
 17     
 18     QFile::remove("qtDB.db");    //it's very necessary to testing many times! 
 19 
 20     QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
 21     db.setHostName("easybook-3313b0");          //设置数据库主机名
 22     db.setDatabaseName("qtDB.db");              //设置数据库名,setHostName/setDatabaseName/setUserName/setPassword是非必须的
 23     //因为在Qt中,由于QSQLITE数据库驱动对应的SQLite数据库是一种进程内的本地数据库,无需数据库名、用户名、密码、主机名和端口等特性
 24     db.setUserName("zhouhejun");                //设置数据库用户名
 25     db.setPassword("123456");                   //设置数据库密码
 26     db.open();                                     //打开连接
 27 
 28     //创建数据库表automobile1------一个数据库中可以创建多个互不重名的数据库表
 29     QSqlQuery query1;
 30     bool success1 = query1.exec("create table automobile1(id int primary key,attribute varchar(100),type varchar(100),kind varchar(100),nation int,carnumber int,elevaltor int,distance int,oil int,temperature int)");
 31 
 32     if (success1)
 33         qDebug() <<"Create automobile1 Successful";
 34     else
 35         qDebug() <<"Create automobiles1 Fail";
 36 
 37     //创建数据库表automobile
 38     QSqlQuery query;
 39     bool success = query.exec("create table automobile(id int primary key,attribute varchar(100),type varchar(100),kind varchar(100),nation int,carnumber int,elevaltor int,distance int,oil int,temperature int)");
 40     
 41     if (success)
 42         qDebug() << "Create automobile Successful";
 43     else
 44         qDebug() << "Create automobiles Fail";
 45 
 46     //查询
 47     query.exec("select * from automobile");
 48     QSqlRecord rec = query.record();
 49     qDebug() << "automobile records' num:" << rec.count();
 50 
 51     //插入记录
 52     QTime t;
 53     t.start();
 54 
 55     //像这种带有string类型的table,进行插入元组时,应带有QString::fromLocal8Bit("insert into...")才能保证正确显示.
 56     //元组0中因为没有加QString::fromLocal8Bit(...),所以string类型显示不全或乱码
 57     success = query.exec(("insert into automobile values( 0, '四轮','轿车','富康',123,123,123,123,123,123)"));
 58     if (!success)
 59     {
 60         QSqlError lastError = query.lastError();
 61         qDebug() << lastError.driverText() << "insert row 0 failed";
 62     }
 63 
 64     //元组1中的string类型均可显示成功
 65     //值得注意的是,如果直接使用这种query.exec(...)进行插入元组时,里面所有的列元素必须是确定的,可以带有计算,但不能带入函数
 66     success = query.exec(QString::fromLocal8Bit("insert into automobile values( 1, '四轮','轿车','富康',(6+6)*12/3,123,123,123,123,123)"));
 67     if (!success)
 68     {
 69         QSqlError lastError = query.lastError();
 70         qDebug() << lastError.driverText() << "insert row 1 Failed";
 71     }
 72 
 73     //元组2插入失败
 74     success = query.exec(QString::fromLocal8Bit("insert into automobile values( 2, '四轮','轿车','富康',rand() % 100 ,123,123,123,123,123)"));
 75     if (!success)
 76     {
 77         QSqlError lastError = query.lastError();
 78         qDebug() << lastError.driverText() << "insert row 2 Failed";
 79     }
 80 
 81     //如果直接使用这种query.exec(...)进行插入元组时,id/nation等int类型的数据,则必须是具体已确定的数值,而不能用变量进行替代;
 82     //元组3插入失败
 83     int fourthRowId = 3;
 84     success = query.exec(QString::fromLocal8Bit("insert into automobile values(fourthRowId, '四轮','轿车','富康',123,123,123,123,123,123)"));
 85     if (!success)
 86     {
 87         QSqlError lastError = query.lastError();
 88         qDebug() << lastError.driverText() << "insert row 3 Failed";
 89     }
 90 
 91     //同上,元组4插入失败
 92     int thirdRowNation = rand() % 100;
 93     success = query.exec(QString::fromLocal8Bit("insert into automobile values( 4, '四轮','轿车','富康',thirdRowNation,123,123,123,123,123)"));
 94     if (!success)
 95     {
 96         QSqlError lastError = query.lastError();
 97         qDebug() << lastError.driverText() << "insert row 4 Failed";
 98     }
 99     
100     //另外一种query.exec();可以通过query.prepare()进行预插值,然后通过query.bindValue(...)进行数据绑定,
101     //这种方式更加随性一些,因为插入元组的列元素可以是变量,也可以是符合条件的函数
102     query.prepare(QString::fromLocal8Bit("insert into automobile values(?,?,?,?,?,?,?,?,?,?)"));
103     int records1 = 10;
104     for (int i = 0; i < records1; i++)
105     {
106         
107         query.bindValue(0, i+5);    ////ok, 可以正确显示
108         query.bindValue(1, "四轮");     //完全显示不出来
109         query.bindValue(2, QString::fromLocal8Bit("轿车"));  //ok,可以正确显示
110         query.bindValue(3, '富康');    //单引号,可以显示,但是显示错误
111         query.bindValue(4, (6+8)*12/4);    //显示42,ok,可以正确显示
112         query.bindValue(5, rand() % 10000);  //ok, 可以正确显示
113         query.bindValue(6, rand() % 300);
114         query.bindValue(7, rand() % 200000);
115         query.bindValue(8, rand() % 52);
116         query.bindValue(9, rand() % 100);
117 
118         success = query.exec();
119         if (!success)
120         {
121             QSqlError lastError = query.lastError();
122             qDebug() << lastError.driverText() << "insert row " << i + 5 << "Failed";
123         }
124     }
125     qDebug() << "first insert " << records1 << " records, time:" << t.elapsed() << " ms"; 
126 
127     
128 
129 
130     //query.prepare(QString::fromLocal8Bit("insert into automobile values(?,?,?,?,?,?,?,?,?,?)"))中的QString::fromLocal8Bit在此没有作用,可以不加
131     query.prepare(("insert into automobile values(?,?,?,?,?,?,?,?,?,?)"));
132 
133     long records2 = 10;
134     for (int i = 0; i < records2; i++)
135     {
136 
137         query.bindValue(0, i + records1 + 5);
138         query.bindValue(1, QString::fromLocal8Bit("四轮"));
139         query.bindValue(2, QString::fromLocal8Bit("轿车"));          
140         query.bindValue(3, QString::fromLocal8Bit("富康"));   //结合以上可以看出,在当前环境下,使用字符串显示中文,需在中文字符的外面加上QString::fromLocal8Bit
141         query.bindValue(4, rand() % 100);
142         query.bindValue(5, rand() % 10000);
143         query.bindValue(6, rand() % 300);
144         query.bindValue(7, rand() % 200000);
145         query.bindValue(8, rand() % 52);
146         query.bindValue(9, rand() % 100);
147 
148         success = query.exec();
149         if (!success)
150         {
151             QSqlError lastError = query.lastError();
152             qDebug() << lastError.driverText() << "insert row" << i + records1 + 5 << "Failed"; 
153         }    
154     }
155 
156     qDebug() << "second insert " << records2 << " records, time:" << t.elapsed() << " ms";
157     
158     db.close();
159 
160     return a.exec();
161 }

  输出消息为:

  可以看到行号为2、3、4的插入元组的操作失败。

  上述操作在数据库中的显示如下:

  在上述的L156行的qDebug() << "second insert " << records2 << " records, time:" << t.elapsed() << " ms";下方添加如下代码:

 1 //更新记录
 2     t.restart();
 3     for (int i = 0; i < 5+records1; i++)
 4     {
 5         query.clear();
 6         query.prepare(QString("update automobile set attribute=?,type=?,"
 7             "kind=?,nation=?,"
 8             "carnumber=?,elevaltor=?,"
 9             "distance=?,oil=?,"
10             "temperature=? where id=%1").arg(i));
11 
12         query.bindValue(0, QString::fromLocal8Bit("四轮"));
13         query.bindValue(1, QString::fromLocal8Bit("轿车"));
14         query.bindValue(2, QString::fromLocal8Bit("富康"));
15         query.bindValue(3, rand() % 100);
16         query.bindValue(4, rand() % 10000);
17         query.bindValue(5, rand() % 300);
18         query.bindValue(6, rand() % 200000);
19         query.bindValue(7, rand() % 52);
20         query.bindValue(8, rand() % 100);
21 
22         success = query.exec();
23         if (!success)
24         {
25             QSqlError lastError = query.lastError();
26             qDebug() << lastError.driverText() <<"update Failed";
27         }
28     }
29     qDebug() << "update " << 5 + records1 << " records,elapsed time:" << t.elapsed() << " ms";
30 
31 
32     //排序
33     t.restart();
34     success = query.exec("select * from automobile order by id desc");
35     if (success)
36         qDebug() << "Sort " << 5 + records1 + records2 << " records, time:" << t.elapsed() << " ms";
37     else
38         qDebug() << "Sort Failed!";
39 
40     //删除
41     t.restart();
42     query.exec("delete from automobile where id=15");
43     qDebug() << "delete one record, elapsed time: " << t.elapsed() << " ms";

  则上述所有操作在数据库中的最终显示如下:

  可以看出,前15行经过更新,可以正常显示;id=15的元组也已经被删除。

posted on 2016-07-20 15:30  阿珩  阅读(2662)  评论(1编辑  收藏  举报