sqlite3基礎
要使用sqlite,首先需要添加庫文件libsqlite3.dylib。當你搜索libsqlite3關鍵字時,會發現還有一個libsqlite3.0.dylib的庫文件,這里還是建議添加libsqlite3.dylib,原因在于libsqlite3.dylib是一個替身文件,它總是指向最新的sqlite3動態庫;假如出現了新的動態庫libsqlite3.1.dylib,那么libsqlite3.dylib將指向它,而libsqlite3.0.dylib無法指向。
在對sqlite數據庫進行操作前先聲明一個sqlite3類型的對象:
sqlite3 *db;
sqlite3_open — 創建并打開一個sqlite數據庫
SQLITE_API int sqlite3_open( const char *filename, /* Database filename (UTF-8) */ sqlite3 **ppDb /* OUT: SQLite db handle */ );
sqlite3_close — 關閉一個sqlite數據庫
SQLITE_API int sqlite3_close(sqlite3*);
示例1:創建并打開sqlite數據庫
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsPath = [paths objectAtIndex:0]; NSLog(@"documentsPath: %@",documentsPath); NSString *databasePath = [documentsPath stringByAppendingPathComponent:@"personinfo.sqlite"]; NSLog(@"databasePath: %@",databasePath); int state = sqlite3_open([databasePath UTF8String], &db); NSLog(@"%d",state); if(state != SQLITE_OK) { sqlite3_close(db); NSLog(@"數據庫打開失敗"); }
sqlite3_exec — 執行非查詢的sql語句
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 */ );
示例2:執行創建表、插入數據操作
- (BOOL)execSql:(NSString *)sql { char *err; if (sqlite3_exec(db, [sql UTF8String], NULL, NULL, &err) != SQLITE_OK) { sqlite3_close(db); NSLog(@"execute sql fail!"); return NO; } else { NSLog(@"execute sql succeed!"); return YES; } } - (IBAction)createTable:(id)sender { NSLog(@"button clicked"); NSString *strSql = @"CREATE TABLE IF NOT EXISTS PERSONINFO (ID INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER, address TEXT)"; [self execSql:strSql]; } - (IBAction)insertAction:(id)sender { NSLog(@"insert action"); NSString *sql1 = [NSString stringWithFormat: @"INSERT INTO 'PERSONINFO' ('name', 'age', 'address') VALUES ('%@', '%@', '%@')", @"張三", @"23", @"西城區"]; NSString *sql2 = [NSString stringWithFormat: @"INSERT INTO 'PERSONINFO' ('name', 'age', 'address') VALUES ('%@', '%@', '%@')", @"老六", @"20", @"東城區"]; [self execSql:sql1]; [self execSql:sql2]; }
sqlite3_stmt — 相當于ODBC的command對象,用于保存編譯好的sql語句
sqlite3_prepare_v2 — 這個函數將sql文本轉換成一個準備語句(prepared statement)對象,同時返回這個對象的指針。它實際上并不執行這個sql語句,僅僅為執行而準備這個sql語句,也就是說,在調用該函數成功(SQLITE_OK)后,sqlite3_stmt將不再為空對象。
SQLITE_API int sqlite3_prepare_v2( sqlite3 *db, /* Database handle(數據庫指針) */ const char *zSql, /* SQL statement, UTF-8 encoded(使用UTF-8編碼的SQL語句) */ int nByte, /* Maximum length of zSql in bytes.(如果nByte小于0,則函數取出zSql中從開始到第一個0終止符的內容;如果nByte為非負數,那么它就是這個函數能從zSql中讀取的最大字節數。如果nBytes為非負數,zSql在第一次遇見/000或u000的時候終止) */ sqlite3_stmt **ppStmt, /* OUT: Statement handle(能夠使用sqlite3_step()執行的編譯好的準備語句的指針,如果錯誤發生,它被置為NULL,例如輸入一個不正確的sql語句。調用過程必須負責在編譯好的sql語句完成使用后,調用sqlite3_finalize()刪除它。 */ const char **pzTail /* OUT: Pointer to unused portion of zSql(當zSql在遇見終止符或者達到設定的nByte結束后,如果還有剩余的內容,那么這些剩余的內容將被存放到pzTail中,不包含終止符) */ );
sqlite3_step — 執行由sqlite3_prepare創建的準備語句。當調用后返回SQLITE_ROW,則代表還有更多行,可繼續調用sqlite3_step直至返回SQLITE_DONE。對于insert、update或delete語句,也可以用sqlite3_step來執行,但更推薦用sqlite3_exec。
SQLITE_API int sqlite3_step(sqlite3_stmt*);
sqlite3_step的返回值取決于創建sqlite3_stmt參數所使用的函數,假如使用老版本的接口sqlite3_prepare()或sqlite3_prepare16(),返回值會是SQLITE_BUSY、SQLITE_DONE, SQLITE_ROW, SQLITE_ERROR 或 SQLITE_MISUSE;而v2版本的接口sqlite3_prepare_v2()和sqlite3_prepare16_v2()除了這些值以外,還可能返回擴展狀態碼。
sqlite3_reset — 重置一個準備語句(prepared statement)對象到它的初始狀態,準備被重新執行。在V3.6.23.1以后,sqlite3_step()將會自動調用sqlite3_reset。
SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
sqlite3_finalize — 銷毀一個準備語句(prepared statement)對象,在需要時執行這個銷毀函數以防止內存泄露。在準備語句對象為空指針時調用這個函數也沒有什么影響。
SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt);
示例3:利用sqlite3_step執行更新操作
- (IBAction)updateAction:(id)sender { NSString *sqlQuery = @"update PERSONINFO set address='成都市' where age='20'"; sqlite3_stmt *statement; if(sqlite3_prepare_v2(db, [sqlQuery UTF8String], -1, &statement, nil) == SQLITE_OK) { if(sqlite3_step(statement) == SQLITE_DONE) { NSLog(@"update succeed"); } else { NSLog(@"update failed"); } } sqlite3_finalize(statement); }
sqlite3_column — 并不存在sqlite3_column這個函數,它只是一個前綴,下面是相關的具體函數:
SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); SQLITE_API int sqlite3_column_bytes(sqlite3_stmt*, int iCol); SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt*, int iCol); SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol); SQLITE_API int sqlite3_column_int(sqlite3_stmt*, int iCol); SQLITE_API sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol); SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol); SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt*, int iCol); SQLITE_API int sqlite3_column_type(sqlite3_stmt*, int iCol); SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);
上面的函數用來得到結果集當前行中某一列的值,列索引從0開始。
示例4:查詢并打印出結果集
- (IBAction)selectAction:(id)sender { NSString *sqlQuery = @"SELECT * FROM PERSONINFO"; sqlite3_stmt *statement; if (sqlite3_prepare_v2(db, [sqlQuery UTF8String], -1, &statement, nil) == SQLITE_OK) { while (sqlite3_step(statement) == SQLITE_ROW) { char *cID = (char*)sqlite3_column_text(statement, 0); NSString *strID = [[NSString alloc] initWithUTF8String:cID]; char *cName = (char*)sqlite3_column_text(statement, 1); NSString *strName = [[NSString alloc] initWithUTF8String:cName]; int age = sqlite3_column_int(statement, 2); char *cAddress = (char*)sqlite3_column_text(statement, 3); NSString *strAddress = [[NSString alloc] initWithUTF8String:cAddress]; NSLog(@"id:%@ name:%@ age:%d address:%@",strID, strName, age, strAddress); } } sqlite3_finalize(statement); }

浙公網安備 33010602011771號