SQLite是一款輕型的資料庫。能夠支援Windows/Linux/Unix等等主流的作業系統,同時能夠跟很多程式語言相結合。佔用資源非常的低,但處理速度卻是相當的快。近期做了關於SQLite的項目。學會了一些初級的用法。先總結如下:
一、 獲得sqlite3.lib檔案
在SQLite官方網站上只能下載到sqlite dll和相應的原始碼,要想在VC中使用還必須用到sqlite3.lib檔案(當然也可以通過LoadLibrary和GetProAddress來使用,但一般項目中都會用到很多SQLite提供的函數,這樣難免會顯得比較麻煩)。在網上搜到此類問題的剞劂辦法。具體過程如下:
1、 下載sqlite dll;
2、 通過命令列使用Microsoft Visual Studio\\VC98\\Bin下的LIB命令產生.lib。參照如下樣本。
C:\\Program Files\\Microsoft Visual Studio\\VC98\\Bin>LIB /out:D:\\test\\sqlite3.lib /MACHINE:IX86 /DEF:D:\\test\\sqlite3.def
表示根據D:\test\sqlite3.def產生sqlite3.lib,並放到D:\test\路徑下
二、 有了sqlite3.lib檔案,就可以在VC下使用SQLite資料庫了
1、 串連/關閉資料庫
int sqlite3_open(const char *filename, sqlite3 **ppDb)
filename為資料庫名,如不在其當前工程路徑,需要加上絕對路徑,否則會在當前工程下建立一個同名的空資料庫.
ppDb 為指向結構體sqlite3 指標變數的地址.
傳回值:如果傳回值為SQLITE_OK 的話,則表示成功.否則返回錯誤號碼.可以在sqlite3.h檔案中找到錯誤號碼對應的意義,也可以通過函數sqlite3_errmsg(sqlite3*);擷取錯誤資訊
int sqlite3_close(sqlite3 *) 關閉資料庫
2、 執行sql語句(查詢資料庫)
法一:
int sqlite3_exec(sqlite3*, const char *sql, sqlite3_callback, void *, char **errmsg )
參數說明:
Sql:以”\0”結尾的sql語句;
sqlite3_callback,:為執行sql語句的回呼函數,不用可以為NULL,回呼函數原形下邊介紹;
void *變數是作為回呼函數的第一個參數的
errmsg為擷取執行改函數可能得到的錯誤資訊
回呼函數原形:typedef int (*sqlite3_callback)( void *para, int colun_count, char **column_values, char **column_names)
Para:sqlite3_exec函數中的第四個參數
colun_count:為該次查詢到一行喲多少列(如果sql語句為 select * from ..,則為資料庫中一條記錄的列數,當sql語句為select field1,field2 form時,則為你艘查的欄位數)
column_names:指向欄位名所在二維數組的指標
column_values:column_names對應的值;
法二:
int sqlite3_get_table(sqlite3*, const char *sql, char ***resultp, int *nrow, int *ncolumn, char **errmsg );
resultp為查詢結果,它記憶體布局是:第一行是欄位名稱,是緊接著是每個欄位的值
其他參數同上。
對應布局(查詢了2個欄位):
name id
Tom 1
Bill 2
John 3
但我們一般認為他是字串組成的一維數組
對應關係為
result [0] = "name"; 0 = 0 *(*ncolumn)+ 0
result [1] = "id"; 1 = 0 *(*ncolumn)+ 1
result [2] = " Tom "; 2 = 1 *(*ncolumn)+ 0
result [3] = "1";
result [4] = " Bill ";
result [5] = "2";
result [6 ]= "John
result [7 ]= "3;
注意:使用法二後必須用sqlite3_free_table(azResult)釋放資源
3、執行其他sql語句
仍然使用sqlite3_exec函數執行響應的增、刪、改以及建立表的sql語句;
4、擷取指定資料庫的相關資訊
A、擷取指定資料庫中所有表的資訊
執行sql語句
"select * from sqlite_master where type='table' order by name"
其中有個欄位為name 他所代表的就是資料表的名字
B、擷取指定表的資訊包括欄位名以及某個欄位的類型。
I把sql語句 “select * form tab_name”通過函數sqlite3_prepare解析到sqlite3_stmt結構裡去
int sqlite3_prepare(sqlite3 *db,const char *zSql, int nByte,
sqlite3_stmt **ppStmt, char **pzTail)
nByte表示sql語句的長度,當為-1時,該語句會自動計算其長度,
pzTail一般給0(NULL)就行。
II、通過函數sqlite3_step執行剛才解析到sqlite3_stmt中的sql語句,沒次查詢一條記錄(查詢一行就夠了)
int sqlite3_step(sqlite3_stmt*);
III、利用函數擷取所需資訊
//擷取第N列的欄位名(從0開始)
const char *sqlite3_column_name(sqlite3_stmt*, int N);
//擷取第N列建表時宣告類型(聲明為varchar(10),得到為varchar(10))
const char *sqlite3_column_decltype (sqlite3_stmt*, int iCol)
//擷取SQLite的類型(類型號為int型)
int sqlite3_column_type (sqlite3_stmt*,int);
#define SQLITE_INTEGER 1
#define SQLITE_FLOAT 2
#define SQLITE_TEXT3 3
#define SQLITE_BLOB 4
#define SQLITE_NULL 5
IV、完畢之後使用sqlite3_finalize釋放之前得到的結構sqlite3_stmt,樣本為:
sqlite3_finalize( stat );
C、擷取指定表中的記錄數
執行sql語句”select COUNT(*) from”,其結果就為指定表中的記錄數,要將得到的結果從char * 型轉化為int型
三、 對位元據的操作。
以上有關查詢、寫入資料的操作都是在沒有二進位欄位的條件下進行的,SQLite中對含有二進位的表進行查詢和寫入有單獨的方法。
1、 寫入位元據
//首先將查詢語句解析到結構sqlite3_stmt中去(tab_blob2個欄位 ID和data)。
sqlite3_stmt * stat;
sqlite3_prepare( db, “insert into tab_blob ( ID,data) values( 10, ? )”, -1, &stat, 0 )
其中“?”表示data欄位還處於未知狀態,等會才插入
注意:該函數執行成功的條件為:傳回值SQLITE_OK 且 stat 不為NULL
//將位元據進行綁定
sqlite3_bind_blob( stat, 1, pdata, (int)(length_of_data_in_bytes), NULL )
第二個參數為前邊“?”在表中的序號(從0開始),此處1表示第二個欄位
如果有多個“?”怎麼辦?
那就多執行幾次sqlite3_bind_blob,並且改變第二個參數。
Pdata為位元據在記憶體中的起始地址
length_of_data_in_bytes為位元據以位元組為單位的長度
第5個參數:是個析夠回呼函數,告訴sqlite當把資料處理完後調用此函數來析夠你的資料。一般都填NULL,需要釋放的記憶體自己用代碼來釋放
//把需要寫入的資料寫入資料庫
int result = sqlite3_step( stat );
//釋放sqlite3_stmt資料
sqlite3_finalize( stat );
2、 讀位元據
sqlite3_prepare( db, “select * from tab_blob”, -1, &stat, 0 );
prepare函數返回SQLITE_OK後,表示成功
通過int result = sqlite3_step( stat );進行查詢資料;
每次查詢一行,傳回值為SQLITE_ROW表示查詢成功,當傳回值不為SQLITE_ROW時表示查詢結束.
然後是通過對應與欄位類型的函數獲得各個欄位的值。
//擷取int型
int sqlite3_column_int(sqlite3_stmt*, int iCol);
//擷取duble型
double sqlite3_column_double(sqlite3_stmt*, int iCol);
//擷取TEXT型
const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
//擷取二進位型
const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);//擷取位元據在記憶體位址
int sqlite3_column_bytes(sqlite3_stmt*, int iCol);//擷取位元據的長度
四、 關於中文路徑開啟檔案失敗的處理
很多時候我們會發現當資料庫檔案處於中文路徑下時,就會開啟檔案失敗。這主要是由於SQLite使用utf8格式,所以需要將其轉換為相應的格式。可以通過函數
WideCharToMultiByte(CP_UTF8,,.....)進行轉換,當然如果你的路徑為多位元組的話,你首先得將路徑轉換為Widechar才行。
ey:
int sqlite_data_operate::connect_database(const char *database_full_name)
{
CA2T lpt_str(database_full_name);
char data_base[1024] = {0};
int size = WideCharToMultiByte(CP_UTF8, 0, lpt_str, -1, data_base, 0, NULL, NULL);
WideCharToMultiByte(CP_UTF8, 0, lpt_str, -1, data_base, size, NULL, NULL);
return sqlite3_open(data_base, &m_db);
}