最近由於項目的需要,需要一個小型的資料庫的支援,我找到了SQLite ,它是我見到過最簡單最方便的資料庫,而且我可以免費獲得原代碼,對於SQLite的作者我更是佩服的五體投地!
SQLite的是: http://www.sqlite.org/download.html
我下載的是SQLite3,如果你只是的簡單增刪改的功能,那麼下面幾個api足夠你使用的了!
typedef struct sqlite3 sqlite3; //一個標記資料對象的結構
int sqlite3_open(const char*, sqlite3**); //開啟資料庫,第一個參數是資料庫檔案名,第二個返回開啟的資料庫物件的結構指標
int sqlite3_open16(const void*, sqlite3**); //同樣開啟資料,不同的是編碼方式是UTF16,上面的是UTF8的格式,需要注意的地方
int sqlite3_close(sqlite3*); //關閉資料庫
const char *sqlite3_errmsg(sqlite3*); //擷取最近一次操作錯誤資訊,api中不帶16標記的模式都是UTF8的格式
const void *sqlite3_errmsg16(sqlite3*); //同樣不用多說
int sqlite3_errcode(sqlite3*); //這是返回錯誤碼
int sqlite3_exec(sqlite3 *db, const char *zSql, sqlite3_callback xCallback,void *pArg, char **pzErrMsg); //該api用的比較多
//具體意思就是執行sql語句,第三個和第四個參數用於設定回呼函數的,最後一個參數返回錯誤資訊.
還有一個比較方便的api:
int sqlite3_get_table(
sqlite3 *db, /* The database on which the SQL executes */
const char *zSql, /* The SQL to be executed */
char ***pazResult, /* Write the result table here */
int *pnRow, /* Write the number of rows in the result here */
int *pnColumn, /* Write the number of columns of result here */
char **pzErrMsg /* Write error messages here */
)
這個api利用sql語句查詢的時候結果直接返回到pazResult中,但是必須記著調用sqlite3_free_table(pazResult)釋
放它!
好了,這個api足夠你應付了,如果需要更深的瞭解,感覺看它的代碼就好了,注視寫的很全,不過都是e文,:)
說明:我下載的原始碼是
sqlite-amalgamation-3_4_2.zip (616.06 KiB) |
|
This ZIP archive contains all preprocessed C code combined into a single source file (the amalgamation). |
該代碼簡單,而且就一個標頭檔,哈哈,下面給個簡單的例子:
// SQLiteDemo.cpp : 定義控制台應用程式的進入點。
//
#include "stdafx.h"
extern "C"
{
#include "sqlite3.h"
};
//sqlite3的回呼函數
// sqlite 每查到一條記錄,就調用一次這個回調
int LoadMyInfo( void * para, int n_column, char ** column_value, char ** column_name )
{
//para是你在 sqlite3_exec 裡傳入的 void * 參數
//通過para參數,你可以傳入一些特殊的指標(比如類指標、結構指標),然後在這裡面強制轉換成對應的類型(這裡面是void*類型,必須強制轉換成你的類型才可用)。然後操作這些資料
//n_column是這一條記錄有多少個欄位 (即這條記錄有多少列)
// char ** column_value 是個關索引值,查出來的資料都儲存在這裡,它實際上是個1維數組(不要以為是2維數組),每一個元素都是一個 char * 值,是一個欄位內容(用字串來表示,以/0結尾)
//char ** column_name 跟 column_value是對應的,表示這個欄位的欄位名稱
//這裡,我不使用 para 參數。忽略它的存在.
int i;
printf( "記錄包含 %d 個欄位/n", n_column );
for( i = 0 ; i < n_column; i ++ )
{
printf( "欄位名:%s ?> 欄位值:%s/n", column_name[i], column_value[i] );
}
printf( "------------------/n" );
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
sqlite3 * db = NULL; //聲明sqlite關鍵結構指標
int result;
//開啟資料庫
//需要傳入 db 這個指標的指標,因為 sqlite3_open 函數要為這個指標分配記憶體,還要讓db指標指向這個記憶體區
result = sqlite3_open("D://Projects//demo//SQLiteDemo//wwxSQLite.db", &db );
if( result != SQLITE_OK )
{
//資料庫開啟失敗
return -1;
}
//資料庫作業碼
//建立一個測試表,表名叫 MyTable_1,有2個欄位: ID 和 name。其中ID是一個自動增加的類型,以後insert時可以不去指定這個欄位,它會自己從0開始增加
char * errmsg = NULL;
result = sqlite3_exec( db, "create table MyTable_2( ID integer primary key autoincrement, name nvarchar(32) , translate nvarchar(1024))", NULL, NULL, &errmsg );
if(result != SQLITE_OK)
{
printf( "建立表失敗,錯誤碼:%d,錯誤原因:%s/n", result, errmsg );
}
//插入一些記錄
result = sqlite3_exec( db, "insert into MyTable_2( name, translate) values ( '走路', 'haha')", 0, 0, &errmsg );
if(result != SQLITE_OK )
{
printf( "插入記錄失敗,錯誤碼:%d,錯誤原因:%s/n", result, errmsg );
}
result = sqlite3_exec( db, "insert into MyTable_2( name,translate) values ( '騎單車', 'hello' )", 0, 0, &errmsg );
if(result != SQLITE_OK )
{
printf( "插入記錄失敗,錯誤碼:%d,錯誤原因:%s/n", result, errmsg );
}
result = sqlite3_exec( db, "insert into MyTable_2( name,translate ) values ( '坐汽車', 'good')", 0, 0, &errmsg );
if(result != SQLITE_OK )
{
printf( "插入記錄失敗,錯誤碼:%d,錯誤原因:%s/n", result, &errmsg );
}
//開始查詢資料庫,這裡使用回呼函數查詢
result = sqlite3_exec( db, "select * from MyTable_2", LoadMyInfo, NULL, &errmsg );
//下面使用sqlite3_get_table //開始查詢,傳入的 dbResult 已經是 char **,這裡又加了一個 & 取地址符,傳遞進去的就成了 char ***
char ** dbResult;
int nRow,nColumn;
int index;
result = sqlite3_get_table( db, "select * from MyTable_2", &dbResult, &nRow, &nColumn, &errmsg );
if( SQLITE_OK == result )
{
//查詢成功
index = nColumn; //前面說過 dbResult 前面第一行資料是欄位名稱,從 nColumn 索引開始才是真正的資料
printf( "查到%d條記錄/n", nRow );
for(int i = 0; i < nRow ; i++ )
{
printf( "第 %d 條記錄/n", i+1 );
for(int j = 0 ; j < nColumn; j++ )
{
printf( "欄位名:%s ?> 欄位值:%s/n", dbResult[j], dbResult [index] );
++index; // dbResult 的欄位值是連續的,從第0索引到第 nColumn - 1索引都是欄位名稱,從第 nColumn 索引開始,後面都是欄位值,它把一個二維的表(傳統的行列標記法)用一個扁平的形式來表示
}
printf( "-------/n" );
}
}
//到這裡,不論資料庫查詢是否成功,都釋放 char** 查詢結果,使用 sqlite 提供的功能來釋放
sqlite3_free_table( dbResult );
//關閉資料庫
sqlite3_close( db );
system("PAUSE");
return 0;
}
上面的代碼是借別人的代碼改的,很簡單!希望對你有用,:)
作者:wangweixing2000 2007.8.24