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的元組也已經被刪除。