簡體   English   中英

sqlite3_exec() 回調函數說明

[英]sqlite3_exec() Callback function clarification

我無法理解在 SQLite3 數據庫中使用回調函數。

我知道它用於遍歷具有多條記錄的 SELECT 語句。 但我不明白它是如何做到的,也不明白如何制作我自己有用的回調。 我已經多次通讀本教程以試圖理解,但這對我來說並不適合。

當我使用他們的示例並在 Visual Studio 中調試以查看如何填充和遍歷參數數組時,我迷路了。 此外,VS 僅顯示陣列中的當前插槽,而不是整個陣列本身。

如果您需要任何說明,請告訴我,因為我是來學習的!

我要求有人解釋如何使用回調。 也許是其他人如何使用它的一些例子。 只是對這個人在做什么的一個解釋:

static int callback(void *data, int argc, char **argv, char **azColName){
   int i;
   fprintf(stderr, "%s: ", (const char*)data);
   for(i=0; i<argc; i++){
      printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
   }
   printf("\n");
   return 0;
}

假設您有一個名為User的非常簡單的表,如下所示:

╔════╦══════════╗
║ ID ║ Name     ║
╟────╫──────────╢
║ 1  ║ Slvrfn   ║
║ 2  ║ Sean     ║
║ 3  ║ Drew     ║
║ 4  ║ mah      ║
╚════╩══════════╝

你像這樣調用sqlite3_exec (參數在文檔中有詳細描述):

/* Error handling omitted for brevity */
sqlite3_exec(db, "SELECT * FROM User", my_special_callback, NULL, NULL);

SQLite 將執行傳遞的 SQL 語句,並且對於它找到的每個結果行,它將調用my_special_callback 因此,對於我們的示例User表, my_special_callback將被調用 4 次。 所以讓我們創建my_special_callback

/*
 * Arguments:
 *
 *   unused - Ignored in this case, see the documentation for sqlite3_exec
 *    count - The number of columns in the result set
 *     data - The row's data
 *  columns - The column names
 */
static int my_special_callback(void *unused, int count, char **data, char **columns)
{
    int idx;

    printf("There are %d column(s)\n", count);

    for (idx = 0; idx < count; idx++) {
        printf("The data in column \"%s\" is: %s\n", columns[idx], data[idx]);
    }

    printf("\n");

    return 0;
}

給定我們的示例表和數據,輸出將如下所示:

There are 2 column(s)
The data in column "ID" is: 1
The data in column "Name" is: Slvrfn

There are 2 column(s)
The data in column "ID" is: 2
The data in column "Name" is: Sean

There are 2 column(s)
The data in column "ID" is: 3
The data in column "Name" is: Drew

There are 2 column(s)
The data in column "ID" is: 4
The data in column "Name" is: mah

現在如何使它有用,這就是sqlite3_exec的第四個參數的用武之地。從文檔中:

sqlite3_exec() 的第四個參數傳遞到每個回調調用的第一個參數。

因此,假設我們要運行 SQL 並構建所有用戶姓名的鏈表。 我們需要做的第一件事是改變我們調用sqlite3_exec

/* Create my fictional linked list */
struct my_linked_list *head = my_linked_list_alloc();

/*
 * Pass a pointer to my list as the 4th argument to sqlite3_exec. Error
 * handling omitted for brevity
 */
sqlite3_exec(db, "SELECT * FROM User", my_special_callback, head, NULL);

/* My list is now built, I can do stuff with it... */
my_linked_list_traverse(head, /* ... Stuff ... */);

並修改my_special_callback以使用它

/*
 * Arguments:
 *
 *     list - Pointer to a linked list of names
 *    count - The number of columns in the result set
 *     data - The row's data
 *  columns - The column names
 */
static int my_special_callback(void *list, int count, char **data, char **columns)
{
    struct my_linked_list *head = list;

    /*
     * We know that the value from the Name column is in the second slot
     * of the data array.
     */
    my_linked_list_append(head, data[1]);

    return 0;
}

現在,如果您要使用問題中包含的callback ,您可以這樣稱呼它:

/*
 * Pass the table name as the 4th argument to sqlite3_exec. Error
 * handling omitted for brevity
 */
sqlite3_exec(db, "SELECT * FROM User", callback, "User", NULL);

輸出將是:

User: 
ID = 1
Name = Slvrfn

User: 
ID = 2
Name = Sean

... etc ...

(除了User:部分將被打印到 stderr 而不是 stdout)

希望這有助於為您解決問題。 如果您還有不明白的地方,請告訴我。

該教程很糟糕,因為它只使用sqlite3_exec()

在一般情況下,使用sqlite3_exec()唯一有用方法是將其替換為sqlite3_prepare_v2() / sqlite3_step() / sqlite3_column_*() / sqlite3_finalize()調用,以便您可以在實際讀取數據的同一位置讀取數據需要處理它:

sqlite3_stmt *stmt;
const char *sql = "SELECT ID, Name FROM User";
int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
if (rc != SQLITE_OK) {
    print("error: ", sqlite3_errmsg(db));
    return;
}
while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
    int id           = sqlite3_column_int (stmt, 0);
    const char *name = sqlite3_column_text(stmt, 1);
    // ...
}
if (rc != SQLITE_DONE) {
    print("error: ", sqlite3_errmsg(db));
}
sqlite3_finalize(stmt);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM