sqlite的幾個經常使用方法 --轉

http://www.cnblogs.com/kfqcome/archive/2011/06/27/2136999.htmlhtml

一.使用流程mysql

要使用sqlite,須要從sqlite官網下載到三個文件,分別爲sqlite3.lib,sqlite3.dll,sqlite3.h,而後再在本身的工程中配置好頭文件和庫文件,同時將dll文件放到當前目錄下,就完成配置可使用sqlite了。sql

使用的過程根據使用的函數大體分爲以下幾個過程:數據庫

  • sqlite3_open()
  • sqlite3_prepare()
  • sqlite3_step()
  • sqlite3_column()
  • sqlite3_finalize()
  • sqlite3_close()

這幾個過程是概念上的說法,而不徹底是程序運行的過程,如sqlite3_column()表示的是對查詢得到一行裏面的數據的列的各個操做統稱,實際上在sqlite中並不存在這個函數。api

1.  sqlite3_open():打開數據庫安全

在操做數據庫以前,首先要打開數據庫。這個函數打開一個sqlite數據庫文件的鏈接而且返回一個數據庫鏈接對象。這個操做同時程序中的第一個調用的sqlite函數,同時也是其餘sqlite api的先決條件。許多的sqlite接口函數都須要一個數據庫鏈接對象的指針做爲它們的第一個參數。函數

函數定義編碼

int sqlite3_open(lua

  const char *filename,   /* Database filename (UTF-8) */spa

  sqlite3 **ppDb          /* OUT: SQLite db handle */

);

int sqlite3_open16(

  const void *filename,   /* Database filename (UTF-16) */

  sqlite3 **ppDb          /* OUT: SQLite db handle */

);

int sqlite3_open_v2(

  const char *filename,   /* Database filename (UTF-8) */

  sqlite3 **ppDb,         /* OUT: SQLite db handle */

  int flags,              /* Flags */

  const char *zVfs        /* Name of VFS module to use */

);

 

說明:

假如這個要被打開的數據文件不存在,則一個同名的數據庫文件將被建立。若是使用sqlite3_open和sqlite3_open_v2的話,數據庫將採用UTF-8的編碼方式,sqlite3_open16採用UTF-16的編碼方式

返回值:

若是sqlite數據庫被成功打開(或建立),將會返回SQLITE_OK,不然將會返回錯誤碼。Sqlite3_errmsg()或者sqlite3_errmsg16能夠用於得到數據庫打開錯誤碼的英文描述,這兩個函數定義爲:

const char *sqlite3_errmsg(sqlite3*);

const void *sqlite3_errmsg16(sqlite3*);

        

參數說明:

filename:須要被打開的數據庫文件的文件名,在sqlite3_open和sqlite3_open_v2中這個參數採用UTF-8編碼,而在sqlite3_open16中則採用UTF-16編碼

ppDb:一個數據庫鏈接句柄被返回到這個參數,即便發生錯誤。惟一的一場是若是sqlite不能分配內存來存放sqlite對象,ppDb將會被返回一個NULL值。

flags:做爲數據庫鏈接的額外控制的參數,能夠是SQLITE_OPEN_READONLY,SQLITE_OPEN_READWRITE和SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE中的一個,用於控制數據庫的打開方式,能夠和SQLITE_OPEN_NOMUTEXSQLITE_OPEN_FULLMUTEX, SQLITE_OPEN_SHAREDCACHE,以及SQLITE_OPEN_PRIVATECACHE結合使用,具體的詳細狀況能夠查閱文檔

 

 

 

 

2.  Sqlite3_prepare()

這個函數將sql文本轉換成一個準備語句(prepared statement)對象,同時返回這個對象的指針。這個接口須要一個數據庫鏈接指針以及一個要準備的包含SQL語句的文本。它實際上並不執行(evaluate)這個SQL語句,它僅僅爲執行準備這個sql語句

函數定義(僅列出UTF-8的)

int sqlite3_prepare(

  sqlite3 *db,            /* Database handle */

  const char *zSql,       /* SQL statement, UTF-8 encoded */

  int nByte,              /* Maximum length of zSql in bytes. */

  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */

  const char **pzTail     /* OUT: Pointer to unused portion of zSql */

);

int sqlite3_prepare_v2(

  sqlite3 *db,            /* Database handle */

  const char *zSql,       /* SQL statement, UTF-8 encoded */

  int nByte,              /* Maximum length of zSql in bytes. */

  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */

  const char **pzTail     /* OUT: Pointer to unused portion of zSql */

);

 

參數:

db:數據指針

zSql:sql語句,使用UTF-8編碼

nByte:若是nByte小於0,則函數取出zSql中從開始到第一個0終止符的內容;若是nByte不是負的,那麼它就是這個函數能從zSql中讀取的字節數的最大值。若是nBytes非負,zSql在第一次碰見’/000/或’u000’的時候終止

pzTail:上面提到zSql在碰見終止符或者是達到設定的nByte以後結束,假如zSql還有剩餘的內容,那麼這些剩餘的內容被存放到pZTail中,不包括終止符

ppStmt:可以使用sqlite3_step()執行的編譯好的準備語句的指針,若是錯誤發生,它被置爲NULL,如假如輸入的文本不包括sql語句。調用過程必須負責在編譯好的sql語句完成使用後使用sqlite3_finalize()刪除它。

 

說明

若是執行成功,則返回SQLITE_OK,不然返回一個錯誤碼。推薦在如今任何的程序中都使用sqlite3_prepare_v2這個函數,sqlite3_prepare只是用於前向兼容

 

備註

<1>準備語句(prepared statement)對象

typedef struct sqlite3_stmt sqlite3_stmt;

        

準備語句(prepared statement)對象一個表明一個簡單SQL語句對象的實例,這個對象一般被稱爲「準備語句」或者「編譯好的SQL語句」或者就直接稱爲「語句」。

         語句對象的生命週期經歷這樣的過程:

l  使用sqlite3_prepare_v2或相關的函數建立這個對象

l  使用sqlite3_bind_*()給宿主參數(host parameters)綁定值

l  經過調用sqlite3_step一次或屢次來執行這個sql

l  使用sqlite3——reset()重置這個語句,而後回到第2步,這個過程作0次或屢次

l  使用sqlite3_finalize()銷燬這個對象

 

在sqlite中並無定義sqlite3_stmt這個結構的具體內容,它只是一個抽象類型,在使用過程當中通常以它的指針進行操做,而sqlite3_stmt類型的指針在其實是一個指向Vdbe的結構體得指針

<2>宿主參數(host parameters)

在傳給sqlite3_prepare_v2()的sql的語句文本或者它的變量中,知足以下模板的文字將被替換成一個參數:

l  ?

l  ?NNN,NNN表明數字

l  :VVV,VVV表明字符

l  @VVV

l  $VVV

在上面這些模板中,NNN表明一個數字,VVV表明一個字母數字標記符(例如:222表示名稱爲222的標記符),sql語句中的參數(變量)經過上面的幾個模板來指定,如

「select ? from ? 「這個語句中指定了兩個參數,sqlite語句中的第一個參數的索引值是1,這就知道這個語句中的兩個參數的索引分別爲1和2,使用」?」的話會被自動給予索引值,而使用」?NNN」則能夠本身指定參數的索引值,它表示這個參數的索引值爲NNN。」:VVV」表示一個名爲」VVV」的參數,它也有一個索引值,被自動指定。

可使用sqlite3_bind_*()來給這些參數綁定值

 

 

 

3.  sqlite3_setp()

這個過程用於執行有前面sqlite3_prepare建立的準備語句。這個語句執行到結果的第一行可用的位置。繼續前進到結果的第二行的話,只需再次調用sqlite3_setp()。繼續調用sqlite3_setp()知道這個語句完成,那些不返回結果的語句(如:INSERT,UPDATE,或DELETE),sqlite3_step()只執行一次就返回

函數定義

int sqlite3_step(sqlite3_stmt*);

返回值

函數的返回值基於建立sqlite3_stmt參數所使用的函數,假如是使用老版本的接口sqlite3_prepare()和sqlite3_prepare16(),返回值會是 SQLITE_BUSY, SQLITE_DONE, SQLITE_ROW, SQLITE_ERROR 或 SQLITE_MISUSE,而v2版本的接口sqlite3_prepare_v2()和sqlite3_prepare16_v2()則會同時返回這些結果碼和擴展結果碼。

對全部V3.6.23.1以及其前面的全部版本,須要在sqlite3_step()以後調用sqlite3_reset(),在後續的sqlite3_ step以前。若是調用sqlite3_reset重置準備語句失敗,將會致使sqlite3_ step返回SQLITE_MISUSE,可是在V3. 6.23.1之後,sqlite3_step()將會自動調用sqlite3_reset。

int sqlite3_reset(sqlite3_stmt *pStmt);

sqlite3_reset用於重置一個準備語句對象到它的初始狀態,而後準備被從新執行。全部sql語句變量使用sqlite3_bind*綁定值,使用sqlite3_clear_bindings重設這些綁定。Sqlite3_reset接口重置準備語句到它代碼開始的時候。sqlite3_reset並不改變在準備語句上的任何綁定值,那麼這裏猜想,多是語句在被執行的過程當中發生了其餘的改變,而後這個語句將它重置到綁定值的時候的那個狀態。

 

4.  sqlite3_column()

這個過程從執行sqlite3_step()執行一個準備語句獲得的結果集的當前行中返回一個列。每次sqlite3_step獲得一個結果集的列停下後,這個過程就能夠被屢次調用去查詢這個行的各列的值。對列操做是有多個函數,均以sqlite3_column爲前綴

const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);

int sqlite3_column_bytes(sqlite3_stmt*, int iCol);

int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);

double sqlite3_column_double(sqlite3_stmt*, int iCol);

int sqlite3_column_int(sqlite3_stmt*, int iCol);

sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);

const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);

const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);

int sqlite3_column_type(sqlite3_stmt*, int iCol);

sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);

說明

第一個參數爲從sqlite3_prepare返回來的prepared statement對象的指針,第二參數指定這一行中的想要被返回的列的索引。最左邊的一列的索引號是0,行的列數可使用sqlite3_colum_count()得到。

這些過程會根據狀況去轉換數值的類型,sqlite內部使用sqlite3_snprintf()去自動進行這個轉換,下面是關於轉換的細節表:

內部類型

請求的類型

轉換

NULL

INTEGER

結果是0

NULL

FLOAT

結果是0.0

NULL

TEXT

結果是NULL

NULL

BLOB

結果是NULL

INTEGER

FLOAT

從整形轉換到浮點型

INTEGER

TEXT

整形的ASCII碼顯示

INTEGER

BLOB

同上

FLOAT

INTEGER

浮點型轉換到整形

FLOAT

TEXT

浮點型的ASCII顯示

FLOAT

BLOB

同上

TEXT

INTEGER

使用atoi()

TEXT

FLOAT

使用atof()

TEXT

BLOB

沒有轉換

BLOB

INTEGER

先到TEXT,而後使用atoi

BLOB

FLOAT

先到TEXT,而後使用atof

BLOB

TEXT

若是須要的話添加0終止符

 

注:BLOB數據類型是指二進制的數據塊,好比要在數據庫中存放一張圖片,這張圖片就會以二進制形式存放,在sqlite中對應的數據類型就是BLOB

 

int sqlite3_column_bytes(sqlite3_stmt*, int iCol)int sqlite3_column_bytes16(sqlite3_stmt*, int iCol)兩個函數返回對應列的內容的字節數,這個字節數不包括後面類型轉換過程當中加上的0終止符。

下面是幾個最安全和最簡單的使用策略

  • 先sqlite3_column_text() ,而後 sqlite3_column_bytes()
  • 先sqlite3_column_blob(),而後sqlite3_column_bytes()
  • 先sqlite3_column_text16(),而後sqlite3_column_bytes16()

 

 

5.  sqlite3_finalize

    int sqlite3_finalize(sqlite3_stmt *pStmt);

這個過程銷燬前面被sqlite3_prepare建立的準備語句,每一個準備語句都必須使用這個函數去銷燬以防止內存泄露。

在空指針上調用這個函數沒有什麼影響,同時能夠準備語句的生命週期的任一時刻調用這個函數:在語句被執行前,一次或屢次調用sqlite_reset以後,或者在sqlite3_step任何調用以後無論語句是否完成執行

 

6.  sqlite3_close

這個過程關閉前面使用sqlite3_open打開的數據庫鏈接,任何與這個鏈接相關的準備語句必須在調用這個關閉函數以前被釋放

 

 

二.使用舉例

 

?

#include "stdafx.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;

}

#define CHECK_RC(rc,szInfo,szErrMsg,db) if(rc!=SQLITE_OK) /

           {printf("%s error!/n",szInfo);/

           printf("%s/n",szErrMsg);    /

           sqlite3_free(szErrMsg);         /

           sqlite3_close(db);              /

           return 0;}

int _tmain(int argc, _TCHAR* argv[])

{

  

    sqlite3 *db;

    char *dbPath="f:/test.db";

    char *szErrMsg = 0;

  

    int rc= sqlite3_open(dbPath, &db);

    CHECK_RC(rc,"open database",db);

    char *szSql="create table UserInfo(ID int primary key , UserName char, PassWord char);";

    rc=sqlite3_exec(db,szSql,0,0,&szErrMsg);

    CHECK_RC(rc,"create table",szErrMsg,db);

    rc=sqlite3_exec(db,"insert into UserInfo(ID,UserName,PassWord) values(1,'kfqcome','123456')",0,0,&szErrMsg);

    CHECK_RC(rc,"insert info",szErrMsg,db);

    rc=sqlite3_exec(db,"insert into UserInfo(ID,UserName,PassWord) values(2,'miss wang','654321')",0,0,&szErrMsg);

    CHECK_RC(rc,"insert info",szErrMsg,db);

    szSql="select * from UserInfo";

    rc = sqlite3_exec(db,szSql, callback, 0, &szErrMsg);

    CHECK_RC(rc,"query values",szErrMsg,db);

    sqlite3_close(db);

    getchar();

    return 0;

}

  輸出的結果:

ID = 1

UserName = kfqcome

PassWord = 123456

 

ID = 2

UserName = miss wang

PassWord = 654321

 

這裏執行sql語句用的是sqlite3_exec,它是前面幾個函數的封裝

 

int sqlite3_exec(

  sqlite3*,                                  /* An open database */

  const char *sql,                           /* SQL to be evaluated */

  int (*callback)(void*,int,char**,char**),  /* Callback function */

  void *,                                    /* 1st argument to callback */

  char **errmsg                              /* Error msg written here */

);

sqlite3_exec是sqlite3_prepare_v2,sqlite3_step()和sqlite3_finalize()的封裝,能讓程序屢次執行sql語句而不要寫許多重複的代碼。

Sqlite3_exec接口執行0或多個UTF-8編碼的,分號分割的sql語句,傳到第二個參數中。若是sqlite3_exec的第三個參數回調函數指針不爲空,那麼它會爲每一個來自執行的SQL語句的結果行調用(也就是說回調函數會調用屢次,上面例子中會返回2個結果行,於是會被執行2次),第4個參數是傳給回調函數的第一個參數,若是回調函數指針爲空,那麼回調不會發生同時結果行被忽略。

若是在執行sql語句中有錯誤發生,那麼當前的語句的執行被中止,後續的語句也被跳過。第五個參數不爲空的時候,它被分配內存並寫入了錯誤信息,因此在sqlite3_exec後面須要調用sqlite3_free去釋放這個對象以防止內存泄露

 

回調函數:

int (*callback)(void*,int,char**,char**),  /* Callback function */

         第一個參數經過sqlite3_exec的第第四個參數傳入的

         第二個參數是結果行的列數

         第三個參數是行中列數據的指針

         第四個參數是行中列名稱的指針

相關文章
相關標籤/搜索