在前面的博客中已經介紹了如何連接SQLite數據庫,并且簡單的查詢和遍歷結果集。在前面用到了sqlite3_stmt *stmt,也就是預編譯后的SQL語句。在本篇博客中會了解一下sqlite3_stmt,然后了解一下變量的綁定。變量綁定,簡單的說就是往預編譯后的SQL語句中傳入相應的值。
一. sqlite3_stmt 的生命周期
這個對象的實例代表著一個被編譯成二進制的SQL語句。每個SQL語句都必須經過預編譯轉換成sqlite3_stmt才能被執行。在iOS開發中,application或者UIViewController等都是有自己的生命周期的,預編譯語句也是有自己的生命周期的,其生命周期如下:
1.sqlite3_stmt對象的生命起源于sqlite3_PRepare_v2(), 使用sqlite3_prepare_v2()可以創建sqlite3_stmt對象。
2.使用sqlite3_bind_*()接口可以給sqlite3_stmt對象綁定變量。
3.調用sqlite3_step()一次或者多次來運行SQL語句。
4.調用sqlite3_reset()回到上一次執行的SQL語句,你可以調用sqlite3_reset()多次,sqlite3_reset()更像版本管理中的回滾操作。
5.使用sqlite3_finalize()析構函數來釋放sqlite3_stmt對象。
sqlite3_stmt對象的構造函數(推薦使用“v2”接口):sqlite3_prepare(), sqlite3_prepare16(), sqlite3_prepare16_v2(), sqlite3_prepare_v2()
sqlite3_stmt對象的析構函數:sqlite3_finalize()
下方是有關sqlite3_stmt對象的接口,本篇博客主要介紹有關sqlite3_bind_*()的方法。
二、值綁定
先簡單介紹一下什么是值綁定吧。用大白話說,值綁定就是在SQL語句預編譯時把一些參數使用占位符(這里是?號)來代替,然后與程序中的變量進行綁定。類似于字符串的格式化。如果你之前搞過java的JDBC或者php, 在他們操作數據庫執行SQL語句時都有類似值綁定的一個概念。 就是把外界變量把SQL語句占位的值進行替換。值綁定經常在SELECT,INSERT,UPDATE等語句中進行使用。
1.為預編譯SQL語句綁定變量,綁定不同類型變量需要不同的綁定接口,下方是常用的綁定變量的接口。
2.在sqlite3_prepare_v2()輸入的SQL語句的文本中,下面的這些參數將會被替換掉,在下面的參數中,NNN表示一個整數(這個整數就代表這個參數的索引),VVV代表一個字母標示符(參數的名字)。可以使用sqlite3_bind_*()函數為上面的這些占位符進行賦值。
說的直白一些,“?”號就是匿名參數,從第一個問號出現往后的索引默認是1,往后以此類推。而“?NNN”是為匿名參數指定索引,你可以這樣寫“?1” , "?2"等,而:VVV, @VVV, $VVV這些就是有名參數了,VVV就是參數的名字。比如:ludashi, @ludashi, $ludashi。
下面的實例給出了參數不同的幾種表現形式, 前一種是匿名參數,后邊參數就有自己的名字了。
3.sqlite3_bind_*()參數介紹(這些綁定函數執行成功后回返回SQLITE_OK, 執行不成功的話回返回相應的錯誤代碼)
(1) sqlite3_bind_*()的第一個參數是含有上述占位符預編譯后的語句指針,也就是sqlite3_stmt的對象。
(2) sqlite3_bind_*()的第二個參數是SQL語句中參數的索引,例如第一個參數的索引值是1,那么就傳1。匿名參數的索引是從1開始往后遞增的,而有參數名稱的可以通過sqlite3_bind_parameter_index()接口傳入參數名稱來獲取該參數的索引,sqlite3_bind_parameter_index()用法如下,第一個參數是sqlite3_stmt的對象,而后邊的參數是SQL參數名稱,返回值就是該參數的索引。
int index = sqlite3_bind_parameter_index(statement, "$brandidMin");
(3) 第三個參數是要綁定的值。
(4) sqlite3_bind_blob(), sqlite3_bind_text()和sqlite3_bind_text16()這三個接口中還有有第四和第五個參數,第四個參數代表第三個參數“綁定值”的字節長度。第五個參數是一個指向內存管理回調函數的指針。
4.每個綁定函數的使用場景
(1) BLOB是數據庫中存儲大數據的一種數據類型,它是以二進制的形式來存儲數據的。
1 SQLITE_API int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
(2) 顧名思義,下面的方法是綁定double類型的數據的
1 SQLITE_API int sqlite3_bind_double(sqlite3_stmt*, int, double);
(3) 綁定一個32位的整型值
1 SQLITE_API int sqlite3_bind_int(sqlite3_stmt*, int, int);
(4) 綁定一個64位的整型值
1 SQLITE_API int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
(5)綁定一個NULL的值(在數據庫中可以為NULL)
1 SQLITE_API int sqlite3_bind_null(sqlite3_stmt*, int);
(6)綁定一個UTF-8編碼的字符串,第四個參數上面也提到了,是綁定字符串的長度,如果為負值的話,就是傳多少就綁定多少。
1 SQLITE_API int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*));
(7)綁定一個UTF-16編碼的字符串,第四個參數上面也提到了,是綁定字符串的長度,如果為負值的話,就是傳多少就綁定多少。
1 SQLITE_API int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
(8) 綁定sqlite3_value結構體類型的值,sqlite3_value結構體可以保存任意格式的數據。
SQLITE_API int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
(9)綁定一個任意長度的BLOB類型的二進制數據,它的每一個字節被置0。第3個參數是字節長度。這個函數的特殊用處是,創建一個大的BLOB對象,之后可以通過BLOB接口函數進行更新。
1 SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
5.值綁定常用工具函數
(1)下方的函數返回預編譯SQL語句中參數的個數,這些參數可以是匿名參數,也可以是有名參數。
具體用法如下:
1 int count = sqlite3_bind_parameter_count(statement);2 NSLog(@"%d", count);
(2)通過索引獲取對應參數的名稱
具體用法如下:
1 const char * name = sqlite3_bind_parameter_name(statement, 1);2 NSLog(@"%s", name);
(3) 在一個是通過名字獲取索引了,正好和上面的方法相反。
調用方式如下:
1 int index = sqlite3_bind_parameter_index(statement, ":brandidMax");2 NSLog(@":brandidMax——index = %d", index);
三、值綁定實例
下面的實例是在查詢語句中使用值綁定,綁定完值后,調用查詢數據庫的方法,然后進行數值的輸出,因為上面說的夠多了,下面的代碼就不用加注釋了。
1 -(void) qureyInfoWithDataBase2: (sqlite3 *) database{ 2 3 NSString * qureyInfo = @"SELECT * FROM CARBRAND WHERE BRANDID > :brandidMin AND BRANDID < :brandidMax"; 4 5 sqlite3_stmt *statement; 6 7 const char * zSql = [qureyInfo UTF8String]; 8 9 int result = sqlite3_prepare_v2(database, zSql, -1, &statement, nil);10 11 int count = sqlite3_bind_parameter_count(statement);12 NSLog(@"count = %d", count);13 14 const char * name = sqlite3_bind_parameter_name(statement, 1);15 NSLog(@"name = %s", name);16 17 if (result == SQLITE_OK) {18 19 int index = sqlite3_bind_parameter_index(statement, ":brandidMax");20 NSLog(@":brandidMax_index = %d", index);21 22 //值綁定23 sqlite3_bind_int(statement, 1, 180);24 sqlite3_bind_int(statement, 2, 200);25 26 [self queryUserInfoWith: database WithStatement: statement];27 }28 29 }
查詢數據庫的方法
1 //查詢數據庫 2 - (void) queryUserInfoWith: (sqlite3 *) database WithStatement: (sqlite3_stmt *) statement { 3 4 while (sqlite3_step(statement) == SQLITE_ROW) { 5 6 int rowNum = sqlite3_column_int(statement, 0); 7 8 char *rowDataOne = (char *) sqlite3_column_text(statement, 1); 9 10 char *rowDataTow = (char *) sqlite3_column_text(statement, 2);11 12 NSString *nameString = [NSString stringWithUTF8String:rowDataOne];13 14 NSString *firstLetterString = [NSString stringWithUTF8String:rowDataTow];15 16 NSLog(@"BrandId = %d, Name = %@, FirstLetter = %@",rowNum , nameString, firstLetterString);17 18 }19 sqlite3_finalize(statement);20 21 }
輸入結果如下:
今天博客就先到這兒,關于SQLite數據庫的東西會繼續更新。
新聞熱點
疑難解答