sqlite3 вставлять и читать BLOB-данные в базе данных - PullRequest
5 голосов
/ 18 ноября 2010

Мне нужно прочитать и записать данные BLOB в базу данных. Вот моя структура таблицы

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

Как я могу вставить его в базу данных, а затем извлечь из него?

Среда: iPhone SDK 4.1, база данных SQLite3.

Этот код не работает:

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

Ответы [ 5 ]

11 голосов
/ 19 ноября 2010

Спасибо всем !! С вашей помощью я решил проблему и хочу поделиться результатами для будущих новичков, как и я.

-(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);
}
1 голос
/ 18 ноября 2010

Помимо выбора клиента или интерфейса программирования, использование не отличается от других строковых полей.


[Обновление] Мне еще не повезло в разработке для iPhone, но я считаю, что он такой же, как и любой другой запрос SELECT или INSERT. Обязательно закодируйте большой двоичный объект и заключите его в одинарные апострофы ('), такие как строки.

0 голосов
/ 15 февраля 2014

Этот код не работает:

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

Вы вызываете функции SQLite в правильном порядке. Согласно документации SQLite:

Самая безопасная и запоминающаяся политика - вызывать эти подпрограммы. одним из следующих способов:

  • sqlite3_column_text (), за которым следует sqlite3_column_bytes ()
  • sqlite3_column_blob (), за которым следует sqlite3_column_bytes ()
  • sqlite3_column_text16 (), за которым следует sqlite3_column_bytes16 ()

Другими словами, вы должны вызвать sqlite3_column_text (), sqlite3_column_blob () или sqlite3_column_text16 () сначала для принудительного вызова результат в желаемый формат, затем вызовите sqlite3_column_bytes () или sqlite3_column_bytes16 (), чтобы найти размер результата. Не смешивать вызовы sqlite3_column_text () или sqlite3_column_blob () с вызовами sqlite3_column_bytes16 () и не смешивайте вызовы с sqlite3_column_text16 () с вызовами sqlite3_column_bytes ().

Однако buff2 является целым числом, а не указателем данных. sqlite3_column_bytes сообщает, сколько байтов находится в BLOB-объекте.

0 голосов
/ 28 сентября 2012

// ----- вставить ИЗОБРАЖЕНИЕ

  - (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;    
}   


  }

// -------- получить изображение

   -(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 голосов
/ 19 ноября 2010

почему бы не использовать fmdb Гасом Мюллером и др. из Flying Meat? http://flyingmeat.com/

https://github.com/ccgus/fmdb

Если вы найдете fmdb полезным, идите и купите одно из превосходных приложений Flying Meat. VoodooPad или Акрон.

...