天天看點

Mac OS X Sqlite程式設計應用

Sqlite是一個輕量級的資料庫引擎,大概幾百K左右,是以在嵌入式裝置中應用廣泛;而且由于接口簡單,使其在非嵌入式領域中也被大量使用; 詳細内容請參考官方介紹:http://www.sqlite.org/about.html,這裡就不再贅述;

一、工程中引入sqlite3

資料庫建立前需要在程式中引入sqlite3庫檔案以及在代碼中添加sqlite3頭檔案;以XCode開發環境為例,需要在“Target->Build->Other Linker Flags”中加入“-lsqlite3”連結選項;記得代碼檔案中加入#import <sqlite3.h>;

二、資料庫建立

資料庫建立類似檔案建立,使用sqlite3_open()函數,如果不存在就建立,如果存在就打開;

sqlite3 *db = NULL;

int rc;

char * dbPath = "myTest.db3";

rc = sqlite3_open(dbPath, &db);

if(rc)

{

printf("Open database failed!");

sqlite3_close(db);

return 1;

}

       使用sqlite3建立的資料庫檔案名稱以db3作為檔案類型并非必需,而是和sqlite檔案有個差別;資料檔案首次建立後,還需要建立表;代碼如下:

//create or open Table

char *sql = " CREATE TABLE ContactTbl("/

"ID INTEGER PRIMARY KEY,"/

"Name VARCHAR(80),"/

"TEL1 VARCHAR(20),"/

"EMAIL VARCHAR(40)"/

");";

sqlite3_exec(db, sql, 0, 0, &zErrMsg);

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

       網上有許多檢視和編輯sqlite3資料庫檔案的可視化小工具,例如:SQLiteSpy.exe;這樣進行資料庫分析和修改時就不必每次都自己寫代碼來操作了;

三、資料庫插入

向剛才建立的表中添加一個條目,由于sqlite網站中都是英文資料類型,我使用UTF8編碼格式的代碼檔案(XCode預設代碼檔案格式為UTF8編碼)直接輸入中文字元,能夠正常執行,其他編碼格式沒有試過,感覺應該不會有什麼問題,改天有時間嘗試一下;

//insert three item

sql = "INSERT INTO /"ContactTbl/" VALUES(NULL, '小康', '18602914000', '[email protected]');";

sqlite3_exec(db, sql, 0, 0, &zErrMsg);

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

四、資料庫查詢

使用sqlite3_get_table()進行資料查詢時,傳回一個char **類型的字元數組;傳回的行列值分别是表中資料的行和列數目;需要注意的是,傳回的字元數組比實際資料多了一行表頭;是以在使用和輸出時需要注意;按照上面的資料格式,行、列值分别為1、4;而字元數組的數目為(nRow+1)*nColumn;

//query data, don't forget to free the result

char **aResult = NULL;

int nRow = 0;

int nColumn = 0;

sql = "SELECT * FROM ContactTbl";

sqlite3_get_table(db, sql, &aResult, &nRow, &nColumn, &zErrMsg);

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

下面是格式輸出代碼:

//printf("ID/t/t姓名/t/t電話/t/t電子郵件/t/t/n");

//此處不需要輸出表頭,因為字元數組中已經包括表頭

int rowIndex;

for(rowIndex=0; rowIndex<(nRow+1)*nColumn; rowIndex++)

{

printf("%s/t/t", aResult[rowIndex]);

if(0==(rowIndex+1)%nColumn)

{

printf("/n");

}

}

sqlite3_free_table(aResult);

例如下面這張表以及查詢結果資料格式列舉如下:

Name        | Age

-----------------------

Alice       | 43

Bob         | 28

Cindy       | 21

aResult[0] = "Name";

aResult[1] = "Age";

aResult[2] = "Alice";

aResult[3] = "43";

aResult[4] = "Bob";

aResult[5] = "28";

aResult[6] = "Cindy";

aResult[7] = "21";

簡單說,擷取到的字元數組就是将表中某行某列(包括表頭),作為一個字元串,這樣依次存儲下來,成為一個字元串數組,編碼格式為UTF8;

另外,由于查詢傳回的字元數組是在sqlite3_get_table()函數内部配置設定的記憶體空間,使用完成後需要使用sqlite3_free_table()函數進行釋放,此處不能簡單的通過sqlite3_free()函數釋放;

五、資料庫删除

資料庫條目的删除和插入類似,代碼如下:

//delete item

sql = "DELETE FROM ContactTbl WHERE ID = 3;";

sqlite3_exec(db, sql, 0, 0, &zErrMsg);

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

下面附上整個main.m的源代碼:

//

// main.m

// sqlite3Test

//

// Created by kh on 10-11-22.

// Copyright 2010 cx. All rights reserved.

//

#import <sqlite3.h>

#import <Cocoa/Cocoa.h>

int main(int argc, char *argv[])

{

sqlite3 *db = NULL;

int rc;

char * zErrMsg = NULL;

char * dbPath = "myTest.db3";

//create or open database

rc = sqlite3_open(dbPath, &db);

if(rc)

{

printf("Open database failed!");

sqlite3_close(db);

return 1;

}

//create or open Table

char *sql = " CREATE TABLE ContactTbl("/

"ID INTEGER PRIMARY KEY,"/

"Name VARCHAR(80),"/

"TEL1 VARCHAR(20),"/

"EMAIL VARCHAR(40)"/

");";

sqlite3_exec(db, sql, 0, 0, &zErrMsg);

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

//insert three item

sql = "INSERT INTO /"ContactTbl/" VALUES(NULL, '小康', '18602914000', '[email protected]');";

sqlite3_exec(db, sql, 0, 0, &zErrMsg);

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

sql = "INSERT INTO /"ContactTbl/" VALUES(NULL, '小陳', '18602935000', '[email protected]');";

sqlite3_exec(db, sql, 0, 0, &zErrMsg);

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

sql = "INSERT INTO /"ContactTbl/" VALUES(NULL, '小霞', '18602966000', '[email protected]');";

sqlite3_exec(db, sql, 0, 0, &zErrMsg);

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

//query data, don't forget to free the result

char **aResult = NULL;

int nRow = 0;

int nColumn = 0;

sql = "SELECT * FROM ContactTbl";

sqlite3_get_table(db, sql, &aResult, &nRow, &nColumn, &zErrMsg);

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

//printf("ID/t/t姓名/t/t電話/t/t電子郵件/t/t/n");

int rowIndex;

for(rowIndex=0; rowIndex<(nRow+1)*nColumn; rowIndex++)

{

printf("%s/t/t", aResult[rowIndex]);

if(0==(rowIndex+1)%nColumn)

{

printf("/n");

}

}

sqlite3_free_table(aResult);

//delete item

sql = "DELETE FROM ContactTbl WHERE ID = 3;";

sqlite3_exec(db, sql, 0, 0, &zErrMsg);

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

//and requery the data

sql = "SELECT * FROM ContactTbl";

sqlite3_get_table(db, sql, &aResult, &nRow, &nColumn, &zErrMsg);

printf("After delete the ID 3/n");

for(rowIndex=0; rowIndex<(nRow+1)*nColumn; rowIndex++)

{

printf("%s/t/t", aResult[rowIndex]);

if(0==(rowIndex+1)%nColumn)

{

printf("/n");

}

}

sqlite3_close(db);

char para[50] = {0};

sprintf(para, "rm %s", dbPath);

system(para);

return 0;

}

最後的删除語句用于在測試後删除資料庫檔案,避免重複執行後資料庫中有重複條目,呵呵;針對以上代碼,Consel輸出如下:

(null)

(null)

(null)

(null)

(null)

ID Name TEL1 EMAIL

1 小康 18602914000 [email protected]

2 小陳 18602935000 [email protected]

3 小霞 18602966000 [email protected]

(null)

After delete the ID 3

ID Name TEL1 EMAIL

1 小康 18602914000 [email protected]

2 小陳 18602935000 [email protected]

繼續閱讀