【Qt】Sqlite


首先複習一下 sqlite shell 的用法,驗證幾個重點

【Sqlite】

  • Sqlite 支援的資料型態
    • TEXT
    • NUMERIC
    • INTEGER
    • REAL
    • NONE(BOOL)
  • 基本操作,假設我們要建立一個像下面一樣的資料庫來記錄姓名,
    中間混合繁體中文(Big5所謂的許功蓋問題),英文(Chen)與俄文(Ира)。
      firstname(名) lastname(姓)
    第一筆資料 功蓋
    第二筆資料 Ира Chen
  • 首先進入sqlite ,先建立名為 p.db 的資料庫來儲存上面資料。
    $ sqlite3 p.db
    SQLite version 3.6.16
    Enter ".help" for instructions
    Enter SQL statements terminated with a ";"
  • create: 先建立資料表,一個資料庫裡面可以有許多資料表。
    sqlite> create table person (firstname varchar(20), lastname varchar(20));
  • 列出資料表,確定上個動作已經是成功的。
    sqlite> .table
    person
  • 列出 schema,確認所建立的欄位。 
    sqlite> .schema person
    CREATE TABLE person (firstname varchar(20), lastname varchar(20));
  • insert: 開始新增我們所需要的那兩筆資料。
    sqlite> insert into person values('功蓋', '許');
    sqlite> insert into person values('Ира', 'Chen');
  • select: 查詢rowid
    sqlite> select rowid from person;
    1
    2
  • select: 查詢資料,確定新增兩筆資料成功。
    sqlite> select * from person;
    功蓋|許
    ира|Chen
  • where: 利用 select 配合 where 查詢符合姓為 Chen 這個人的資料。
    sqlite> select * from person where lastname='Chen';
    ира|Chen
  • 建立視圖,可區別一般使用者或管理者所要看到的資料。
    sqlite> create view pv as select lastname from person;
    sqlite> select * from pv;
    許
    Chen
  • 更新,把 Ира Chen 改成 May Chen。 
    sqlite> 
    sqlite> update person set firstname='May' where lastname='Chen';
    sqlite> select * from person;
    功蓋|許
    May|Chen
  • 刪除,把 第二筆資料刪除,這樣就只剩下 許功蓋 這個人
    sqlite> delete from person where lastname='Chen';
    sqlite> select * from person;
    功蓋|許
  • 新增欄位,假設我們新增加一個 id 的欄位
    sqlite> alter table person add id integer;
    sqlite>  .schema person
    CREATE TABLE person(firstname varchar(20), lastname varchar(20), id integer);
  • 刪除欄位
    目前好像不支援。 (http://www.sqlite.org/lang_altertable.html)
    解決想法是整個 table 刪掉並重建欄位。
    (1) 更名原始資料表,如由 table 改成 table_tmp  (2) 建立新Table,新Table是不包含要刪除的欄位的。
    (3) 由備份的 table_tmp 整個倒入新 table,不包含要拿掉欄位的資料。
  • 更名欄位
    目前好像不支援。 解決方式同上。只是在建立新table時,作欄位更名的動作。
  • 更名資料表,將 person 資料表改名成 p 資料表。 
    sqlite> alter table person remane to p;
    sqlite> .schema p
    CREATE TABLE "p"(firstname varchar(20), lastname varchar(20), id integer);
  • 資料庫匯出(未驗證)
    $sqlite3 p.db “.dump” > p.sql
  • 資料庫匯入(未驗證)
    $ sqlite3 p.db < p.sql
  • 離開
    sqlite> .quit 
    $ 

【Sqliteman】

  • 除了 sqlite shell 以外,還可以使用一套據說是 QT 寫的 sqliteman http://sqliteman.com/ 來觀察剛剛的結果。運行結果如下。可以看到 Tables 與 Views。
    image
  • 有時作者並不一定會在現行版本發行Windows版本,就要往回找之前發行的版本。
    下載網址 http://sourceforge.net/projects/sqliteman/files/image

【C】

在 C 的使用 (目前沒有用C特別處理 Unicode的問題,參考 http://evanjones.ca/unicode-in-c.html)

  1. 安裝套件
    $ apt-get install libsqlite3-dev
  2. 程式碼( 存成 p.c )
    #include <stdio.h> 
    #include <sqlite3.h>
     
    static int callback(void *NotUsed, int argc, char **argv, char **azColName){ 
    int i; 
    for(i=0; i<argc; i++){ 
    printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL"); 
    } 
    printf("\n"); 
    return 0; 
    } 
     
    int main(int argc, char **argv){ 
    sqlite3 *db; 
    char *zErrMsg = 0; 
    int rc; 
     
    if( argc!=3 ){ 
    fprintf(stderr, "Usage: %s DATABASE SQL-STATEMENT\n", argv[0]); 
    return 1;
    } 
    rc = sqlite3_open(argv[1], &db); 
    if( rc ){ 
    fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db)); 
    sqlite3_close(db); 
    return 1; 
    } 
    rc = sqlite3_exec(db, argv[2], callback, 0, &zErrMsg); 
    if( rc!=SQLITE_OK ){ 
    fprintf(stderr, "SQL error: %s\n", zErrMsg); 
    sqlite3_free(zErrMsg); 
    } 
    sqlite3_close(db); 
    return 0; 
    }
  3. 編譯(注意要加 –lsqlite3)
    $ gcc -o p p.c –lsqlite3 
  4. 執行
    $./p p.db "select * from person;"
    firstname = 功蓋
    lastname = 許
    id = NULL
    
    firstname = ира
    lastname = Chen
    id = NULL

【Qt】
配合QT的使用。其中需要注意的是,Sqlite內部編碼為 unicode, 而Qt 我們指定為 UTF-8。
Qt 寫入 Sqlite 需先將內容轉換成 Unicode,而Qt 讀取Sqlite時不需要,因 Qt 會自行偵測。
以下只擷取出重點程式碼。

  1. 記得載入 QtSql module。
    image
  2. dialog.h ( include  部分)
    #include <QtSql>
    #include <QTableView>
    #include <QMessageBox>
  3. dialog.cpp
    bool Dialog::SqliteTest()
    {
    
        QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
        db.setDatabaseName("database.dat");
        if (!db.open())
        {
            QMessageBox::warning(0, QObject::tr("Database Error"),
                                 db.lastError().text());
            return false;
        }
        QSqlQuery rs(db);
        rs.exec("CREATE TABLE person (firstname varchar(20), lastname varchar(20))");
        QByteArray strSql("insert into person(firstname,lastname) \
                       values('Ира', 'Chen')");
        QTextCodec *codec = QTextCodec::codecForName("UTF-8");
        QString string = codec->toUnicode(strSql);
        rs.exec(string);
    
        QSqlQueryModel *model = new QSqlQueryModel;
        model->setQuery("SELECT * FROM person");
        model->setHeaderData(0, Qt::Horizontal, "firstname");
        model->setHeaderData(1, Qt::Horizontal, "lastname");
    
        QTableView *view = new QTableView;
        view->setWindowTitle("QSqlQueryModel");
        view->setModel(model);
        view->show();
    
        db.close();
    }
  4. 執行結果
    image

【參考】

 

Ed32. Copyright 2008 All Rights Reserved Revolution Two Church theme by Brian Gardner Converted into Blogger Template by Bloganol dot com