Załóżmy, że masz bardzo prosty stół zwany User
który wygląda mniej więcej tak:
╔════╦══════════╗
║ ID ║ Name ║
╟────╫──────────╢
║ 1 ║ Slvrfn ║
║ 2 ║ Sean ║
║ 3 ║ Drew ║
║ 4 ║ mah ║
╚════╩══════════╝
I ty nazywasz sqlite3_exec
tak (argumenty są opisane szczegółowo in the documentation):
/* Error handling omitted for brevity */
sqlite3_exec(db, "SELECT * FROM User", my_special_callback, NULL, NULL);
SQLite wykona przeszedł SQL i dla każdego wyniku wiersz, który znajdzie, zadzwoni pod numer my_special_callback
. Tak więc z naszym przykładem tabeli User
, my_special_callback
zostanie wywołany 4 razy. Więc stwórzmy 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;
}
Biorąc pod uwagę nasz przykład tabela danych, wyjście będzie wyglądać następująco:
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
Teraz, jak czyni to użyteczne, to znaczy gdzie 4. argument sqlite3_exec
przychodzi Od dokumentacji.
4th argument sqlite3_exec() jest przekazywana przez do 1 argumentu wywołania zwrotnego każdego.
Załóżmy, że chcemy uruchomić nasz SQL i zbudować połączoną listę nazw wszystkich naszych użytkowników.Pierwszą rzeczą, jaką musimy zrobić, to zmienić sposób wzywamy 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 ... */);
i modyfikować my_special_callback
go używać
/*
* 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;
}
Teraz, jeśli było użyć callback
uwzględnionych w pytaniu nazwałbyś go tak:
/*
* 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);
wyjście będzie:
User:
ID = 1
Name = Slvrfn
User:
ID = 2
Name = Sean
... etc ...
(Z wyjątkiem User:
części będzie wydrukowany na stderr zamiast stdout)
Mam nadzieję, że to pomoże jasne rzeczy dla Ciebie. Daj mi znać, jeśli nadal jest coś, czego nie rozumiesz.
Czy możesz wyjaśnić swoje pytanie? To jest strona Q/A. –
Aby uzyskać ogólne informacje dotyczące tematu, powinieneś zapytać się na jednej z list mailingowych (patrz http://www.sqlite.org/support.html). Stosowanie przepełnienia stosu wymaga znacznie bardziej szczegółowego pytania (zazwyczaj z użyciem kodu, który napisałeś i nie możesz wykonać pracy). – mah
Myślę, że gdybyś miał wyjaśnić, co masz na myśli przez "przydatne wywołania zwrotne", może to pomóc komuś odpowiedzieć. Co chcesz zrobić z twoim oddzwonieniem? Co próbujesz osiągnąć? –