2012-04-17 49 views
2

代码BLOB图像保存图像:要检索的SQLite

NSData *imageData=UIImagePNGRepresentation(animalImage); 
     NSString *insertSQL=[NSString stringWithFormat:@"insert into AnimalsTable (name,propertyID,animalID,breed,mainBreed,dateofbirth,sex,notes,imageData) values(\"%@\",\"%@\",\"%@\",\"%@\",\"%@\",\"%@\",\"%@\",\"%@\",\"%@\")",nameString,propertyString,animalidString,breedString,mainBreedString,dateString,sexString,notesString,imageData]; 
    sqlite3_stmt *addStatement; 
     NSLog(@"%@",appDelegate.sqlFile); 
    const char *insert_stmt=[insertSQL UTF8String]; 
    if (sqlite3_open([appDelegate.sqlFile UTF8String],&database)==SQLITE_OK) { 
     sqlite3_prepare_v2(database,insert_stmt,-1,&addStatement,NULL); 

     if (sqlite3_step(addStatement)==SQLITE_DONE) { 

      sqlite3_bind_blob(addStatement, 1, [imageData bytes], [imageData length], SQLITE_TRANSIENT); 
      NSLog(@"Data saved"); 

     } 
     else{ 
      //NSAssert1(0, @"Error while updating. '%s'", sqlite3_errmsg(database)); 

      NSLog(@"Some Error occured"); 
    } 

    sqlite3_close(database); 

对于检索图像:

NSString *select_sql=[NSString stringWithFormat:@"select name,animalID,imageData from AnimalsTable where mainBreed='%@' AND breed='%@'",mainString,subString]; 
     const char *sql = [select_sql UTF8String]; 
     sqlite3_stmt *selectstmt; 
     if(sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL) == SQLITE_OK) { 

      while(sqlite3_step(selectstmt) == SQLITE_ROW) { 

      NSString *animalName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 0)]; 
      NSString *animalid=[NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 1)]; 
      NSData *dataForCachedImage = [[NSData alloc] initWithBytes:sqlite3_column_blob(selectstmt, 2) length: sqlite3_column_bytes(selectstmt, 2)];   
      [animalNamesArray addObject:animalName]; 
      [animalIDArray addObject:animalid]; 
      [imageDataArray addObject:dataForCachedImage]; 

     } 
    } 
} 
else 
    sqlite3_close(database); 

在UITableView的CellForIndexPath:

NSData *dataForCachedImage=[imageDataArray objectAtIndex:indexPath.row]; 
    UIImage *dataImage=[[UIImage alloc] init]; 
    dataImage=[UIImage imageWithData:dataForCachedImage]; 
    cell.imageView.image=dataImage; 

当我调试的代码:

我得到字节对于NSData = 226381字节和对于dataImage 0x0。

请帮帮我。

+1

要开始,你需要正确[使用'?'](http://www.sqlite.org/c3ref/bind_blob.html)绑定你的值。尝试使用'%@'替换值与其他任何关系数据库一样[危险](http://en.wikipedia.org/wiki/SQL_injection)。 – Joe 2012-04-17 14:41:27

+0

除了使用%@而不使用?之外,还可以告诉我上面的代码有什么问题吗? – anjum 2012-04-17 15:39:46

回答

4

您需要将您的值正确绑定到查询才能正常工作。当您在第一行设置查询时,将插入数据的描述,而不是正确的数据。如果您要记录查询,您可能会看到类似<0FFAEC32 ... 23F0E8D1>的内容。 然后您试图稍后正确地绑定blob,但由于您的查询写入不正确,所以它没有任何效果。

//Although you try to bind a blob here it does not get bound 
//to anything since you do not include a parameter template. 
sqlite3_bind_blob(addStatement, 1, [imageData bytes], [imageData length], SQLITE_TRANSIENT); 

要在这里解决,这是一个小例子:

//query does not need to be an NSString* but just a const char * 
//replace all %@ with ? 
const char *sql = "INSERT INTO AnimalsTable(name, ..., imageData) values(?, ..., ?)"; 
if (sqlite3_open([appDelegate.sqlFile UTF8String],&database)==SQLITE_OK) { 
     sqlite3_prepare_v2(database,insert_stmt,-1,&addStatement,NULL); 

     //Bind all of the values here before you execute the statement 
     sqlite3_bind_text(addStatement, 1, [nameString UTF8String], -1, NULL); 
     ... 
     sqlite3_bind_blob(addStatement, 9, [imageData bytes], [imageData length], SQLITE_TRANSIENT); 

     if (sqlite3_step(addStatement)==SQLITE_DONE) { 
      NSLog(@"Data saved"); 
     } 
     ... 

     //You must finalize your statement before closing the database 
     sqlite3_finalize(addStatement); 
     sqlite3_close(database); 

使用绑定值有助于防止插入这可能是一个SQL注入攻击,并提高对于经常运行的查询的查询性能数据无效。

注意*:如果你要做大量的SQL考虑使用FMDB甚至核心数据。

+0

我也类似地提出了你所提到的,但是当我在sql manager中检查它时,数据是用空值保存的。 – anjum 2012-04-18 08:26:44

+0

我已经改变了sqlite3_bind_text(addStatement,1,[nameString UTF8String],-1,NULL);到SQLITE_TRANSIENT。现在数据正常保存。但是原始问题仍然存在。 – anjum 2012-04-18 08:33:19

+0

我用过吗?标记在我的整个查询中,也改变了位置。 – anjum 2012-04-18 12:23:44