深入SQLite基本操作的總結詳解_Mysql

來源:互聯網
上載者:User

sqlite提供的是一些C函數介面,你可以用這些函數操作資料庫。通過使用這些介面,傳遞一些標準 sql 語句(以 char * 類型)給 sqlite 函數,sqlite 就會為你操作資料庫。sqlite 跟MS的access一樣是檔案型資料庫,就是說,一個資料庫就是一個檔案,此資料庫裡可以建立很多的表,可以建立索引、觸發器等等,但是,它實際上得到的就是一個檔案。備份這個檔案就備份了整個資料庫。 sqlite 不需要任何資料庫引擎,這意味著如果你需要 sqlite 來儲存一些使用者資料,甚至都不需要安裝資料庫。

下面開始介紹資料庫基本操作。
1、基本流程
(1)關鍵資料結構:
     sqlite 裡最常用到的是 sqlite3 * 類型。從資料庫開啟開始,sqlite就要為這個類型準備好記憶體,直到資料庫關閉,整個過程都需要用到這個類型。當資料庫開啟時開始,這個類型的變數就代表了你要操作的資料庫。下面再詳細介紹。
(2)開啟資料庫:
     int sqlite3_open( 檔案名稱, sqlite3 ** ); 用這個函數開始資料庫操作。需要傳入兩個參數,一是資料庫檔案名,比如:..\\test\\testDatabase.db。
檔案名稱不需要一定存在,如果此檔案不存在,sqlite 會自動建立它。如果它存在,就嘗試把它當資料庫檔案來開啟。 其中sqlite3 ** 參數即前面提到的關鍵資料結構。這個結構底層細節如何,你不要關它。
    函數傳回值表示操作是否正確,如果是 SQLITE_OK 則表示操作正常。相關的傳回值sqlite定義了一些宏。具體這些宏的含義可以參考 sqlite3.h 檔案。裡面有詳細定義。
(3)關閉資料庫:
    int sqlite3_close(sqlite3 *); 前面如果用 sqlite3_open 開啟了一個資料庫,結尾時不要忘了用這個函數關閉資料庫。
    sqlite資料庫操作例子

複製代碼 代碼如下:

   #include "./sqlite3.h"
    int main( int , char** )
    {
        sqlite3 * db = NULL; //聲明sqlite關鍵結構指標
        int result;
        //需要傳入 db 這個指標的指標,
        //因為 sqlite3_open 函數要為這個指標分配記憶體,還要讓db指標指向這個記憶體區
        result = sqlite3_open("..\\test\\testDatabase.db", &db);//開啟資料庫
        if( result != SQLITE_OK )
        {
            return -1; //資料庫開啟失敗
        }
        //資料庫作業碼
        //…-
        //資料庫開啟成功
        sqlite3_close( db ); //關閉資料庫
        return 0;
    }

這就是一次資料庫操作過程。

2、 SQL語句操作(如何用sqlite 執行標準 sql 文法)
(1)執行sql語句: int sqlite3_exec(sqlite3*, const char *sql, sqlite3_callback, void *, char **errmsg ); 這就是執行一條 sql 語句的函數。
 參數說明:
     第1個參數不再說了,是前面open函數得到的指標。說了是關鍵資料結構。
     第2個參數const char *sql 是一條 sql 語句,以\0結尾。
     第3個參數sqlite3_callback 是回調,當這條語句執行之後,sqlite3會去調用你提供的這個函數。
     第4個參數void * 是你所提供的指標,你可以傳遞任何一個指標參數到這裡,這個參數最終會傳到回呼函數裡面,如果不需要傳遞指標給回呼函數,可以填NULL。等下我們再看回呼函數的寫法,以及這個參數的使用。
     第5個參數char ** errmsg 是錯誤資訊。注意是指標的指標。sqlite3裡面有很多固定的錯誤資訊。執行 sqlite3_exec 之後,執行失敗時可以查閱這個指標(直接 printf("%s\n",errmsg))得到一串字串資訊,這串資訊告訴你錯在什麼地方。sqlite3_exec函數通過修改你傳入的指標的指標,把你提供的指標指向錯誤提示資訊,這樣sqlite3_exec函數外面就可以通過這個 char*得到具體錯誤提示。
      說明:通常,sqlite3_callback 和它後面的 void * 這兩個位置都可以填 NULL。填NULL表示你不需要回調。比如你做 insert 操作,做 delete 操作,就沒有必要使用回調。而當你做 select 時,就要使用回調,因為 sqlite3 把資料查出來,得通過回調告訴你查出了什麼資料。
(2)exec 的回調 :typedef int (*sqlite3_callback)(void*,int,char**, char**); 你的回呼函數必須定義成上面這個函數的類型。

sqlite資料庫操作例子:
複製代碼 代碼如下:

//sqlite3的回呼函數
     // sqlite 每查到一條記錄,就調用一次這個回調
     //para是你在 sqlite3_exec 裡傳入的 void * 參數
     //通過para參數,你可以傳入一些特殊的指標(比如類指標、結構指標),然後在這裡面強制轉換成對應的類型
     //(這裡面是void*類型,必須強制轉換成你的類型才可用)。然後操作這些資料
     //n_column是這一條記錄有多少個欄位 (即這條記錄有多少列)
     //char ** column_value 是關索引值,查出來的資料都儲存在這裡,實際上是個1維數組(不要以為是2維數組),
     //每一個元素都是一個 char * 值,是一個欄位內容(用字串來表示,以\0結尾)
     //char ** column_name 跟 column_value是對應的,表示這個欄位的欄位名稱     
      int LoadMyInfo( void * para, int n_column, char ** column_value, char ** column_name )
      {
            //這裡,我不使用 para 參數。忽略它的存在.
            int i;
            printf( "記錄包含 %d 個欄位\n", n_column );
            for( i = 0 ; i < n_column; i ++ )
            {
                printf( "欄位名:%s ?> 欄位值:%s\n", column_name[i], column_value[i] );
            }
            printf( "\n" );
            return 0;
      }

      int main( int , char ** )
      {
            sqlite3 * db;
            int result;
            char * errmsg = NULL;
            result = sqlite3_open("..\\test\\testDatabase.db", &db );
            if( result != SQLITE_OK )
            {
                return -1; //資料庫開啟失敗
            }
            //資料庫作業碼
            //建立測試表,表名叫 MyTable_1,有2個欄位: ID 和 name。其中ID是一個自動增加的類型,
            //以後insert時可以不去指定這個欄位,它會自己從0開始增加            
            result = sqlite3_exec( db, "create table MyTable_1( ID integer primary key autoincrement, name nvarchar(32) ))", NULL, NULL, errmsg );
            if(result != SQLITE_OK )
            {
               printf("建立表失敗,錯誤碼:%d,錯誤原因:%s\n", result, errmsg );
            }
            //插入一些記錄
            result = sqlite3_exec( db, "insert into MyTable_1( name) values ('走路')", 0, 0, errmsg); 
            if(result != SQLITE_OK )
          {
             printf( “插入記錄失敗,錯誤碼:%d,錯誤原因:%s\n”, result, errmsg );
           }

            result = sqlite3_exec( db,"insert into MyTable_1( name ) values ('騎單車')", 0, 0, errmsg);
            if(result != SQLITE_OK )
            {
                printf("插入記錄失敗,錯誤碼:%d,錯誤原因:%s\n", result, errmsg );
            }

            result = sqlite3_exec( db, "insert into MyTable_1( name ) values ( '坐汽車')", 0, 0, errmsg );
            if(result != SQLITE_OK )
            {
                printf( "插入記錄失敗,錯誤碼:%d,錯誤原因:%s\n", result, errmsg );
            }             
            result = sqlite3_exec( db, "select * from MyTable_1", LoadMyInfo, NULL, errmsg );//開始查詢資料庫              sqlite3_close( db ); //關閉資料庫            
            return 0;
      }

通過上面的例子,應該可以知道如何開啟一個資料庫,如何做資料庫基本操作。
(3)不使用回調查詢資料庫
     sqlite3_exec 是使用回調來執行 select 操作。還有一個方法可以直接查詢而不需要回調。但是,我個人感覺還是回調好,因為代碼可以更加整齊,只不過用回調很麻煩,你得聲明一個函數,如果這個函數是類成員函數,你還不得不把它聲明成 static 的(C++成員函數實際上隱藏了一個參數:this,C++調用類的成員函數的時候,隱含把類指標當成函數的第一個參數傳遞進去。結果,這造成跟前面說的 sqlite 回呼函數的參數不相符。只有當把成員函式宣告成 static 時,它才沒有多餘的隱含的this參數)。雖然回調顯得代碼整齊,但有時候你還是想要非回調的 select 查詢。這可以通過 sqlite3_get_table 函數做到。
    int sqlite3_get_table(sqlite3*, const char *sql, char ***resultp, int *nrow, int *ncolumn, char **errmsg );
    參數說明:
    第1個參數不再多說,看前面的例子。
    第2個參數是 sql 語句,跟 sqlite3_exec 裡的 sql 是一樣的。是一個很普通的以\0結尾的char *字串。
    第3個參數是查詢結果,它依然一維數組(不要以為是二維數組,更不要以為是三維數組)。它記憶體布局是:第一行是欄位名稱,後面是緊接著是每個欄位的值。下面用例子來說事。
    第4個參數是查詢出多少條記錄(即查出多少行)。
    第5個參數是多少個欄位(多少列)。
    第6個參數是錯誤資訊,跟前面一樣,這裡不多說了。
sqlite資料庫操作例子:
複製代碼 代碼如下:

 int main( int , char ** )
    {
        sqlite3* db;
        int result;
        char* errmsg = NULL;
        char **dbResult; //是 char ** 類型,兩個*號
        int nRow, nColumn;
        int i , j;
        int index;
        result = sqlite3_open("..\\test\\testDatabase.db", &db );
        if( result != SQLITE_OK )
        {
           return -1; //資料庫開啟失敗
        }
        //資料庫作業碼
        //假設前面已經建立了 MyTable_1 表
        //開始查詢,傳入的 dbResult 已經是 char **,這裡又加了一個 & 取地址符,傳遞進去的就成了 char ***
         result = sqlite3_get_table( db, "select * from MyTable_1", &dbResult, &nRow, &nColumn, &errmsg );
        if( SQLITE_OK == result ) //查詢成功
        {
           index = nColumn; //前面說過 dbResult 前面第一行資料是欄位名稱,從 nColumn 索引開始才是真正的資料
           printf("查到%d條記錄\n", nRow );
           for( i = 0; i < nRow ; i++ )
           {
               printf( "第 %d 條記錄\n", i+1 );
               for( j = 0 ; j < nColumn; j++ )
               {
                 printf("欄位名:%s ß> 欄位值:%s\n", dbResult[j], dbResult [index]);
                 // dbResult 的欄位值是連續的,從第0索引到第 nColumn - 1索引都是欄位名稱
                 // 從第 nColumn 索引開始,後面都是欄位值,
                 //它把一個二維的表(傳統的行列標記法)用一個扁平的形式來表示
                  ++index;
              }
              printf( "\n" );
          }
       }
       //到這裡,不論資料庫查詢是否成功,都釋放 char** 查詢結果,使用 sqlite 提供的功能來釋放
       sqlite3_free_table( dbResult );
       sqlite3_close( db );//關閉資料庫
       return 0;
    }
   
到這個例子為止,sqlite3 的常用用法都介紹完了。 用以上的方法,完全可以應付絕大多數資料庫需求。

3、交易處理
sqlite 是支援交易處理的。如果你知道你要同步刪除很多資料,不仿把它們做成一個統一的事務。通常一次 sqlite3_exec 就是一次事務,如果你要刪除1萬條資料,sqlite就做了1萬次:開始新事務->刪除一條資料->提交事務->開始新事務->… 的過程。這個操作是很慢的。因為時間都花在了開始事務、提交事務上。你可以把這些同類操作做成一個事務,這樣如果操作錯誤,還能夠復原事務。事務的操作沒有特別的介面函數,它就是一個普通的 sql 語句而已:
分別如下:
複製代碼 代碼如下:

int result;
    result = sqlite3_exec( db, "begin transaction", 0, 0, &zErrorMsg ); //開始一個事務
    result = sqlite3_exec( db, "commit transaction", 0, 0, &zErrorMsg ); //提交事務
    result = sqlite3_exec( db, "rollback transaction", 0, 0, &zErrorMsg ); //復原事務

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.