2012-04-17 3 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 bytes И для dataImage 0x0.

Пожалуйста, помогите мне.

+1

Для начала вам необходимо [привязать свои значения с помощью '?'] (Http://www.sqlite.org/c3ref/bind_blob.html). Попытка заменить значения с помощью '% @' также как [опасно] (http://en.wikipedia.org/wiki/SQL_injection) как любая другая база данных отношений. – Joe

+0

Не могли бы вы рассказать мне, что случилось с моим кодом выше, вместо% @ вместо?. – anjum

ответ

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 или даже Core Data.

+0

Я также сделал то, что вы упомянули, но данные сохраняются с нулевыми значениями, когда я проверил его в sql-менеджере. – anjum

+0

Я изменил sqlite3_bind_text (addStatement, 1, [nameString UTF8String], -1, NULL); к SQLITE_TRANSIENT. Теперь данные сохраняются должным образом. Но проблема orignal все еще существует. – anjum

+0

Я использовал? в моем запросе, а также изменил положение. – anjum

Смежные вопросы