乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      基于C API的SQLite3基本數(shù)據(jù)庫操作

       erran 2015-11-25

      SQLite是一款開源嵌入式文件型數(shù)據(jù)庫,這個主要是和其他一些C/S架構(gòu)的關(guān)系型數(shù)據(jù)庫比較而來的,比如MySQL等。

      說他是嵌入式,因為SQLite的所有功能全部包裝在一個dll中,我們只需要使用其中的導(dǎo)出接口就可以操作SQLite數(shù)據(jù)庫,這樣使得數(shù)據(jù)存儲功能能夠很方便的集成進用戶的程序中,并運行在客戶程序的進程空間中

      說他是文件型,因為SQLite的數(shù)據(jù)庫文件就是一個獨立文件(SQLite本身不限制數(shù)據(jù)庫文件的擴展名),再沒有其他的了,數(shù)據(jù),表結(jié)構(gòu),查詢,視圖等等都保存在這個數(shù)據(jù)庫文件中,不會依賴任何數(shù)據(jù)庫環(huán)境

      SQLite的主要特點:
      1。無需部署,0配置,無服務(wù)端
      2??缙脚_
      2。數(shù)據(jù)文件管理方便
      3。較完善的SQL92標(biāo)準(zhǔn)支持,SQLite基本實現(xiàn)了SQL92標(biāo)準(zhǔn),其他的一些不兼容的地方,可以參看官方相關(guān)說明,鏈接:
      http://www./omitted.html
      4。SQL語句執(zhí)行速度快,具體的對比數(shù)據(jù),網(wǎng)上的評測有很多,這里就不多說了
      5。應(yīng)用較廣。最著名的集成應(yīng)該數(shù)Android了吧,其他的PHP ,Python等都做了集成,所以還是很不錯的
      6。完美的Unicode編碼支持。SQLite的接口中,凡是涉及字符串的都是用UTF8或UTF16編碼交互,有的同時提供這兩種編碼的接口函數(shù),所以多語種支持絕對不是問題(這也是我偏愛SQLite的很重要的原因,呵呵)。

      好了,下面說說基于C API的SQLite操作,這里謝絕討論其他的一些包裝庫,這不是本文的范圍,當(dāng)然SQLite的接口包裝庫函數(shù)還是很多的,基本覆蓋各種主流開發(fā)語言。如基于Object Pascal的sqlitesimpledelphi,想了解這個庫的朋友可以查看我的其他博文:
      Delphi 2010下使用sqlitesimpledelphi連接SQLite數(shù)據(jù)庫及中文亂碼問題的解決
      http://hi.baidu.com/2356/blog/item/4a5549366d94afd6a3cc2bc7.html
      sqlitesimpledelphi修正以支持Unicode,Delphi 2010 測試通過
      http://hi.baidu.com/2356/blog/item/236ceb2455f2520c4c088db2.html

      SQLite的數(shù)據(jù)庫操作其實和常規(guī)的數(shù)據(jù)庫操作流程是一樣的:
      1。連接數(shù)據(jù)庫。
      2。構(gòu)造SQL語句并執(zhí)行
      3。對于SELECT語句,可以獲取查詢結(jié)果
      4。數(shù)據(jù)庫使用完畢之后,關(guān)閉數(shù)據(jù)庫

      這里說明一下,下面所介紹的函數(shù)不會涵蓋所有的API函數(shù),畢竟SQLite針對同一個功能點提供了不同的API函數(shù),主要表現(xiàn)在參數(shù)和配置功能上,有需要深入了解的朋友可以參考官方的文檔。

      1。打開數(shù)據(jù)庫
      API函數(shù):
      int sqlite3_open(
      const char *filename,   /* 數(shù)據(jù)庫文件路徑(UTF-8編碼) */
      sqlite3 **ppDb          /* 輸出: SQLite 數(shù)據(jù)庫句柄 */
      );
      int sqlite3_open16(
      const void *filename,   /* 數(shù)據(jù)庫文件路徑(UTF-16) */
      sqlite3 **ppDb          /* 輸出: SQLite 數(shù)據(jù)庫句柄 */
      );
      如果調(diào)用成功會返回SQLITE_OK,否則返回錯誤碼。

      2。構(gòu)造SQL語句,這里就不多說了,這和SQLite本身無關(guān),可以根據(jù)需要使用適當(dāng)?shù)姆椒?gòu)造即可,注意傳給SQLite函數(shù)的時候,字符串編碼要記得轉(zhuǎn)換為UTF8/UTF16

      3。執(zhí)行SQL語句。
      在SQLite中執(zhí)行SQL語句比較簡單的方法是調(diào)用函數(shù):
      int sqlite3_exec(
      sqlite3*,                                  /* 打開的數(shù)據(jù)庫句柄 */
      const char *sql,                           /* UTF8編碼的SQL語句 */
      int (*callback)(void*,int,char**,char**), /* 回調(diào)函數(shù),對于SELECT語句返回的結(jié)果處理在回調(diào)函數(shù)中進行 */
      void *,                                    /* 傳遞給回調(diào)函數(shù)的參數(shù) */
      char **errmsg                              /* 相關(guān)錯誤信息 */
      );

      其實sqlite3_exec只是封裝了sqlite3_prepare、sqite3_step(即SQL中的預(yù)編譯技術(shù))的,主要目的是為使用者提供方便,筆者個人覺得使用后者會更加好一點,這里先做一下總結(jié):

      int sqlite3_prepare(
      sqlite3 *db,            /* 打開的數(shù)據(jù)庫句柄 */
      const char *zSql,       /* UTF8編碼的SQL語句,可以參數(shù)化 */
      int nByte,              /* SQL語句的字節(jié)長度,可以傳遞-1,即字符串以\0結(jié)尾 */
      sqlite3_stmt **ppStmt, /* 輸出:預(yù)編譯之后的SQL語句句柄 */
      const char **pzTail     /* 輸出: 指向zSql緩沖區(qū)中跳過有效SQL字符串的第一個字節(jié) */
      );

      int sqlite3_prepare_v2(
      sqlite3 *db,            /* 打開的數(shù)據(jù)庫句柄 */
      const char *zSql,       /* UTF8編碼的SQL語句,可以參數(shù)化 */
      int nByte,              /* SQL語句的字節(jié)長度,可以傳遞-1,即字符串以寬字符\0結(jié)尾 */
      sqlite3_stmt **ppStmt, /* 輸出: 預(yù)編譯之后的SQL語句句柄 */
      const char **pzTail     /* 輸出: 指向zSql緩沖區(qū)中跳過有效SQL字符串的第一個字節(jié) */
      );

      int sqlite3_prepare16(
      sqlite3 *db,            /* 打開的數(shù)據(jù)庫句柄 */
      const void *zSql,       /* UTF16編碼的SQL語句,可以參數(shù)化 */
      int nByte,              /* SQL語句的字節(jié)長度,可以傳遞-1,即字符串以寬字符\0結(jié)尾 */
      sqlite3_stmt **ppStmt, /* 輸出: 預(yù)編譯之后的SQL語句句柄 */
      const void **pzTail     /* 輸出: 指向zSql緩沖區(qū)中跳過有效SQL字符串的第一個字節(jié) */
      );

      int sqlite3_prepare16_v2(
      sqlite3 *db,            /* 打開的數(shù)據(jù)庫句柄 */
      const void *zSql,       /* UTF16編碼的SQL語句,可以參數(shù)化 */
      int nByte,              /* SQL語句的字節(jié)長度,可以傳遞-1,即字符串以寬字符\0結(jié)尾 */
      sqlite3_stmt **ppStmt, /* 輸出: 預(yù)編譯之后的SQL語句句柄 */
      const void **pzTail     /* 輸出: 指向zSql緩沖區(qū)中跳過有效SQL字符串的第一個字節(jié) */
      );

      其中帶參數(shù)的SQL語句可以這樣定義參數(shù):
       
      NNN 
      :VVV 
      @VVV 
      $VVV 
      參數(shù)編號從1開始,例如:INSERT into db values(?1, ?2)

      v2版本函數(shù)時SQLite根據(jù)需要添加的增強函數(shù),新的程序推薦使用v2版本函數(shù),只需與原來函數(shù)的區(qū)別,可以參考官方原文

      int sqlite3_step(sqlite3_stmt*);
      執(zhí)行一次預(yù)編譯SQL語句,在這之前,如果SQL是參數(shù)化的,可以調(diào)用sqlite3_bind來綁定數(shù)據(jù),int、string、blob等等
      如果執(zhí)行成功會返回SQLITE_DONE,如果查詢有結(jié)果會返回SQLITE_ROW,并可以通過API獲取結(jié)果中的第一行數(shù)據(jù),需要獲取下一行數(shù)據(jù)可以再次調(diào)用sqlite3_step直到返回SQLITE_DONE表示后面沒有數(shù)據(jù)了
      如果需要重新對預(yù)編譯的SQL綁定數(shù)據(jù)并執(zhí)行,需要先reset一下,然后再調(diào)用step,即函數(shù):
      int sqlite3_reset(sqlite3_stmt *pStmt);

      下面是綁定數(shù)據(jù)到預(yù)編譯SQL語句的相關(guān)函數(shù):
      以下函數(shù)的第一個參數(shù)指代預(yù)編譯的SQL句柄,第二個參數(shù)指代綁定的參數(shù)編號,對應(yīng)于參數(shù)化的SQL語句中的參數(shù)編號:

      int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
      該函數(shù)用于綁定二進制數(shù)據(jù)BLOB,其中最后一個參數(shù)是一個回調(diào)函數(shù),當(dāng)成功綁定數(shù)據(jù)后,會被調(diào)用,一般用于自動釋放對應(yīng)的緩沖區(qū)

      int sqlite3_bind_double(sqlite3_stmt*, int, double);
      該函數(shù)綁定double浮點數(shù)

      int sqlite3_bind_int(sqlite3_stmt*, int, int);
      該函數(shù)綁定int整數(shù)

      int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
      該函數(shù)用于綁定具有64位長度的整數(shù),對應(yīng)于C中的long long結(jié)構(gòu),由于一個int的范圍可能無法滿足超大數(shù)據(jù)量的要求,所以SQLite也支持64位整數(shù),畢竟SQLite官方聲稱SQLite是支持最大2T的數(shù)據(jù)的

      int sqlite3_bind_null(sqlite3_stmt*, int);
      該函數(shù)綁定一個空數(shù)據(jù)到指定列

      int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*));
      該函數(shù)綁定一段字符串,源字符串是UTF8編碼的

      int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
      該函數(shù)綁定一段字符串,源字符串是UTF16編碼的

      int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
      該函數(shù)綁定以SQLite結(jié)構(gòu)sqlite3_value存儲的通用數(shù)據(jù),其中sqlite3_value可以是上述的所有類型,此函數(shù)不太常用

      int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
      該函數(shù)綁定指定大小的全零BLOB數(shù)據(jù)

      3。獲取SQL查詢結(jié)果
      對于SELECT語句,還需要能夠獲取結(jié)果。上面也提到調(diào)用sqlite3_step之后,對于有結(jié)果的查詢會返回第一行結(jié)果,這時可以通過API函數(shù)獲取當(dāng)前行的指定字段結(jié)果:

      const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
      該函數(shù)以BLOB數(shù)據(jù)格式獲取對應(yīng)列的數(shù)據(jù),BOLB長度使用sqlite3_column_bytes獲取

      int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
      int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
      該函數(shù)可以用于返回BLOB和字符串的字節(jié)長度。對于BLOB,兩個函數(shù)效果是一樣的,但是對于字符串sqlite3_column_bytes返回的是UTF8編碼的字符串長度,而sqlite3_column_bytes16返回的是UTF16編碼的字符串長度,其間會做必要的字符串格式轉(zhuǎn)換

      double sqlite3_column_double(sqlite3_stmt*, int iCol);
      該函數(shù)返回double數(shù)據(jù)列

      int sqlite3_column_int(sqlite3_stmt*, int iCol);
      該函數(shù)返回int數(shù)據(jù)列

      sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);
      該函數(shù)返回64位整數(shù),即long long數(shù)據(jù)

      const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
      const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);
      該函數(shù)返回字符串,其中sqlite3_column_text輸出的字符串使用UTF8編碼

      sqlite3_column_text16使用UTF16編碼
      int sqlite3_column_type(sqlite3_stmt*, int iCol);
      該函數(shù)返回對應(yīng)列的數(shù)據(jù)類型

      sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);
      該函數(shù)以sqlite3_value結(jié)構(gòu)體返回數(shù)據(jù)

      上面是根據(jù)列ID來獲取對應(yīng)的列數(shù)據(jù)的,如果想通過列名稱獲取列數(shù)據(jù),則需要將列名稱轉(zhuǎn)換為對應(yīng)的列ID,可以使用下面的函數(shù):
      const char *sqlite3_column_name(sqlite3_stmt*, int N);
      const void *sqlite3_column_name16(sqlite3_stmt*, int N);
      該函數(shù)返回對應(yīng)列的名稱

      4。關(guān)閉數(shù)據(jù)庫

      int sqlite3_close(sqlite3 * db);
      使用該函數(shù)可以關(guān)閉數(shù)據(jù)庫

      好了,基本的調(diào)用流程就這么些了,看完這篇文章,應(yīng)該能夠完成基本的數(shù)據(jù)讀寫操作了,至于其他的高級操作,有興趣的朋友可以登錄SQLite官方網(wǎng)站查看,這里就不在本文多說了。

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多