问题描述
我无法理解回调函数在 SQLite3 数据库中的使用.
据我所知,它用于遍历具有多条记录的 SELECT 语句.但我不明白它是如何做到的,也不明白如何制作我自己的有用回调.我已经多次通读 本教程 以试图理解,但这只是不做给我.
当我使用他们的示例并在 Visual Studio 中调试以查看如何填充和遍历参数数组时,我迷路了.另外 VS 只显示阵列中的当前槽位,而不是整个阵列本身.
如果您需要任何说明,请告诉我,因为我是来学习的!
我要求有人解释如何使用回调.也许是其他人如何使用它的一些例子.只是对这个人在做什么的一个解释:
static int callback(void *data, int argc, char **argv, char **azColName){国际我;fprintf(stderr, "%s: ", (const char*)data);for(i=0; i
假设您有一个非常简单的表,名为 User
,它看起来像这样:
你像这样调用sqlite3_exec
(参数详细描述在文档中):
/* 为简洁起见省略了错误处理 */sqlite3_exec(db, "SELECT * FROM User", my_special_callback, NULL, NULL);
SQLite 将执行传递的 SQL 语句,并且对于它找到的每个结果行,它将调用 my_special_callback
.因此,对于我们的示例 User
表,my_special_callback
将被调用 4 次.所以让我们创建my_special_callback
:
/** 参数:** 未使用 - 在这种情况下被忽略,请参阅 sqlite3_exec 的文档* count - 结果集中的列数* data - 该行的数据* 列 - 列名*/static int my_special_callback(void *unused, int count, char **data, char **columns){国际idx;printf("有 %d 列
", count);for (idx = 0; idx <计数; idx++) {printf("%s"列的数据为:%s
", columns[idx], data[idx]);}printf("
");返回0;}
给定我们的示例表和数据,输出将如下所示:
有 2 列ID"列中的数据为:1名称"列数据为:Slvrfn有 2 列ID"列中的数据为:2姓名"列中的数据为:肖恩有 2 列ID"列中的数据为:3姓名"列数据为:Drew有 2 列ID"列数据为:4名称"列中的数据为:mah现在是如何使它有用,这就是 sqlite3_exec
的第四个参数的用武之地.来自文档:
sqlite3_exec() 的第四个参数被传递到第一个每个回调调用的参数.
假设我们要运行 SQL 并构建一个包含所有用户姓名的链表.我们需要做的第一件事是改变我们调用 sqlite3_exec
的方式:
/* 创建我虚构的链表 */struct my_linked_list *head = my_linked_list_alloc();/** 将指向我的列表的指针作为第四个参数传递给 sqlite3_exec.错误* 为简洁起见省略了处理*/sqlite3_exec(db, "SELECT * FROM User", my_special_callback, head, NULL);/* 我的列表现在已经建立,我可以用它做一些事情... */my_linked_list_traverse(head,/* ... Stuff ... */);
并修改my_special_callback
使用
/** 参数:** list - 指向名称链表的指针* count - 结果集中的列数* data - 该行的数据* 列 - 列名*/static int my_special_callback(void *list, int count, char **data, char **columns){struct my_linked_list *head = list;/** 我们知道 Name 列中的值在第二个槽中* 数据数组.*/my_linked_list_append(head, data[1]);返回0;}
现在,如果您要使用问题中包含的 callback
,您可以这样称呼它:
/** 将表名作为第四个参数传递给 sqlite3_exec.错误* 为简洁起见省略了处理*/sqlite3_exec(db, "SELECT * FROM User", callback, "User", NULL);
输出将是:
用户:ID = 1名称 = Slvrfn用户:ID = 2姓名 = 肖恩... 等等 ...(除了 User:
部分将被打印到 stderr 而不是 stdout)
希望这有助于为您解决问题.如果您还有什么不明白的地方,请告诉我.
I am having trouble understanding the use of the callback function in a SQLite3 database.
I understand it is used to traverse SELECT statements with multiple records. But I do not understand how it does that or how to make my own useful callback. I have read through this tutorial several times to try to understand, but that is just not doing it for me.
When I use their example and debug in Visual Studio to see how the argument arrays are populated and traversed i get lost. Also VS only shows the current slot in the array, not the entire array itself.
If you need any clarification please let me know as I am here to learn!
I am asking for someone to explain how the callback is used. Maybe some examples of how others have used it. Just an explanation of what this one is doing even:
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
", azColName[i], argv[i] ? argv[i] : "NULL");
}
printf("
");
return 0;
}
Let's assume you have a very simple table called User
that looks something like this:
╔════╦══════════╗ ║ ID ║ Name ║ ╟────╫──────────╢ ║ 1 ║ Slvrfn ║ ║ 2 ║ Sean ║ ║ 3 ║ Drew ║ ║ 4 ║ mah ║ ╚════╩══════════╝
And you call sqlite3_exec
like this (the arguments are described in detail in the documentation):
/* Error handling omitted for brevity */
sqlite3_exec(db, "SELECT * FROM User", my_special_callback, NULL, NULL);
SQLite will execute the passed SQL statement and for every result row that it finds it will call my_special_callback
. So with our example User
table, my_special_callback
will be called 4 times. So let's create 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)
", count);
for (idx = 0; idx < count; idx++) {
printf("The data in column "%s" is: %s
", columns[idx], data[idx]);
}
printf("
");
return 0;
}
Given our example table and data, the output will look like this:
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
Now to how to make this useful, that is where the 4th argument to sqlite3_exec
comes in. From the documentation:
So let's say that we want to run our SQL and build a linked list of the names of all of our users. The first thing we need to do is change how we are calling 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 ... */);
And modify my_special_callback
to use it
/*
* 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;
}
Now, if you were to use the callback
you included in your question, you would call it like this:
/*
* 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);
The output would be:
User: ID = 1 Name = Slvrfn User: ID = 2 Name = Sean ... etc ...
(Except the User:
part would be printed to stderr instead of stdout)
Hopefully this helps clear things up for you. Let me know if there is still something that you don't understand.
这篇关于sqlite3_exec() 回调函数说明的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!