2010-11-18 13 views
5

Necesito leer y escribir datos BLOB en una base de datos. Aquí está mi tabla de estructurasqlite3 insertar y leer datos BLOB en la base de datos

#define CREATE_TABLE_USERS_SQL "CREATE TABLE IF NOT EXISTS %@ (\ 
UserID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, \ 
Name VARCHAR(50), \ 
Image BLOB);" 

¿Cómo puedo insertarlo en la base de datos y luego recuperarlo?

Entorno: iPhone SDK 4.1 Base de datos SQLite3.

Este código falla:

 NSData * buf2 = [[NSData alloc] init]; 
     sqlite3_column_blob(statement, 5); 
     buf2 = sqlite3_column_bytes(statement, 5); 
     user.image = [UIImage imageWithData: buf2]; 
+0

Esta pregunta es la misma que la tuya, y las respuestas allí deben abordar tus necesidades: http://stackoverflow.com/questions/643682/reading-and-writing-images-to-an-sqlite-db- para-iphone-use –

Respuesta

1

Aparte de la elección de su cliente o interfaz de programación, el uso no difiere de cualquier otro campo de cadena.


[Actualización] no he tenido la suerte de desarrollar para el iPhone todavía, pero creo que es lo mismo que cualquier otra consulta SELECT o INSERT. Asegúrese de codificar el BLOB y encerrarlo con apóstrofos simples (') como cadenas.

+0

He añadido una pregunta – yozhik

10

Gracias a todos !! Con el suyo ayudan Me'v resuelto el problema y quieren compartir los resultados para futuras principiantes como yo.)

-(void) addToDB 
{ 
    NSLog(@"\nCreating db"); 
    NSString *str = @"CREATE TABLE IF NOT EXISTS Images (image1 BLOB);"; 
    int res = SQLITE_ERROR; 


    res = sqlite3_open([@"aa.sql" UTF8String], &database); 
    res = sqlite3_exec(database, [str UTF8String], NULL, NULL, NULL); 

    sqlite3_stmt *updStmt =nil; 

    const char *sql = "INSERT INTO Images (image1) VALUES (?);"; 
    res = sqlite3_prepare_v2(database, sql, -1, &updStmt, NULL); 

    if(res!= SQLITE_OK) 
    { 
     NSLog(@"Error while creating update statement:%s", sqlite3_errmsg(database)); 
    } 

    UIImage *img = [UIImage imageNamed: @"flower.png"]; 
    NSData *imageData = [NSData dataWithData: UIImagePNGRepresentation(img)]; 

    res = sqlite3_bind_blob(updStmt, 1, [imageData bytes], [imageData length] , SQLITE_TRANSIENT); 

    if((res = sqlite3_step(updStmt)) != SQLITE_DONE) 
    { 
     NSLog(@"Error while updating: %@", sqlite3_errmsg(database)); 
     sqlite3_reset(updStmt); 
    } 

    res = sqlite3_reset(updStmt); 
    res = sqlite3_close(database); 
} 

-(void) readFromDB 
{ 
    NSLog(@"\nReading from db"); 

    NSString *query = @"SELECT image1 from Images"; 
    int res = SQLITE_ERROR; 
    int len = 0; 

    res = sqlite3_open([@"aa.sql" UTF8String], &database); 

    sqlite3_stmt *statement; 
    res = sqlite3_prepare_v2 (database, [query UTF8String], -1, &statement, nil); 

    if (res == SQLITE_OK) 
    { 
     if (sqlite3_step(statement) == SQLITE_ROW) 
     { 
      len = sqlite3_column_bytes(statement, 0); 
      NSData *imgData = [[NSData alloc] initWithBytes: sqlite3_column_blob(statement, 0) length: len];   


      UIImage *img = [[UIImage alloc] initWithData:imgData]; 

      self.view1.image = img; 

     } 
    } 
    sqlite3_finalize(statement); 

    res = sqlite3_close(database); 
} 
+0

Gracias por publicar, este código funciona bien. Pero cuando cambio el nombre de la imagen de "flower.png" a otro como "xyz.png", muestra la imagen anterior en la vista de la imagen, puede indicar el motivo ....... –

+0

maby, primero debe ir al registro apropiado en la base de datos, y solo luego leer la imagen, y ahora siempre se necesita el primer registro. intenta eso, realmente no recuerdo que fue hace un año. – yozhik

+0

en NSLog (@ "Error al crear la declaración de actualización:% @", sqlite3_errmsg (base de datos)); Se debe usar el formato% s –

0

// ----- insertar una imagen

- (void)setImage:(UIImage *)theImage 
{ 

    if(sqlite3_open([databasePath UTF8String],&myDatabase)==SQLITE_OK) 
    {  
    NSString *insertProgrammeSql = @"INSERT INTO imageTable (imageName) VALUES (?)"; 

sqlite3_stmt *statement; 

    if (sqlite3_prepare_v2(myDatabase, [insertProgrammeSql cStringUsingEncoding:NSUTF8StringEncoding], -1, &statement, NULL) == SQLITE_OK) { 

    NSData *imageData = UIImagePNGRepresentation(theImage); 

     sqlite3_bind_blob(statement, 1, [imageData bytes], [imageData length], SQLITE_TRANSIENT); 

    sqlite3_step(statement); 
} 
    sqlite3_close(myDatabase); 
// return YES;  
} 


    } 

// ---- ---- Obtén

-(UIImage *)getImage 

    { 

    UIImage *image = nil; 


if(sqlite3_open([databasePath UTF8String],&myDatabase)==SQLITE_OK) 
{ 

NSString *selectSql = @"SELECT image FROM imageTable"; 

sqlite3_stmt *statement; 
if (sqlite3_prepare_v2(myDatabase, [selectSql UTF8String], -1, &statement, NULL) == SQLITE_OK) 
{ 
    int length = sqlite3_column_bytes(statement, 0); 
    NSData *imageData = [NSData dataWithBytes:sqlite3_column_blob(statement, 0) length:length]; 

    image = [UIImage imageWithData:imageData]; 



    sqlite3_finalize(statement); 

    } 
    sqlite3_close(myDatabase); 
    } 
return image; 
} 
0

Este código falla:

NSData * buf2 = [[NSData alloc] init]; 
    sqlite3_column_blob(statement, 5); 
    buf2 = sqlite3_column_bytes(statement, 5); 
    user.image = [UIImage imageWithData: buf2]; 

Está llamando a las funciones de SQLite en el orden correcto. De acuerdo con la documentación de SQLite:

el más seguro y más fácil de recordar la política es invocar estas rutinas en una de las siguientes maneras:

  • sqlite3_column_text() seguido de sqlite3_column_bytes()
  • sqlite3_column_blob() seguido de sqlite3_column_bytes()
  • sqlite3_column_text16() seguido de sqlite3_column_bytes16()

En otras palabras, debe llamar sqlite3_column_text(), sqlite3_column_blob(), o sqlite3_column_text16() primero para forzar el resultado en el formato deseado y luego invoque sqlite3_column_bytes() o sqlite3_column_bytes16() para encontrar el tamaño del resultado .No mezcle llamadas a sqlite3_column_text() o sqlite3_column_blob() con llamadas a sqlite3_column_bytes16(), y no mezcle llamadas a sqlite3_column_text16() con llamadas a sqlite3_column_bytes().

Sin embargo, buff2 es un número entero, no un puntero de datos. sqlite3_column_bytes le dice cuántos bytes hay en el blob.

Cuestiones relacionadas