SQLite Using C Library(1)
NSString to C String
C語言所使用的字串方式是以char的類型去儲存內容,而Objective-C卻是用物件的方式去使用,所以字串方面需要轉換成C語言能接受的方式。
假設有個NSString名稱為 sqlitepath ,並將它轉成 databaseFileName 的char類型。
const char *databaseFileName =[sqlitepath UTF8String];
因為在NSString中是使用UTF8編碼進行儲存,利用這方式將字串的每個字取出並存入char的指標中。
引用SQLite C Library
標頭檔上必需要引用
#import <sqlite3.h>
並且必需要引用Library,在引用時先依照下圖到專案設定的 General ,並按下 +
之後到搜尋列輸入關鍵字 sqlite
選擇 libsqlite3.dylib 並按下 Add 將Library引入,引入成功會看到下圖
如此一來配合 sqlite3.h 才會發揮作用。
開啟資料庫
開啟資料的方式像下面般的格式:
returnCode= sqlite3_open(路徑, 資料庫指標);
範例中我們將 sqlitedata.db放在mainBundle之中,程式會先判斷檔案是否存在,不存在會有提示,
char *sqlStatement; sqlite3 *pDb; char *errorMsg; int returnCode; NSString *sqlitepath = [[NSBundle mainBundle] pathForResource:@"sqlitedata" ofType:@"db"]; if ([[NSFileManager defaultManager] fileExistsAtPath:sqlitepath]){ NSLog(@"檔案存在!"); //這裡放置如果檔案存在時的程式 }else{ NSLog(@"檔案不存在!"); } NSLog(@"%@",sqlitepath); const char *databaseFileName =[sqlitepath UTF8String]; returnCode= sqlite3_open(databaseFileName, &pDb); if(returnCode!=SQLITE_OK) { fprintf(stderr, "Error in opening the database. Error: %s", sqlite3_errmsg(pDb)); sqlite3_close(pDb); return; }
SQLITE_OK 代表整個SQLite命令是完成並且無問題產生。
執行SQL語法命令
在於整個SQL資料庫的操作是使用執行語法命令再加上回呼點(callback)設定的方式去操作:
返回碼 = sqlite3_exec(資料庫指標, 資料庫語法, callback名稱, NULL, 錯誤訊息);
原始標頭檔定義:
SQLITE_API 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 */ );
所以只要操作語法命令正確,就可以得到所預期的結果。
刪除資料表
我們在使用時先將建立好的資料表內容都刪除,避免在學習時會有重覆的資料產生,所以我們執行
DROP TABLE IF EXISTS stocks
刪除 stocks 資料表,程式內容:
sqlStatement = "DROP TABLE IF EXISTS stocks"; returnCode = sqlite3_exec(pDb, sqlStatement, NULL, NULL, &errorMsg); if(returnCode!=SQLITE_OK) { fprintf(stderr, "Error in droping table stocks. Error: %s", errorMsg); sqlite3_free(errorMsg); }
刪除資料表只需要確定返回碼正確就可以,不需要設定callback,每次執行之後得到的結果是 SQLITE_OK 就代表整個過程是沒問題的,返回碼可以參照 sqlite3.h
新增資料表及資料庫格式
新增資料因重覆性很高,我將它寫成Function來使用:
void insertData(sqlite3 *pDb, const char*symbol, float price, int units, const char* date){ char *errorMsg; int returnCode; char *st; st = sqlite3_mprintf("INSERT INTO stocks VALUES ('%q', %f, %d, '%q')", symbol, price, units, date); returnCode = sqlite3_exec(pDb, st, NULL, NULL, &errorMsg); if(returnCode!=SQLITE_OK) { fprintf(stderr, "Error in inserting into the stocks table. Error: %s", errorMsg); sqlite3_free(errorMsg); } sqlite3_free(st); }
程式碼中使用 sqlite3_mprintf 來建立執行的語法,這是利用格式化的方式來建立語法,這樣大大的改善可讀性及輸入可建立functaion的特性,然而 sqlite3_mprintf 功能就如同 sprintf 。 範例中連續建立很多筆的資料:
insertData(pDb, "ALU", 14.23, 100, "03-17-2012"); insertData(pDb, "GOOG", 600.77, 20, "01-09-2012"); insertData(pDb, "NT", 20.23, 140, "02-05-2012"); insertData(pDb, "MSFT", 30.23, 5, "01-03-2012"); insertData(pDb, "中文測試!", 30.23, 5, "01-03-2012");
範例程式除了上述的提到的內容外,會在新增完將資料筆數顯示,來確定內容是否新增完成,顯示的技巧會在下次說明。