資料庫的在上一篇部落格中《SQLite之C語言介面規範(三)——Binding Values To Prepared Statements》用到了如何從查詢結果中取出結果值。今天的部落格就詳細的介紹一下sqlite3_column_*()的方法。在SQLite資料庫C語言介面中,從查詢結果中取出不同型別的值需要不同的介面函式。
一. sqlite3_column_*()介紹
1.下圖是sqlite3_column_*()所包含的方法,由下圖容易的看出取出不同型別的值需要不同的介面函式。可以取出的型別有blob, bytes, bytes16, double, int, int64, text, text16等。介面的第一個引數是我們預編譯的SQL語句(sqlite3_stmt的物件),第二個引數是要取出值得行數(從左往右,起始於0)。上面這些介面返回的資訊是當前查詢行中某列的值。在所有情況下,第一個引數確切的說是指向預編譯語句(由sqlite3_prepare_v2() 函式返回的 sqlite3_stmt *)的指標。 第二個引數是應該返回資訊在行中的列索引(結果集的最左邊的列索引0)。結果集中的列的數量可以使用sqlite3_column_count()來獲取。
如果SQL語句目前並不指向一個有效的行或列索引超出了範圍內,那麼結果集是未定義的。上面這些方法僅僅在呼叫sqlite3_step()函式並且返回SQLITE_ROW的情況下呼叫,不能在sqlite3_reset()和sqlite3_finalize()執行後呼叫上述方法。如果你這樣做了,結果集將是不確定的。
2. sqlite3_column_count()具體使用方法如下, 其引數就是sqlite3_stms *的預編譯語句的指標, 返回值就是當前結果集的列數。
1 2 3 4 |
//獲取查詢結果所有的行數 int columnCount = sqlite3_column_count(statement); NSLog(@"columnCount = %d", columnCount); //columnCount = 4 |
3. sqlite3_column_type()這個函式會返回相應列上資料的型別程式碼。返回的結果是SQLITE_INTEGER, SQLITE_FLOAT, SQLITE_TEXT, SQLITE_BLOB 或者 SQLITE_NULL 其中一種情況。在API中對應介面的巨集定義如下。
sqlite3_column_type()的呼叫必須放在sqlite3_step()函式執行(並且有結果返回),不然就會返回NULL。使用方式如下:
1 2 3 |
int columnType = sqlite3_column_type(statement, 1); NSLog(@"columnType = %d", columnType); //columnType = 3(SQLITE_TEXT) |
4. 如果查詢結果的型別是 BLOB 或者 UTF-8 字串型別,你可以使用sqlite3_column_bytes()方法來獲取該資料的位元組長度。如果結果是UTF-16的字串,sqlite3_column_bytes()方法將會把字串自動轉成UTF-8的字串型別,然後再返回字串的位元組數。 sqlite3_column_bytes16()用法是獲取UTF-16字串數值所佔位元組數的,用法和 sqlite3_column_bytes8()相同。這兩個方法返回的不是字串的字元個數,而是字串所佔位元組的個數,當然所佔位元組的個數在這兒不包括C語言中字串結尾的“”。
該函式的具體用法如下:
1 2 3 |
int currentValueBytes = sqlite3_column_bytes(statement, 2); NSLog(@"%@位元組數為 = %d", firstLetterString, currentValueBytes); |
5. sqlite3_column_value()返回的是一個不受保護的sqlite3_value物件。在多執行緒環境下,一個不受保護的sqlite3_value物件,只有被 sqlite3_bind_value() 和 sqlite3_result_value()介面使用才是安全的。
二、使用例項
在上一篇部落格中的查詢遍歷的方法中進行擴充,擴充後的方法如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
//查詢資料庫 - (void) queryUserInfoWith: (sqlite3 *) database WithStatement: (sqlite3_stmt *) statement { //獲取查詢結果所有的行數 int columnCount = sqlite3_column_count(statement); NSLog(@"columnCount = %d", columnCount); while (sqlite3_step(statement) == SQLITE_ROW) { int rowNum = sqlite3_column_int(statement, 0); char *rowDataOne = (char *) sqlite3_column_text(statement, 1); char *rowDataTow = (char *) sqlite3_column_text(statement, 2); NSString *nameString = [NSString stringWithUTF8String:rowDataOne]; NSString *firstLetterString = [NSString stringWithUTF8String:rowDataTow]; NSLog(@"BrandId = %d, Name = %<a href="http://www.jobbole.com/members/uz441800" data-mce-href="http://www.jobbole.com/members/uz441800">@,</a> FirstLetter = %@",rowNum , nameString, firstLetterString); int columnType = sqlite3_column_type(statement, 1); NSLog(@""%@" 型別程式碼為 = %d", nameString, columnType); //columnType = 3(SQLITE_TEXT) int currentValueBytes = sqlite3_column_bytes(statement, 1); NSLog(@""%@" 位元組數為 = %d nn", nameString, currentValueBytes); } sqlite3_finalize(statement); } |
呼叫上面的方法,具體的輸入結果如下:
今天的內容就先到這兒,下篇部落格回來一個完整的例項,把SQL的增刪改查的方法進行封裝,對資料庫進行操作。下篇部落格用到的資料庫就不能放到Bundle中了,需要把其拷貝到沙盒中,然後再對其進行增刪改查。具體內容詳見下篇部落格(稍後更新)。
本篇部落格中使用的資料庫資源GitHub分享地址:https://github.com/lizelu/SQLiteResource
打賞支援我寫出更多好文章,謝謝!
打賞作者
打賞支援我寫出更多好文章,謝謝!