SQLite剖析之編程接口詳解


前言

  使用過程根據函數大致分為如下幾個過程:

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

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

1.sqlite3_open()

  該函數用來打開數據庫。在操作數據庫之前,首先要打開數據庫。這個函數打開一個sqlite數據庫文件的連接並且返回一個數據庫連接對象。這個操作同時程序中的第一個調用的sqlite函數,同時也是其他sqlite api的先決條件。許多的sqlite接口函數都需要一個數據庫連接對象的指針作為它們的第一個參數。

  函數定義:

int sqlite3_open(
  const char *filename,   /* Database filename (UTF-8) */
  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*);

  無論是否成功打開數據庫, 都應該使用 sqlite3_close()關閉數據庫連接。   

  參數說明:

  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 */ /* UTF8編碼的 SQL 語句 */
  int nByte,              /* Maximum length of zSql in bytes. */   /* 參數 sql 的字節數, 包含 '\0' */
  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */ /* 輸出:預編譯語句句柄 */
  const char **pzTail     /* OUT: Pointer to unused portion of zSql */ /* 輸出:指向 sql 語句中未使用的部分 */
);
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’的時候終止。如果用戶知道被傳入的sql語句是以 '\0' 結尾的,那么有一個更好的做法是:把nbytes的值設為該字符串的長度(包含'\0'),這樣可以避免SQLite復制該字符串的一份拷貝,以提高程序的效率。

  pzTail:上面提到zSql在遇見終止符或者是達到設定的nByte之后結束,假如zSql還有剩余的內容,那么這些剩余的內容被存放到pZTail中,不包括終止符。如果pszTail不為NULL, 則*pszTail指向sql中第一個被傳入的SQL語句的結尾。該函數只編譯sql的第一個語句, 所以*pszTail指向的內容則是未被編譯的。

  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語句”或者就直接稱為“語句”。

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

    1. 使用sqlite3_prepare_v2或相關的函數創建這個對象
    2. 使用sqlite3_bind_*()給宿主參數(host parameters)綁定值
    3. 通過調用sqlite3_step一次或多次來執行這個sql
    4. 使用sqlite3——reset()重置這個語句,然后回到第2步,這個過程做0次或多次
    5. 使用sqlite3_finalize()銷毀這個對象

  在sqlite中並沒有定義sqlite3_stmt這個結構的具體內容,它只是一個抽象類型,在使用過程中一般以它的指針進行操作,而sqlite3_stmt類型的指針在實際上是一個指向Vdbe的結構體得指針。

  <2>宿主參數(host parameters)

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

|  ?
|  ?NNN  //NNN代表數字
|  :VVV  //VVV代表字符
|  @VVV
|  $VVV

  在上面這些模板中,NNN代表一個數字,VVV代表一個字母數字標記符(例如:222表示名稱為222的標記符),sql語句中的參數(變量)通過上面的幾個模板來指定,如“select ? from ? “這個語句中指定了兩個參數,sqlite語句中的第一個參數的索引值是1,這就知道這個語句中的兩個參數的索引分別為1和2,使用”?”的話會被自動給予索引值,而使用”?NNN”則可以自己指定參數的索引值,它表示這個參數的索引值為NNN。”:VVV”表示一個名為”VVV”的參數,它也有一個索引值,被自動指定。

  例如:

INSERT INTO people (id, name) VALUES ( ?, ? );
INSERT INTO people (id, id2,name) VALUES ( ?1, ?1.?2 );  //作用:可以用同一個值綁定幾個變量
INSERT INTO people (id, name) VALUES ( :id, :name );
INSERT INTO people (id, name) VALUES ( @id, @name );
INSERT INTO people (id, name) VALUES ( $id, $name );  //用來支持Tcl變量的擴展語法,除非使用Tcl編程,否則推薦使用“:<name>”版本

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

3.int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n,void(*)(void*))

  參數說明:

  第二個參數:為序號(從1開始)

  第三個參數:為字符串值

  第四個參數:為字符串長度

  第五個參數:為一個函數指針,SQLITE3執行完操作后回調此函數,通常用於釋放字符串占用的內存。此參數有兩個常數,SQLITE_STATIC告訴sqlite3_bind_text函數字符串為常量,可以放心使用;而SQLITE_TRANSIENT會使得sqlite3_bind_text函數對字符串做一份拷貝。一般使用這兩個常量參數來調sqlite3_bind_text。statement准備好了以后,就是操作的執行了。

  sqlite3_bind_*系列函數還有好多:

int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));  //功能:為查詢結構體綁定數據

參數說明:

PARAM1(IN):查詢結構體。
PARAM2(IN):綁定第幾個數據(sql語句中的第幾個問號(?))。
PARAM3(IN):二進制數據指針。
PARAM4(IN):二進制數據長度。
PARAM5(IN):析構回調函數,通常設置NULL,結束后自己釋放。

返回值:

SQLITE_OK 成功。

說明:

綁定函數必須要在sqlite3_step前,sqlite3_prepare或者sqlite3_reset之后調用。

未綁定的參數缺省為NULL,類似的綁定函數還有以下:

int sqlite3_bind_double(sqlite3_stmt*, int, double);
int sqlite3_bind_int(sqlite3_stmt*, int, int);
int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite_int64);
int sqlite3_bind_null(sqlite3_stmt*, int);
int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*));
int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); 

4.  sqlite3_step()

  這個過程用於執行有前面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。

  說明:
  當一條語句被sqlite3_prepare()或其相關的函數預編譯后,sqlite3_step()必須被調用一次或多次來評估該預編譯語句。
  該函數的詳細行為依賴於由sqlite3_prepare()(或其相關的函數)產生的是一條怎樣的預編譯語句。

  函數將返回一個以下的結果來標識其執行結果:
     SQLITE_BUSY:忙碌. 數據庫引擎無法鎖定數據去完成其工作. 但可以多次嘗試.
     SQLITE_DONE:完成. sql 語句已經被成功地執行. 在調用 sqlite_reset() 之前, 當前預編譯的語句不應該被 sqlite3_step() 再次調用.
     SQLITE_ROW:查詢時產生了結果. 此時可以通過相關的"數據訪問函數(column access functions)"來取得數據. sqlite3_step() 的再一次調用將取得下一條查詢結果.
     SQLITE_ERROR:發生了錯誤. 此時可以通過 sqlite3_errmmsg() 取得相關的錯誤信息. sqlite3_step() 不能被再次調用.
     SQLITE_MISUSE:不正確的庫的使用. 該函數使用不當.

5.int sqlite3_reset(sqlite3_stmt *pStmt)

  sqlite3_reset用於重置一個准備語句對象到它的初始狀態,然后准備被重新執行。所有sql語句變量使用sqlite3_bind*綁定值,使用sqlite3_clear_bindings重設這些綁定。Sqlite3_reset接口重置准備語句到它代碼開始的時候。sqlite3_reset並不改變在准備語句上的任何綁定值,那么這里猜測,可能是語句在被執行的過程中發生了其他的改變,然后這個語句將它重置到綁定值的時候的那個狀態。

  返回值:

  它的返回值相對有些特殊。返回SQLITE_BUSY表示暫時無法執行操作,SQLITE_DONE表示操作執行完畢,SQLITE_ROW表示執行完畢並且有返回(執行select語句時)。當返回值為SQLITE_ROW時,我們需要對查詢結果進行處理,SQLITE3提供sqlite3_column_*系列函數

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

  參數:

  iCol為列的序號,從0開始。

  返回值:

  如果返回值有多行,則可以再次調用sqlite3_step函數,然后由sqlite3_column_*函數取得返回值。

6.  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);
int sqlite3_column_numeric_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()

(1)得到數據行中某個列的數據:

 
        
sqlite3_column_xxx(sqlite3_stmt*, int iCol); 

     在sqlite3_step返回SQLITE_ROW后,使用它得到第iCol列的數據。

     代表:
     blob:指向保存數據內存的指針
     bytes, bytes16: 得到該blob類型數據的大小,或者text轉換為UTF8/UTF16的字符串長度。
     double, int, int64: 數值
     text,text16:字符串指針
     type:該列的數據類型(SQLITE_INTEGER,SQLITE_FLOAT,SQLITE_TEXT,SQLITE_BLOB,SQLITE_NULL)

     備注:
     如果對該列使用了不同與該列本身類型適合的數據讀取方法,得到的數值將是轉換過的結果。

  (2)得到數據行中某個列的數據的類型:

int sqlite3_column_type(sqlite3_stmt*, int iCol);

     返回值:
     SQLITE_INTEGER、SQLITE_FLOAT、SQLITE_TEXT、SQLITE_BLOB、SQLITE_NULL。

     備注:
     使用的方法和sqlite3_column_xxx()函數類似。

  (3)獲取列數:

int sqlite3_column_count(sqlite3_stmt *pStmt);   

     返回值:
   如果過程沒有返回值,如update,將返回0。

 

  (4)獲取列名 

const char *sqlite3_column_name(sqlite3_stmt*,int);

  (5)返回列數據類型

const char *sqlite3_column_decltype(sqlite3_stmt *, int i);

  (6)得到當前行中包含的數據個數

 
        
int sqlite3_data_count(sqlite3_stmt *pStmt);
  返回值:
  如果sqlite3_step返回SQLITE_ROW,可以得到列數,否則為零。 

7.int sqlite3_reset(sqlite3_stmt *pStmt)

  功能:

  重置所有綁定的值,回到剛剛調用sqlite3_prepare后的狀態。

8.int sqlite3_finalize(sqlite3_stmt *pStmt)

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

  在空指針上調用這個函數沒有什么影響,同時可以准備語句的生命周期的任一時刻調用這個函數:在語句被執行前,一次或多次調用sqlite_reset之后,或者在sqlite3_step任何調用之后不管語句是否完成執行。

  示例:

sqlite3_finalize(pStmt);
pStmt = NULL;

9.sqlite3_close

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

  函數定義:

int sqlite3_close(
    sqlite3* pDB    /* 由 sqlite3_open 或基相關的函數打開的 SQLite 對象句柄 */
);

  說明:
  該函數用來析構sqlite3對象。返回SQLITE_OK表示對象被成功析構,以及所有相關的資源被成功回收。
  應用程序必須在關閉之前"完成(finalize)"所有的"預編譯語句(prepared statements)",並且關閉所有的"二進制句柄綁定(BLOB handle)",如果在關閉時還有未完成的預編譯語句或二進制句柄,那么函數返回SQLITE_BUSY(5)。
  示例:

if(pDB != NULL)
{
    sqlite3_close(pDB);
    pDB = NULL;
} 

10.sqlite3_exec

  函數定義:

int sqlite3_exec(
    sqlite3* pDB,       /* sqlite3句柄 */
    const char* sql,    /* 被執行的 SQL 語句 */
    int (*callback)(void*,int,char**,char**),  /* 執行/查詢回調函數 */
    void* pvoid,    /* 傳遞給回調函數的第一個參數 */
    char**errmsg    /* 錯誤輸出信息 */
);

  說明:
  該函數用來執行若干條SQL語句。
  該函數包裹了先前版本的sqlite3_prepare()、sqlte3_step()和sqlite3_finalize()函數,這樣用戶就可以執行簡單的代碼執行多條SQL語句。
  sqlite3_exec()接口執行多條以";"分隔的SQL語句。如果回調函數不為NULL,則它對每一個行查詢結果都會調用該回調函數。如果沒有回調函數被指定,sqlite3_exec()只是簡單地忽略查詢結果。
  當在執行該SQL語句發生錯誤時,執行將發生中斷,並且后面的語句也全部被忽略。如果errmsg參數不為空,任何錯誤信息將會被寫進由sqlite3_malloc()得到的的內存空間中,即errmsg指向的內存。為了避免內存泄漏,應用程序應該在不需要該錯誤信息后立即調用sqlite3_free()釋放該內存空間。如果errmsg參數不為NULL,並且沒有錯誤發生,errmsg被設置為NULL。
  如果回調函數返回非零,sqlite3_exec()立即中斷查詢,並且不再執行后續的SQL 語句,也不再調用回調函數,sqlite3_exec()將返回SQLITE_ABORT結束執行。
  示例:

sqlite3_exec(pDB, to_utf8("delete from tablename where id=123;"), NULL, NULL, NULL);
sqlite3_exec(pDB, to_utf8("create table if not exists tablename (id integer primary key,name text);"), NULL, NULL, NULL);
sqlite3_exec(pDB, to_utf8("insert into tablename (name) values ('女孩不哭');"), NULL, NULL, NULL);
if(sqlite3_exec(pDB, to_utf8("select * from tablename;"), sqlite_callback, NULL, &pszErrMsg) != SQLITE_OK)
{
  ...
  sqlite3_free(pszErrMsg);
  pszErrMsg = NULL;
}

11.sqlite3_errcode

  函數定義:

int sqlite3_errcode(
    sqlite3* pDB    /* SQLite3 數據庫句柄 */
);  

   說明:
   該函數返回最近一次調用 sqlite3_ API時產生的錯誤碼。

   示例:

int errcode = sqlite3_errcode(pDB);

12.sqlite3_errmsg

  函數定義:

const char *sqlite3_errmsg(
    sqlite3* pDB    /* SQLite3 數據庫句柄 */
);

  說明:
  該函數返回與pDB數據庫指針相關的錯誤信息, 由英語書寫。
  用戶不必考慮內存的釋放,其由SQLite內部管理, 它也將會在下次調用函數時被覆蓋。

  示例:

printf("%s\n", sqlite3_errmsg(pDB));

13.sqlite3_key

  函數定義:

int sqlite3_key(
  sqlite3 *db,                   /* Database to be rekeyed */
  const void *pKey, int nKey     /* The key */
);

  功能:

  為加密的數據庫指定密碼,該函數在sqlite3_open之后調用。

14.sqlite3_rekey

  函數定義:

int sqlite3_rekey(
  sqlite3 *db,                   /* Database to be rekeyed */
  const void *pKey, int nKey     /* The new key */
);

  功能:

  重設數據庫密碼,如果pKey = 0或者nKey = 0,這數據庫不加密。

15.sqlite3_get_table

  函數定義:

int sqlite3_get_table(
  sqlite3*,              /* An open database */
  const char *sql,       /* SQL to be executed */
  char ***resultp,       /* Result written to a char *[]  that this points to */
  int *nrow,             /* Number of result rows written here */
  int *ncolumn,          /* Number of result columns written here */
  char **errmsg          /* Error msg written here */
);

  功能:

查詢表。

參數說明

PARAM1(IN):數據庫句柄
PARAM2(IN):sql語句,以\0結尾
PARAM3(OUT):查詢結果
PARAM4(OUT):返回行數(多少條數據)
PARAM5(OUT):返回列數(多少字段)
PARAM6(OUT):返回錯誤信息

返回值:

  SQLITE_OK 成功。

16.sqlite3_free_table

  函數定義:

void sqlite3_free_table(char **result);

  功能:

  釋放通過sqlite3_get_table查詢保存的結果數據。

  參數說明:
  PARAM1(IN):要釋放的數據指針

17.sqlite3_create_function

  函數定義:

int sqlite3_create_function(
  sqlite3 *,
  const char *zFunctionName,
  int nArg,
  int eTextRep,
  void*,
  void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
  void (*xStep)(sqlite3_context*,int,sqlite3_value**),
  void (*xFinal)(sqlite3_context*)
);

  功能:

  該函數用於注冊/刪除用戶自定義函數。

18.其他

const char *sqlite3_libversion(void);
int sqlite3_libversion_number(void);          //功能:獲取版本號

sqlite_int64 sqlite3_last_insert_rowid(sqlite3*);    //功能:獲取最后插入的行標示.

int sqlite3_changes(sqlite3*);               //功能:獲取最近執行的sqlite3_exec影響的行數.

int sqlite3_total_changes(sqlite3*);            //功能:獲取自從數據庫打開后有改動的函數

void sqlite3_interrupt(sqlite3*);             //功能:打斷或停止數據庫當前操作.

int sqlite3_complete(const char *sql);          //功能:判斷語句是否以分號(;)結尾

int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*);    //功能:設置查詢忙碌時的回調處理;說明:缺省的回調函數為空,如果回調函數為空,表鎖定后sqlite3_exec()執行會直接返回SQLITE_BUSY

int sqlite3_busy_timeout(sqlite3*, int ms);       //功能:設置查詢超時時間(毫秒)

char *sqlite3_mprintf(const char*,...);
char *sqlite3_vmprintf(const char*, va_list);
char *sqlite3_snprintf(int,char*,const char*, ...); //功能:格式化字符,需要用%q來代替%s.(主要是不用對分號'進行轉義)


void *sqlite3_malloc(int);
void *sqlite3_realloc(void*, int);
void sqlite3_free(void*);                //功能:內存函數

int sqlite3_set_authorizer(
  sqlite3*,
  int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
  void *pUserData
);
//功能:設置數據庫授權 void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*); void *sqlite3_profile(sqlite3*, void(*xProfile)(void*,const char*,sqlite_uint64), void*); void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); //功能:設置執行回調函數,sqlite3_exec(),sqlite3_step() ,sqlite3_get_table()時會調用 void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);      //功能:設置事務回調函數 int sqlite3_errcode(sqlite3 *db); const char *sqlite3_errmsg(sqlite3*); //功能:獲取錯誤碼和錯誤消息 int sqlite3_bind_parameter_count(sqlite3_stmt*);            //功能:返回需要綁定的參數數目(sql語句中問號?數量) const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int);     //功能:獲取綁定參數名字,?參數返回NULL int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName); //功能:獲取綁定參數索引 int sqlite3_clear_bindings(sqlite3_stmt*);               //功能:清除綁定的參數

參考代碼:

#include <stdio.h>
#include "sqlite3.h"
int main(){
    sqlite3 *db;
    char *zErrMsg = NULL;
    int rv;
    char szSql[128] = { 0 };
    sqlite3_stmt *stmt;
    rv = sqlite3_open("test.db", &db);
    if(rv){
        fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
        sqlite3_close(db);
        return 1;
    }
    else
       fprintf(stderr,"sqlite3_open OK\n");
       //這里查詢時,假定數據庫中存在表test,並且有一列為COL1(text類型)
       strcpy(szSql,"SELECT COL1 FROM test where COL1=?"); 
       rv = sqlite3_prepare(db, szSql, 128, &stmt, NULL);
       if( rv != SQLITE_OK ) {
         fprintf(stderr, "sqlite3_prepare(%d): %s\n", rv, sqlite3_errmsg(db));
         return -1;
       }    
       rv = sqlite3_bind_text(stmt, 1, "VALUE1", strlen("VALUE1"), SQLITE_STATIC);
       if( rv != SQLITE_OK ) {
         fprintf(stderr, "sqlite3_bind_text(%d): %s\n", rv, sqlite3_errmsg(db));
         return -1;
       }
       rv = sqlite3_step(stmt);
       if( (rv != SQLITE_OK) && (rv != SQLITE_DONE) && (rv != SQLITE_ROW) ) {
         fprintf(stderr, "sqlite3_step(%d): %s\n", rv, sqlite3_errmsg(db));
         return -1;
       }
       while( rv == SQLITE_ROW ){
          fprintf(stderr, "result: %s\n", sqlite3_column_text(stmt,0));
          rv = sqlite3_step(stmt);
       }
       rv = sqlite3_finalize(stmt);
       if( rv != SQLITE_OK ) {
         fprintf(stderr, "sqlite3_finalize(%d): %s\n", rv, sqlite3_errmsg(db));
         return -1;
       }
       sqlite3_close(db);
       return 0;
}
/****************************************************************************/
#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

 程序示例

CREATE TABLE sqlite_master (
  type TEXT,
  name TEXT,
  tbl_name TEXT,
  rootpage INTEGER,
  sql TEXT
);

//獲取Sqlite數據庫中的表名和字段名
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);  
NSString *documentsDirectory = [paths objectAtIndex:0];  
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"database_name"];  
      
sqlite3 *database;  
sqlite3_open([path UTF8String], &database);  
      
charchar *errorMsg;  
const charchar *createSQL = "CREATE TABLE IF NOT EXISTS PEOPLE (ID INTEGER PRIMARY KEY AUTOINCREMENT, FIELD_DATA TEXT)";  
int result = sqlite3_exec(database, createSQL, NULL, NULL, &errorMsg);  
      
sqlite3_stmt *statement;  
if (result == SQLITE_OK) {  
  const charchar *getTableInfo = "select * from sqlite_master where type='table' order by name;";  
  result = sqlite3_prepare_v2(database, getTableInfo, -1, &statement, nil);  
  while (sqlite3_step(statement) == SQLITE_ROW) {  
    charchar *nameData = (charchar *)sqlite3_column_text(statement, 1);  
    NSString *tableName = [[NSString alloc] initWithUTF8String:nameData];  
    NSLog(@"name:%@",tableName);  
  }  
          
  const charchar *getColumn = "PRAGMA table_info(PEOPLE)";  
  result = sqlite3_prepare_v2(database, getColumn, -1, &statement, nil);  
  while (sqlite3_step(statement) == SQLITE_ROW) {  
    charchar *nameData = (charchar *)sqlite3_column_text(statement, 1);  
    NSString *columnName = [[NSString alloc] initWithUTF8String:nameData];  
    NSLog(@"columnName:%@",columnName);  
  }  
          
  sqlite3_finalize(statement);  
}  
sqlite3_close(database);  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM