试图将图像存储到sqlite中,当我尝试检索它时,它是一个字节而不是200万个字节

时间:2016-03-23 04:10:56

标签: ios sqlite uiimage blob nsdata

当我尝试将图像存储到sqlite中时,我已将该图像转换为NSData,并且imageData中有超过2,000,000个字节。

当我尝试从sqlite数据库中检索它时,它变成了一个字节。

这是我的代码:

将图像插入sqlite:

    -(void)INSERTCLAIMATTACHMENT:(NSString *)tablename
                    PARENTID:(long long)parentid
           ATTACHMENTCONTENT:(UIImage *)attachmentimage
              ATTACHMENTNAME:(NSString *)attachmentname
{
    sqlite3_stmt *statement;
    const char *dbPath = [_databasePath UTF8String];

    Global * g = [[Global alloc]init];
    NSData *imageData = [[NSData alloc]init];
    imageData = UIImagePNGRepresentation(attachmentimage);

    if(sqlite3_open(dbPath, &_DB) == SQLITE_OK)
    {
        NSString *insertSQL = [NSString stringWithFormat:@"INSERT INTO CLAIM_ATTACHMENT_ITEM ('PARENT_ID', 'CLAIM_ATTACHMENT_CONTENT', 'CLAIM_ATTACHMENT_NAME', 'CLAIM_ATTACHMENT_SIZE') VALUES ('%lld', '?', '%@', '%lu')", parentid,attachmentname, [imageData length]];
        const char *insert_statement = [insertSQL UTF8String];

        if(sqlite3_prepare_v2(_DB,insert_statement, -1, &statement, NULL) == SQLITE_OK)
           {
               sqlite3_bind_blob(statement, 2, [imageData bytes], [imageData length], SQLITE_TRANSIENT);
               if(sqlite3_step(statement) == SQLITE_DONE)
               {
                   [g showCustomAlertView:@"Successfull" message:@"Attachment has been added into database."];
               }
               else{
                   [g showCustomAlertView:@"Failure" message:[NSString stringWithFormat:@"%s", sqlite3_errmsg(_DB)]];
               }

           }
        else{
            [g showCustomAlertView:@"Failure" message:[NSString stringWithFormat:@"%s", sqlite3_errmsg(_DB)]];
        }

    }
    else{
        [g showCustomAlertView:@"Failure" message:[NSString stringWithFormat:@"%s", sqlite3_errmsg(_DB)]];
    }
    sqlite3_close(_DB);
}

从sqlite中检索图像

-(NSMutableArray *)SELECTATTACHMENTFROMCLAIMATTACHMENTITEM:(long long)rowID
{
    sqlite3_stmt *statement;
    const char *dbPath = [_databasePath UTF8String];

    Global * g = [[Global alloc]init];

    NSMutableArray *attachmentArray = [[NSMutableArray alloc]init];

    if(sqlite3_open(dbPath, &_DB) == SQLITE_OK)
    {
        NSString *querySQL = [NSString stringWithFormat:@"SELECT * FROM CLAIM_ATTACHMENT_ITEM WHERE PARENT_ID = '%lld'", rowID];
        const char *query_Statement = [querySQL UTF8String];

        if(sqlite3_prepare_v2(_DB, query_Statement, -1, &statement, NULL) == SQLITE_OK)
        {
            while(sqlite3_step(statement) == SQLITE_ROW)
            {
                AttachmentItem * attachment = [[AttachmentItem alloc]init];
                NSData *attachmentImageData = [[NSData alloc]initWithBytes:sqlite3_column_blob(statement, 2) length:sqlite3_column_bytes(statement, 2)];

                UIImage *attachmentImage = [UIImage imageWithData:attachmentImageData];

                NSString *attachmentName = [[NSString alloc]initWithUTF8String:sqlite3_column_text(statement, 3)];
                attachment.attachmentImage = attachmentImage;
                attachment.attachmentName = attachmentName;
                [attachmentArray addObject:attachment];
            }
        }
        else
        {
            [g showCustomAlertView:@"Failure" message:[NSString stringWithFormat:@"%s", sqlite3_errmsg(_DB)]];
        }
    }
    else
    {
        [g showCustomAlertView:@"Failure" message:[NSString stringWithFormat: @"%s",sqlite3_errmsg(_DB)]];
    }


    sqlite3_close(_DB);

    return attachmentArray;

}

会发生什么?为什么图像数据缩小为一个字节给我:( 我猜测blob无法存储那么大小的数据?

2 个答案:

答案 0 :(得分:2)

您对sqlite_bind_blob的呼叫传递了错误的字段索引。您在?语句中只有一个INSERT,因此索引应为1,而不是2

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

此外,您需要从?声明中的INSERT中删除引号:

NSString *insertSQL = [NSString stringWithFormat:@"INSERT INTO CLAIM_ATTACHMENT_ITEM ('PARENT_ID', 'CLAIM_ATTACHMENT_CONTENT', 'CLAIM_ATTACHMENT_NAME', 'CLAIM_ATTACHMENT_SIZE') VALUES ('%lld', ?, '%@', '%lu')", parentid,attachmentname, [imageData length]];

使用?结合相应的sqlite3_bind_xxx语句而不是使用stringWithFormat:构建查询的主要原因是,您可以正确引用和转义值。

答案 1 :(得分:1)

VALUES ('%lld', '?', '%@', '%lu')

%替换是文本的,但?由SQL引擎处理,仅当参数标记出现在表达式中时才有效。

使用引号,'?'只是一个包含单个字符?的字符串。

您必须编写没有引号的参数:

[NSString stringWithFormat:@"INSERT ... VALUES ('%lld', ?, '%@', '%lu')", ...];

此语句只有一个SQL参数,因此其索引必须为1,而不是2。