从 sqlite 检索 BLOB 图像

2023-11-29

保存图片的代码:

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 的字节。

请帮我。


您需要将您的值正确绑定到查询才能正常工作。当您在第一行设置查询时,将插入数据的描述,而不是正确的数据。如果您要记录查询,您可能会看到类似的内容<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甚至核心数据。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从 sqlite 检索 BLOB 图像 的相关文章

随机推荐