Página 1 de 2
Estructuras dinámicas a partir de consultas de BD
Publicado: 20 Jun 2011, 07:09
por pspCaracas
Tengo definidas varias estructuras que pueblo a partir de consultas de base de datos. Algo como:
Código: Seleccionar todo
int size;
main{
size = getNumRows("persona")
struct persona[size]
getPeople(persona)
}
int getNumRows(char *tabla){
int numOfRows;
char sql = "select * from ";
strcat(sql, tabla);
executeQuery(sql);
numOfRows = fetchNumOfRows();
return numOfRows;
}
void getPeople(struct persona[ ]){
int i;
char sql = "select * from peole";
executeQuery(sql);
numOfRows = fetchNumOfRows();
for(i=0;fetchRow != NULL,i++){
persona[i].nombre = fetchField(0);
persona[i].nombre = fetchField(1);
...
}
}
Como pueden ver en el main, requiero ejecutar dos consultas a la base de datos, una primera consulta para saber el tamaño de la estructura "dinámica", y luego una segunda vez para llenar los datos.
Ahora mi pregunta: ¿Hay alguna forma de hacer esto en una sola función? He pensado en hacer la declaración de la estructura en la segunda función a través de un puntero...y de esta forma me arroaría una consulta a la base de datos.
¿Alguna idea de cómo hacerlo? O algún sitio donde leer?
Re: Estructuras dinámicas a partir de consultas de BD
Publicado: 15 Ago 2011, 20:19
por m0skit0
Siento la tardanza... ¿Conseguiste resolver esto?
Re: Estructuras dinámicas a partir de consultas de BD
Publicado: 15 Ago 2011, 20:36
por pspCaracas
De momento no...he tenido que sobrevivir con las dobles consultas

Mi duda en esencia es si se pueden declarar estructuras dinámicas y cambiarles el tamaño a voluntad (en ejemplo dependiendo de la cantidad de registros que arroje la base de datos consultada).
No te preocupes por la tardanza...como todo, se responde cuando se puede!! (regla n° 1 de listas de correos y foros)
Re: Estructuras dinámicas a partir de consultas de BD
Publicado: 16 Ago 2011, 09:10
por m0skit0
Primero, una bronca: ¡usa las etiquetas [code] para el código!
Segundo, otra brona: ¡no uses variables globales!
A ver si he entendido bien tu problema: lo que quieres es que el array persona sea dinámico, es decir, que pueda variar dependiendo de cuántas entradas tenga la tabla. Además quieres hacerlo en una sola consulta.
Re: Estructuras dinámicas a partir de consultas de BD
Publicado: 16 Ago 2011, 14:35
por pspCaracas
m0skit0 escribió:Primero, una bronca: ¡usa las etiquetas [code] para el código!
Listo!
m0skit0 escribió:Segundo, otra brona: ¡no uses variables globales!
Entendido!!
m0skit0 escribió:A ver si he entendido bien tu problema: lo que quieres es que el array persona sea dinámico, es decir, que pueda variar dependiendo de cuántas entradas tenga la tabla. Además quieres hacerlo en una sola consulta.
Exacto!!
Re: Estructuras dinámicas a partir de consultas de BD
Publicado: 16 Ago 2011, 14:50
por m0skit0
Aclarar que yo no he hecho consultas a BBDD en C...
Supongo que
executeQuery() te tiene que devolver un result set o algo parecido. En vez de devolver el número de filas, devuelve el result set entero, así podrás consultar tanto los datos como el número de filas cuando desees.
En cuanto a la estructura dinámica, es bastante fácil (asumiendo que el struct se llama
persona - te aconsejo que uses
typedef struct en vez de
struct a secas):
Código: Seleccionar todo
persona* personas;
unsigned long long size = getSize();
personas = (persona*) malloc(size * sizeof(persona));
personas[0]; etc...
free(personas);
Re: Estructuras dinámicas a partir de consultas de BD
Publicado: 16 Ago 2011, 17:42
por pspCaracas
Voy a proba a ver cómo me va...
¿Y cuál es la diferencia con typdef?
Re: Estructuras dinámicas a partir de consultas de BD
Publicado: 16 Ago 2011, 18:54
por m0skit0
pspCaracas escribió:¿Y cuál es la diferencia con typdef?
No necesitas andar poniendo
struct delante todo el rato
Ah y con
m0skit0 escribió:devuelve el result set entero
me refiero a un puntero

Re: Estructuras dinámicas a partir de consultas de BD
Publicado: 16 Ago 2011, 22:17
por pspCaracas
m0skit0 escribió:pspCaracas escribió:¿Y cuál es la diferencia con typdef?
No necesitas andar poniendo
struct delante todo el rato
Esto mola muchísimo!!!
m0skit0 escribió:Ah y con
m0skit0 escribió:devuelve el result set entero
me refiero a un puntero

Eso si lo había entendido/asumido!!
Re: Estructuras dinámicas a partir de consultas de BD
Publicado: 19 Ago 2011, 21:55
por pspCaracas
Ya lo logré, pero faltaron apuntadores ¬¬
Busqué un poco más para completar tu ejemplo m0skit0, y encontré este de
cómo reservar arreglos multidimensionales (en inglés para el que lo quiera revisar).
En mi caso tengo esto:
En el SQL.h
Código: Seleccionar todo
struct definition {
int id;
char valueType[10];
float value;
int time;
};
int getDefinition(MYSQL *, struct histDefinition **);
En el SQL.c
Código: Seleccionar todo
int getDefinition(MYSQL *conn, struct definition **def){
MYSQL_STMT *stmt;
char *sql;
// Bind variables
MYSQL_BIND result[4];
int myId, myTime;
float myValue;
char myValueType[10];
unsigned long myValueTypeLength;
my_bool is_null[3];
my_ulonglong numRows;
int i;
sql = "select * DefinitionTable";
// Statement handler
statementHandler(&conn, &stmt, &sql);
// Initialize the result column structures
memset(result, 0, sizeof(result)); /* zero the structures */
// Init param structure
// Result
result[0].buffer_type = MYSQL_TYPE_LONG;
result[0].buffer = (void *) &myId;
result[0].is_unsigned = 0;
result[0].is_null = &is_null[0];
result[0].length = 0;
result[1].buffer_type = MYSQL_TYPE_FLOAT;
result[1].buffer = (void *) &myValue;
result[1].is_unsigned = 0;
result[1].is_null = &is_null[1];
result[1].length = 0;
result[2].buffer_type = MYSQL_TYPE_LONG;
result[2].buffer = (void *) &myTime;
result[2].is_unsigned = 0;
result[2].is_null = &is_null[2];
result[2].length = 0;
result[3].buffer_type = MYSQL_TYPE_STRING;
result[3].buffer = (void *) myValueType;
result[3].buffer_length = sizeof (myValueType);
result[3].is_null = &is_null[4];
result[3].length = &myValueTypeLength;
// Bind result
if (mysql_stmt_bind_result(stmt, result) != 0) {
print_stmt_error(stmt, "Could not bind results");
return -1;
}
// Execute!!
if (mysql_stmt_execute(stmt) != 0) {
print_stmt_error(stmt, "Could not execute statement");
return -1;
}
if (mysql_stmt_store_result(stmt) != 0) {
print_stmt_error(stmt, "Could not buffer result set");
return -1;
}
// Get the number of rows
numRows = mysql_stmt_num_rows (stmt);
// Dynamic structure
*def = (struct definition*) malloc (numRows * sizeof(struct definition));
// Fetch
for(i=0; mysql_stmt_fetch (stmt) == 0; i++){
// Init data
(*def)[i].id = 0;
(*def)[i].value = 0;
(*def)[i].time = 0;
strcpy((*def)[i].valueType,"");
(*def)[i].id = myId;
(*def)[i].deadband = myValue;
(*def)[i].deadtime = myTime;
strncpy((*def)[i].valueType, myValueType, strlen(myValueType));
(*def)[i].valueType[strlen(myValueType)] = '\0';
}
// Deallocate result set
mysql_stmt_free_result(stmt);
// Close the statement
mysql_stmt_close(stmt);
return ((int) numRows);
}
En el programa.c
Código: Seleccionar todo
int main(){
int numHistDef;
// Open database
openDB(&conn);
struct definition *def = NULL;
numDef = getDefinition(conn, &def);
syslog(LOG_INFO,"> num of Definitions: %d", numHistDef);
for (i = 0; i < numDef; i++) {
syslog(LOG_INFO, "> def[%d].id: %d", i, def[i].id);
syslog(LOG_INFO, "> def[%d].value: %f", i, def[i].value);
syslog(LOG_INFO, "> def[%d].time: %d", i, def[i].time);
syslog(LOG_INFO, "> def[%d].valueType: %s",i, def[i].valueType);
}
exit(0);
}
Salida:
Código: Seleccionar todo
Aug 19 15:14:53 buckbeak programa: > num of Definitions: 3
Aug 19 15:14:53 buckbeak programa: > def[0].id: 1
Aug 19 15:14:53 buckbeak programa: > def[0].value: 0.100000
Aug 19 15:14:53 buckbeak programa: > def[0].time: 30
Aug 19 15:14:53 buckbeak programa: > def[0].valueType: fsw
Aug 19 15:14:53 buckbeak programa: > def[1].id: 3
Aug 19 15:14:53 buckbeak programa: > def[1].value: 10.000000
Aug 19 15:14:53 buckbeak programa: > def[1].time: 30
Aug 19 15:14:53 buckbeak programa: > def[1].valueType: fsw
Aug 19 15:14:53 buckbeak programa: > def[2].id: 5
Aug 19 15:14:53 buckbeak programa: > def[2].value: 5.000000
Aug 19 15:14:53 buckbeak programa: > def[2].time: 20
Aug 19 15:14:53 buckbeak programa: > def[2].valueType: fsw
Lo bonito del conector de MySQL es que en el mismo result set viene el número de registros, haciendo solo una consulta. Justo lo que quería

PD: Te debo los typdef porque aun no soy diestro con eso
