首页 > 解决方案 > 使用 sqlite3 将某些数据分配给结构

问题描述

我在C中有这个结构:

typedef struct{
  char *NOMBRE;
  char *APELLIDO;
  int DNI;
  char *FECHA_NACIMIENTO;
  int TELEFONO;
  char *EMAIL;
  char *DOMICILIO;
  long N_SS ;
  long N_CUENTA ;
  char *PASSWORD;
} Usuario;

现在我已经有了结构,我想通过 SQL 语句将表中的某些数据分配给结构。

这是我的方法:

void bd_sacarDatosUsuario(char *user) {
  sqlite3 *db;
  char *zErrMsg = 0;
  const char* data = "Callback function called";

  char sql[70];
  char sql2[10];
  char user2[10];
  strcpy(sql, "SELECT * FROM DATOS_PERSONALES WHERE DNI='");

  int rc = sqlite3_open("BD/gimud.db", &db);
  if (rc) {
    fprintf(stdout, "Can't open database: %s\n", sqlite3_errmsg(db));
  } else {
    fprintf(stdout, "Opened database successfully\n");
  }
  strcpy(sql2, "';");
  strcpy(user2, user);
  strcat(sql, user2);
  strcat(sql, sql2);

  printf("%s\n", sql);

  rc = sqlite3_exec(db, sql, callback, (void*) data, &zErrMsg);

  if (rc != SQLITE_OK) {
    fprintf(stderr, "SQL error: %s\n", zErrMsg);
    sqlite3_free(zErrMsg);

  } else {
    fprintf(stdout, "Consulta creada con exito\n");
  }
  sqlite3_close(db);
}

我如何在回调函数中将数据分配给 Usuario u?我是说:

Usuario u;
u.NOMBRE = argv[0]; // and so on...

标签: csqliteselectstruct

解决方案


首先,我想提一下,下面的代码可能不是您要寻找的最终代码,但它可以帮助您了解回调函数的工作原理。

如果第 3 个参数的回调函数sqlite3_exec()不为 NULL,则为从评估的 SQL 语句出来的每个结果行调用它。您可以将附加参数传递给callback函数,这是您有机会将数据从表保存到所谓的Usuario结构的地方。的第四个参数callback用于此目的。

出于演示目的,以下代码执行以下操作:

  • 打开数据库
  • 创建一个包含三列的表,包括 ID、NAME 和 PASSWORD 字段
  • 在表中插入一行(ID=1, NAME=PETER, PASSWORD=ORANGE)
  • 为结构分配空间
  • 执行 select 语句并调用存储数据的 CALLBACK()函数。
#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h>
#include <string.h>

typedef struct Usuario{
    char *name;
    char *password;
} Usuario;

int callback(void *Usuario, int argc, char **argv, char **azColName) {
    struct Usuario *tmp = (struct Usuario *)Usuario;
    char missing[] = "MISSING";
    tmp->name = (char *)malloc(sizeof(char) * strlen(argv[1]));
    tmp->name = argv[1] ? argv[1] : (char*)"NULL";
    tmp->password = (char *)malloc(sizeof(char) * strlen(argv[2]));
    tmp->password = argv[2] ? argv[2] : (char*)"NULL";
    return 0;
}


void bd_sacarDatosUsuario() {
    sqlite3 *db;
    char *zErrMsg = 0;
    int rc;

    // Open database
    rc = sqlite3_open("test.db", &db);
    if( rc ) {
        fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
        return ;
    } else {
        fprintf(stderr, "Opened database successfully\n");
    }

    /* Create table statement */
    const char *sql = "CREATE TABLE TEST("  \
    "ID INT PRIMARY KEY NOT NULL," \
    "NAME CHAR(50) NOT NULL," \
    "PASSWORD CHAR(50) NOT NULL);";
    rc = sqlite3_exec(db, sql, NULL, 0, &zErrMsg);

    if( rc != SQLITE_OK ){
        fprintf(stderr, "SQL error: %s\n", zErrMsg);
        sqlite3_free(zErrMsg);
    } else {
        fprintf(stdout, "Success\n");
    }

    // Insert test data
    sql = "INSERT INTO TEST(ID, NAME, PASSWORD) VALUES(1, \"PETER\", \"ORANGE\");";
    rc = sqlite3_exec(db, sql, NULL, 0, &zErrMsg);
    if( rc != SQLITE_OK ){
        fprintf(stderr, "SQL error: %s\n", zErrMsg);
        sqlite3_free(zErrMsg);
    } else {
        fprintf(stdout, "Success\n");
    }


    // Allocate space for the structure
    struct Usuario *u = (struct Usuario *)malloc(sizeof(struct Usuario));

    sql = "SELECT * FROM TEST";
    rc = sqlite3_exec(db, sql, callback, u, &zErrMsg);
    if( rc != SQLITE_OK ){
        fprintf(stderr, "SQL error: %s\n", zErrMsg);
        sqlite3_free(zErrMsg);
    } else {
        fprintf(stdout, "Success\n");
    }

    sqlite3_close(db);

    printf("Hi my name is: %s with password of %s\n", u->name, u->password);
}

int main() {
    bd_sacarDatosUsuario();

}

根据您的需要更改结构。请注意,您应该检查 malloc 是否返回非 NULL 值,当然在不需要它之后将其释放。


推荐阅读