1.介紹:sqlite3是linux上的小巧的數(shù)據(jù)庫,一個文件就是一個數(shù)據(jù)庫。 sqlite3程序當你編譯SQLite庫時自動被建立。只須取得一個源文件樹的拷貝,運行“configure"然后"make"即可。
C/C++下SQLite編程 參考文件:A introduction to the sqlite c/c++ interface 找到安裝SQLite的路徑: 我們的sqlite3的庫文件目錄是:/usr/local/sqlite3/lib //我的機子安裝目錄文件名是sqlite-3.3.6 編譯指南:現(xiàn)在編譯:[root@localhost dada]# gcc c3.c -o c3 opendbsqlite.c:11:21: sqlite3.h: 沒有那個文件或目錄 /tmp/ccTkItnN.o(.text+0x2b): In function `main': 可以在gcc語句后面加上如下 -lsqlite3 -L/usr/local/sqlite3/lib -I/usr/local/sqlite3/include 指明用到的庫文件;為庫文件指定路徑;為頭文件指定路徑 繼續(xù)編譯: 出現(xiàn) "error while loading shared libraries" 等錯誤 我們可以這樣解決: [root@localhost temp]# gcc c3.c -o c3 -lsqlite3 -L/usr/local/sqlite3/lib -I/usr/local/sqlite3/include –static 靜態(tài)編譯后的文件相對動態(tài)編譯更大,很容易理解,靜態(tài)編譯把頭庫文件作為程序的一部分都包含進來了。 方法二:重新配置系統(tǒng)環(huán)境變量 LD_LIBRARY_PATH 好了,現(xiàn)在我們來指定系統(tǒng)環(huán)境變量 LD_LIBRARY_PATH 的值 …. LD_LIBRARY_PATH=/usr/local/sqlite3/lib: ….. (看到了吧,LD_LIBRARY_PATH這一行開始就是sqlite3的庫文件路徑:) 我們推薦使用動態(tài)編譯的方法。
常用函數(shù) int sqlite3_open( const char *filename, /* Database filename (UTF-8) */ sqlite3 **ppDb /* OUT: SQLite db handle */ ); int sqlite3_close(sqlite3 *); int sqlite3_exec(sqlite3*, const char *sql, sqlite3_callback, void *, char **errmsg ); 這就是執(zhí)行一條 sql 語句的函數(shù)。 第1個參數(shù)不再說了,是前面open函數(shù)得到的指針。說了是關(guān)鍵數(shù)據(jù)結(jié)構(gòu)。 第2個參數(shù)const char *sql 是一條 sql 語句,以/0結(jié)尾。 第3個參數(shù)sqlite3_callback 是回調(diào),當這條語句執(zhí)行之后,sqlite3會去調(diào)用你提供的這個函數(shù)。 第4個參數(shù)void * 是你所提供的指針,你可以傳遞任何一個指針參數(shù)到這里,這個參數(shù)最終會傳到回調(diào)函數(shù)里面,這個指針比較重要,可以用來作參數(shù)的傳遞。如果不需要傳遞指針給回調(diào)函數(shù),可以填NULL。等下我們再看回調(diào)函數(shù)的寫法,以及這個參數(shù)的使用。 第5 個參數(shù)char ** errmsg 是錯誤信息。注意是指針的指針。sqlite3里面有很多固定的錯誤信息。執(zhí)行 sqlite3_exec 之后,執(zhí)行失敗時可以查閱這個指針(直接 printf(“%s/n”,errmsg))得到一串字符串信息,這串信息告訴你錯在什么地方。sqlite3_exec函數(shù)通過修改你傳入的指針的指針,把你提供的指針指向錯誤提示信息,這樣sqlite3_exec函數(shù)外面就可以通過這個 char*得到具體錯誤提示。 說明:通常, sqlite3_callback 和它后面的 void * 這兩個位置都可以填 NULL。填NULL表示你不需要回調(diào)。比如你做 insert 操作,做 delete 操作,就沒有必要使用回調(diào)。而當你做 select 時,就要使用回調(diào),因為 sqlite3 把數(shù)據(jù)查出來,得通過回調(diào)告訴你查出了什么數(shù)據(jù)。用select時也可以用sqlite3_get_table 查詢: int sqlite3_get_table( sqlite3 *db, /* An open database */ const char *zSql, /* SQL to be evaluated */ char ***pazResult, /* Results of the query */ int *pnRow, /* Number of result rows written here */ int *pnColumn, /* Number of result columns written here */ char **pzErrmsg /* Error msg written here */ ); void sqlite3_free_table(char **result); //釋放內(nèi)存空間
一.使用流程 要使用sqlite,需要從sqlite官網(wǎng)下載到三個文件,分別為sqlite3.lib,sqlite3.dll,sqlite3.h,然后再在自己的工程中配置好頭文件和庫文件,同時將dll文件放到當前目錄下,就完成配置可以使用sqlite了。 使用的過程根據(jù)使用的函數(shù)大致分為如下幾個過程:
這幾個過程是概念上的說法,而不完全是程序運行的過程,如sqlite3_column()表示的是對查詢獲得一行里面的數(shù)據(jù)的列的各個操作統(tǒng)稱,實際上在sqlite中并不存在這個函數(shù)。 1. sqlite3_open():打開數(shù)據(jù)庫 在操作數(shù)據(jù)庫之前,首先要打開數(shù)據(jù)庫。這個函數(shù)打開一個sqlite數(shù)據(jù)庫文件的連接并且返回一個數(shù)據(jù)庫連接對象。這個操作同時程序中的第一個調(diào)用 的sqlite函數(shù),同時也是其他sqlite api的先決條件。許多的sqlite接口函數(shù)都需要一個數(shù)據(jù)庫連接對象的指針作為它們的第一個參數(shù)。 函數(shù)定義 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 */ );
說明: 假如這個要被打開的數(shù)據(jù)文件不存在,則一個同名的數(shù)據(jù)庫文件將被創(chuàng)建。如果使用sqlite3_open和sqlite3_open_v2的話,數(shù)據(jù)庫將采用UTF-8的編碼方式,sqlite3_open16采用UTF-16的編碼方式 返回值: 如果sqlite數(shù)據(jù)庫被成功打開(或創(chuàng)建),將會返回SQLITE_OK,否則將會返回錯誤碼。Sqlite3_errmsg()或者sqlite3_errmsg16可以用于獲得數(shù)據(jù)庫打開錯誤碼的英文描述,這兩個函數(shù)定義為: const char *sqlite3_errmsg(sqlite3*); const void *sqlite3_errmsg16(sqlite3*);
參數(shù)說明: filename:需要被打開的數(shù)據(jù)庫文件的文件名,在sqlite3_open和sqlite3_open_v2中這個參數(shù)采用UTF-8編碼,而在sqlite3_open16中則采用UTF-16編碼 ppDb:一個數(shù)據(jù)庫連接句柄被返回到這個參數(shù),即使發(fā)生錯誤。唯一的一場是如果sqlite不能分配內(nèi)存來存放sqlite對象,ppDb將會被返回一個NULL值。 flags:作為數(shù)據(jù)庫連接的額外控制的參數(shù),可以是SQLITE_OPEN_READONLY,SQLITE_OPEN_READWRITE和 SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE中的一個,用于控制數(shù)據(jù)庫的打開方式,可以和SQLITE_OPEN_NOMUTEX,SQLITE_OPEN_FULLMUTEX, SQLITE_OPEN_SHAREDCACHE,以及SQLITE_OPEN_PRIVATECACHE結(jié)合使用,具體的詳細情況可以查閱文檔
2. Sqlite3_prepare() 這個函數(shù)將sql文本轉(zhuǎn)換成一個準備語句(prepared statement)對象,同時返回這個對象的指針。這個接口需要一個數(shù)據(jù)庫連接指針以及一個要準備的包含SQL語句的文本。它實際上并不執(zhí)行(evaluate)這個SQL語句,它僅僅為執(zhí)行準備這個sql語句 函數(shù)定義(僅列出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 */ );
參數(shù): db:數(shù)據(jù)指針 zSql:sql語句,使用UTF-8編碼 nByte:如果nByte小于0,則函數(shù)取出zSql中從開始到第一個0終止符的內(nèi)容;如果nByte不是負的,那么它就是這個函數(shù)能從zSql中讀取的字節(jié)數(shù)的最大值。如果nBytes非負,zSql在第一次遇見’/000/或’u000’的時候終止 pzTail:上面提到zSql在遇見終止符或者是達到設(shè)定的nByte之后結(jié)束,假如zSql還有剩余的內(nèi)容,那么這些剩余的內(nèi)容被存放到pZTail中,不包括終止符 ppStmt:能夠使用sqlite3_step()執(zhí)行的編譯好的準備語句的指針,如果錯誤發(fā)生,它被置為NULL,如假如輸入的文本不包括sql語句。調(diào)用過程必須負責在編譯好的sql語句完成使用后使用sqlite3_finalize()刪除它。
說明 如果執(zhí)行成功,則返回SQLITE_OK,否則返回一個錯誤碼。推薦在現(xiàn)在任何的程序中都使用sqlite3_prepare_v2這個函數(shù),sqlite3_prepare只是用于前向兼容
備注 <1>準備語句(prepared statement)對象 typedef struct sqlite3_stmt sqlite3_stmt;
準備語句(prepared statement)對象一個代表一個簡單SQL語句對象的實例,這個對象通常被稱為“準備語句”或者“編譯好的SQL語句”或者就直接稱為“語句”。 語句對象的生命周期經(jīng)歷這樣的過程: l 使用sqlite3_prepare_v2或相關(guān)的函數(shù)創(chuàng)建這個對象 l 使用sqlite3_bind_*()給宿主參數(shù)(host parameters)綁定值 l 通過調(diào)用sqlite3_step一次或多次來執(zhí)行這個sql l 使用sqlite3——reset()重置這個語句,然后回到第2步,這個過程做0次或多次 l 使用sqlite3_finalize()銷毀這個對象
在sqlite中并沒有定義sqlite3_stmt這個結(jié)構(gòu)的具體內(nèi)容,它只是一個抽象類型,在使用過程中一般以它的指針進行操作,而sqlite3_stmt類型的指針在實際上是一個指向Vdbe的結(jié)構(gòu)體得指針 <2>宿主參數(shù)(host parameters) 在傳給sqlite3_prepare_v2()的sql的語句文本或者它的變量中,滿足如下模板的文字將被替換成一個參數(shù): l ? l ?NNN,NNN代表數(shù)字 l :VVV,VVV代表字符 l @VVV l $VVV 在上面這些模板中,NNN代表一個數(shù)字,VVV代表一個字母數(shù)字標記符(例如:222表示名稱為222的標記符),sql語句中的參數(shù)(變量)通過上面的幾個模板來指定,如 “select ? from ? “這個語句中指定了兩個參數(shù),sqlite語句中的第一個參數(shù)的索引值是1,這就知道這個語句中的兩個參數(shù)的索引分別為1和2,使用”?”的話會被自動給 予索引值,而使用”?NNN”則可以自己指定參數(shù)的索引值,它表示這個參數(shù)的索引值為NNN?!?VVV”表示一個名為”VVV”的參數(shù),它也有一個索引 值,被自動指定。 可以使用sqlite3_bind_*()來給這些參數(shù)綁定值
3. sqlite3_setp() 這個過程用于執(zhí)行有前面sqlite3_prepare創(chuàng)建的準備語句。這個語句執(zhí)行到結(jié)果的第一行可用的位置。繼續(xù)前進到結(jié)果的第二行的話,只需 再次調(diào)用sqlite3_setp()。繼續(xù)調(diào)用sqlite3_setp()知道這個語句完成,那些不返回結(jié)果的語句 (如:INSERT,UPDATE,或DELETE),sqlite3_step()只執(zhí)行一次就返回 函數(shù)定義 int sqlite3_step(sqlite3_stmt*); 返回值 函數(shù)的返回值基于創(chuàng)建sqlite3_stmt參數(shù)所使用的函數(shù),假如是使用老版本的接口sqlite3_prepare()和 sqlite3_prepare16(),返回值會 是 SQLITE_BUSY, SQLITE_DONE, SQLITE_ROW, SQLITE_ERROR 或 SQLITE_MISUSE,而v2版本的接口sqlite3_prepare_v2()和sqlite3_prepare16_v2()則會同時返 回這些結(jié)果碼和擴展結(jié)果碼。 對所有V3.6.23.1以及其前面的所有版本,需要在sqlite3_step()之后調(diào)用sqlite3_reset(),在后續(xù)的 sqlite3_ step之前。如果調(diào)用sqlite3_reset重置準備語句失敗,將會導致sqlite3_ step返回SQLITE_MISUSE,但是在V3. 6.23.1以后,sqlite3_step()將會自動調(diào)用sqlite3_reset。 int sqlite3_reset(sqlite3_stmt *pStmt); sqlite3_reset用于重置一個準備語句對象到它的初始狀態(tài),然后準備被重新執(zhí)行。所有sql語句變量使用sqlite3_bind*綁定 值,使用sqlite3_clear_bindings重設(shè)這些綁定。Sqlite3_reset接口重置準備語句到它代碼開始的時候。sqlite3_reset并不改變在準備語句上的任何綁定值,那么這里猜測,可能是語句在被執(zhí)行的過程中發(fā)生了其他的改變,然后這個語句將它重置到綁定值的時候的那個狀態(tài)。
4. sqlite3_column() 這個過程從執(zhí)行sqlite3_step()執(zhí)行一個準備語句得到的結(jié)果集的當前行中返回一個列。每次sqlite3_step得到一個結(jié)果集的列停下后,這個過程就可以被多次調(diào)用去查詢這個行的各列的值。對列操作是有多個函數(shù),均以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); 說明 第一個參數(shù)為從sqlite3_prepare返回來的prepared statement對象的指針,第二參數(shù)指定這一行中的想要被返回的列的索引。最左邊的一列的索引號是0,行的列數(shù)可以使用sqlite3_colum_count()獲得。 這些過程會根據(jù)情況去轉(zhuǎn)換數(shù)值的類型,sqlite內(nèi)部使用sqlite3_snprintf()去自動進行這個轉(zhuǎn)換,下面是關(guān)于轉(zhuǎn)換的細節(jié)表:
注:BLOB數(shù)據(jù)類型是指二進制的數(shù)據(jù)塊,比如要在數(shù)據(jù)庫中存放一張圖片,這張圖片就會以二進制形式存放,在sqlite中對應(yīng)的數(shù)據(jù)類型就是BLOB
int sqlite3_column_bytes(sqlite3_stmt*, int iCol)int sqlite3_column_bytes16(sqlite3_stmt*, int iCol)兩個函數(shù)返回對應(yīng)列的內(nèi)容的字節(jié)數(shù),這個字節(jié)數(shù)不包括后面類型轉(zhuǎn)換過程中加上的0終止符。 下面是幾個最安全和最簡單的使用策略
5. sqlite3_finalize int sqlite3_finalize(sqlite3_stmt *pStmt); 這個過程銷毀前面被sqlite3_prepare創(chuàng)建的準備語句,每個準備語句都必須使用這個函數(shù)去銷毀以防止內(nèi)存泄露。 在空指針上調(diào)用這個函數(shù)沒有什么影響,同時可以準備語句的生命周期的任一時刻調(diào)用這個函數(shù):在語句被執(zhí)行前,一次或多次調(diào)用sqlite_reset之后,或者在sqlite3_step任何調(diào)用之后不管語句是否完成執(zhí)行
6. sqlite3_close 這個過程關(guān)閉前面使用sqlite3_open打開的數(shù)據(jù)庫連接,任何與這個連接相關(guān)的準備語句必須在調(diào)用這個關(guān)閉函數(shù)之前被釋放
二.使用舉例
輸出的結(jié)果: ID = 1 UserName = kfqcome PassWord = 123456
ID = 2 UserName = miss wang PassWord = 654321
這里執(zhí)行sql語句用的是sqlite3_exec,它是前面幾個函數(shù)的封裝
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()的封裝,能讓程序多次執(zhí)行sql語句而不要寫許多重復(fù)的代碼。 Sqlite3_exec接口執(zhí)行0或多個UTF-8編碼的,分號分割的sql語句,傳到第二個參數(shù)中。如果sqlite3_exec的第三個參數(shù) 回調(diào)函數(shù)指針不為空,那么它會為每個來自執(zhí)行的SQL語句的結(jié)果行調(diào)用(也就是說回調(diào)函數(shù)會調(diào)用多次,上面例子中會返回2個結(jié)果行,因而會被執(zhí)行2次), 第4個參數(shù)是傳給回調(diào)函數(shù)的第一個參數(shù),如果回調(diào)函數(shù)指針為空,那么回調(diào)不會發(fā)生同時結(jié)果行被忽略。 如果在執(zhí)行sql語句中有錯誤發(fā)生,那么當前的語句的執(zhí)行被停止,后續(xù)的語句也被跳過。第五個參數(shù)不為空的時候,它被分配內(nèi)存并寫入了錯誤信息,所以在sqlite3_exec后面需要調(diào)用sqlite3_free去釋放這個對象以防止內(nèi)存泄露
回調(diào)函數(shù): int (*callback)(void*,int,char**,char**), /* Callback function */ 第一個參數(shù)通過sqlite3_exec的第第四個參數(shù)傳入的 第二個參數(shù)是結(jié)果行的列數(shù) 第三個參數(shù)是行中列數(shù)據(jù)的指針 第四個參數(shù)是行中列名稱的指針 |
|