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

时间:2023-03-09 05:29:39
数据库SQLite在Qt5+VS2012使用规则总结---中文乱码

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

 #include <QtWidgets/QApplication>
#include <QtCore>
#include <QTextCodec>
#include <QSqlDatabase>
#include <QMessageBox>
#include <QSqlQuery>
#include <QTime>
#include <QSqlError>
#include <QSqlDriver>
#include <QSqlRecord>
#include <QtDebug> int main(int argc, char *argv[])
{
QApplication a(argc, argv); QFile::remove("qtDB.db"); //it's very necessary to testing many times! QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setHostName("easybook-3313b0"); //设置数据库主机名
db.setDatabaseName("qtDB.db"); //设置数据库名,setHostName/setDatabaseName/setUserName/setPassword是非必须的
//因为在Qt中,由于QSQLITE数据库驱动对应的SQLite数据库是一种进程内的本地数据库,无需数据库名、用户名、密码、主机名和端口等特性
db.setUserName("zhouhejun"); //设置数据库用户名
db.setPassword(""); //设置数据库密码
db.open(); //打开连接 //创建数据库表automobile1------一个数据库中可以创建多个互不重名的数据库表
QSqlQuery query1;
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)"); if (success1)
qDebug() <<"Create automobile1 Successful";
else
qDebug() <<"Create automobiles1 Fail"; //创建数据库表automobile
QSqlQuery query;
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)"); if (success)
qDebug() << "Create automobile Successful";
else
qDebug() << "Create automobiles Fail"; //查询
query.exec("select * from automobile");
QSqlRecord rec = query.record();
qDebug() << "automobile records' num:" << rec.count(); //插入记录
QTime t;
t.start(); //像这种带有string类型的table,进行插入元组时,应带有QString::fromLocal8Bit("insert into...")才能保证正确显示.
//元组0中因为没有加QString::fromLocal8Bit(...),所以string类型显示不全或乱码
success = query.exec(("insert into automobile values( 0, '四轮','轿车','富康',123,123,123,123,123,123)"));
if (!success)
{
QSqlError lastError = query.lastError();
qDebug() << lastError.driverText() << "insert row 0 failed";
} //元组1中的string类型均可显示成功
//值得注意的是,如果直接使用这种query.exec(...)进行插入元组时,里面所有的列元素必须是确定的,可以带有计算,但不能带入函数
success = query.exec(QString::fromLocal8Bit("insert into automobile values( 1, '四轮','轿车','富康',(6+6)*12/3,123,123,123,123,123)"));
if (!success)
{
QSqlError lastError = query.lastError();
qDebug() << lastError.driverText() << "insert row 1 Failed";
} //元组2插入失败
success = query.exec(QString::fromLocal8Bit("insert into automobile values( 2, '四轮','轿车','富康',rand() % 100 ,123,123,123,123,123)"));
if (!success)
{
QSqlError lastError = query.lastError();
qDebug() << lastError.driverText() << "insert row 2 Failed";
} //如果直接使用这种query.exec(...)进行插入元组时,id/nation等int类型的数据,则必须是具体已确定的数值,而不能用变量进行替代;
//元组3插入失败
int fourthRowId = ;
success = query.exec(QString::fromLocal8Bit("insert into automobile values(fourthRowId, '四轮','轿车','富康',123,123,123,123,123,123)"));
if (!success)
{
QSqlError lastError = query.lastError();
qDebug() << lastError.driverText() << "insert row 3 Failed";
} //同上,元组4插入失败
int thirdRowNation = rand() % ;
success = query.exec(QString::fromLocal8Bit("insert into automobile values( 4, '四轮','轿车','富康',thirdRowNation,123,123,123,123,123)"));
if (!success)
{
QSqlError lastError = query.lastError();
qDebug() << lastError.driverText() << "insert row 4 Failed";
} //另外一种query.exec();可以通过query.prepare()进行预插值,然后通过query.bindValue(...)进行数据绑定,
//这种方式更加随性一些,因为插入元组的列元素可以是变量,也可以是符合条件的函数
query.prepare(QString::fromLocal8Bit("insert into automobile values(?,?,?,?,?,?,?,?,?,?)"));
int records1 = ;
for (int i = ; i < records1; i++)
{ query.bindValue(, i+); ////ok, 可以正确显示
query.bindValue(, "四轮"); //完全显示不出来
query.bindValue(, QString::fromLocal8Bit("轿车")); //ok,可以正确显示
query.bindValue(, '富康'); //单引号,可以显示,但是显示错误
query.bindValue(, (+)*/); //显示42,ok,可以正确显示
query.bindValue(, rand() % ); //ok, 可以正确显示
query.bindValue(, rand() % );
query.bindValue(, rand() % );
query.bindValue(, rand() % );
query.bindValue(, rand() % ); success = query.exec();
if (!success)
{
QSqlError lastError = query.lastError();
qDebug() << lastError.driverText() << "insert row " << i + << "Failed";
}
}
qDebug() << "first insert " << records1 << " records, time:" << t.elapsed() << " ms"; //query.prepare(QString::fromLocal8Bit("insert into automobile values(?,?,?,?,?,?,?,?,?,?)"))中的QString::fromLocal8Bit在此没有作用,可以不加
query.prepare(("insert into automobile values(?,?,?,?,?,?,?,?,?,?)")); long records2 = ;
for (int i = ; i < records2; i++)
{ query.bindValue(, i + records1 + );
query.bindValue(, QString::fromLocal8Bit("四轮"));
query.bindValue(, QString::fromLocal8Bit("轿车"));
query.bindValue(, QString::fromLocal8Bit("富康")); //结合以上可以看出,在当前环境下,使用字符串显示中文,需在中文字符的外面加上QString::fromLocal8Bit
query.bindValue(, rand() % );
query.bindValue(, rand() % );
query.bindValue(, rand() % );
query.bindValue(, rand() % );
query.bindValue(, rand() % );
query.bindValue(, rand() % ); success = query.exec();
if (!success)
{
QSqlError lastError = query.lastError();
qDebug() << lastError.driverText() << "insert row" << i + records1 + << "Failed";
}
} qDebug() << "second insert " << records2 << " records, time:" << t.elapsed() << " ms"; db.close(); return a.exec();
}

  输出消息为:

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

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

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

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

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

 //更新记录
t.restart();
for (int i = ; i < +records1; i++)
{
query.clear();
query.prepare(QString("update automobile set attribute=?,type=?,"
"kind=?,nation=?,"
"carnumber=?,elevaltor=?,"
"distance=?,oil=?,"
"temperature=? where id=%1").arg(i)); query.bindValue(, QString::fromLocal8Bit("四轮"));
query.bindValue(, QString::fromLocal8Bit("轿车"));
query.bindValue(, QString::fromLocal8Bit("富康"));
query.bindValue(, rand() % );
query.bindValue(, rand() % );
query.bindValue(, rand() % );
query.bindValue(, rand() % );
query.bindValue(, rand() % );
query.bindValue(, rand() % ); success = query.exec();
if (!success)
{
QSqlError lastError = query.lastError();
qDebug() << lastError.driverText() <<"update Failed";
}
}
qDebug() << "update " << + records1 << " records,elapsed time:" << t.elapsed() << " ms"; //排序
t.restart();
success = query.exec("select * from automobile order by id desc");
if (success)
qDebug() << "Sort " << + records1 + records2 << " records, time:" << t.elapsed() << " ms";
else
qDebug() << "Sort Failed!"; //删除
t.restart();
query.exec("delete from automobile where id=15");
qDebug() << "delete one record, elapsed time: " << t.elapsed() << " ms";

  则上述所有操作在数据库中的最终显示如下:
数据库SQLite在Qt5+VS2012使用规则总结---中文乱码

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