如何使用ios更新sqlite中的图像

时间:2013-08-29 06:08:25

标签: ios sqlite

我想使用此查询存储带有图像的数据,所有内容都正确更新但图像列始终为null.i不知道此查询中有什么问题。请任何人帮我修复它。我很新到iOS和sqlite。

    UIImage *uiimg = img.image;
    NSData *data = UIImagePNGRepresentation(uiimg);

    NSString *cmd = [NSString stringWithFormat:@"update APPUSERS set name = '%@', u_name =           '%@', contact_no = '%@', address = '%@', dob = '%@', pswrd = '%@', confirm_pswrd = '%@', img = '%d' where u_name ='%@'",name.text, uname.text, pnoneno.text, address.text, dob.text, password.text, confirmpassword.text, data, tempstore] ;

    const char * sql = [cmd UTF8String];


    if (sqlite3_step(update_statement) == SQLITE_DONE)
     {
            NSLog(@"success");
     }
       else
     {
            NSLog(@"failed");

    }

2 个答案:

答案 0 :(得分:4)

有关如何使用sqlite3_bind_blobNSData存储在数据库中的示例,请参阅https://stackoverflow.com/a/17994313/1271826

此外,您绝对应该避免使用stringWithFormat来构建SQL语句。如果地址为123 O'Brian WayMartha's Vineyard,该怎么办?那个撇号会过早地终止你要插入的字符串。当你去插入Jimmy "The Greek" SnyderDwayne "The Rock" Johnson时,双引号并不是更好。更糟糕的是,恶意用户可能会对SQL注入造成严重破坏。

您应该使用?占位符和sqlite3_bind_blob功能NSData。对于您的字符串,请使用sqlite3_bind_text

因此:

UIImage *uiimg = img.image;
NSData *data = UIImagePNGRepresentation(uiimg);

const char *sql = "update APPUSERS set name = ?, u_name = ?, contact_no = ?, address = ?, dob = ?, pswrd = ?, confirm_pswrd = ?, img = ? where u_name =?";

if (sqlite3_prepare_v2(database, sql, -1, &update_statement, NULL) != SQLITE_OK)
    NSLog(@"prepare failed: %s", sqlite3_errmsg(database));

if (sqlite3_bind_text(update_statement, 1, [name.text UTF8String], -1, NULL) != SQLITE_OK)
    NSLog(@"bind 1 failed: %s", sqlite3_errmsg(database));

if (sqlite3_bind_text(update_statement, 2, [uname.text UTF8String], -1, NULL) != SQLITE_OK)
    NSLog(@"bind 2 failed: %s", sqlite3_errmsg(database));

if (sqlite3_bind_text(update_statement, 3, [pnoneno.text UTF8String], -1, NULL) != SQLITE_OK)
    NSLog(@"bind 3 failed: %s", sqlite3_errmsg(database));

if (sqlite3_bind_text(update_statement, 4, [address.text UTF8String], -1, NULL) != SQLITE_OK)
    NSLog(@"bind 4 failed: %s", sqlite3_errmsg(database));

if (sqlite3_bind_text(update_statement, 5, [dob.text UTF8String], -1, NULL) != SQLITE_OK)
    NSLog(@"bind 5 failed: %s", sqlite3_errmsg(database));

if (sqlite3_bind_text(update_statement, 6, [password.text UTF8String], -1, NULL) != SQLITE_OK)
    NSLog(@"bind 6 failed: %s", sqlite3_errmsg(database));

if (sqlite3_bind_text(update_statement, 7, [confirmpassword.text UTF8String], -1, NULL) != SQLITE_OK)
    NSLog(@"bind 7 failed: %s", sqlite3_errmsg(database));

// note, use blob here

if (sqlite3_bind_blob(update_statement, 8, [data bytes], [data length], SQLITE_TRANSIENT) != SQLITE_OK)
    NSLog(@"bind 8 failed: %s", sqlite3_errmsg(database));

if (sqlite3_bind_text(update_statement, 9, [tempstore UTF8String], -1, NULL) != SQLITE_OK)
    NSLog(@"bind 9 failed: %s", sqlite3_errmsg(database));

if (sqlite3_step(update_statement) == SQLITE_DONE)
{
    NSLog(@"success");
}
else
{
    NSLog(@"failed: %s", sqlite3_errmsg(database));
}

sqlite3_finalize(update_statement);

注意,除了sqlite3_bind_xxx之外,我还建议(a)不要忘记先sqlite3_prepare_v2; (b)在任何错误上,查看sqlite3_errmsg; (c)记得在最后做sqlite3_finalize以释放你的记忆。

但请注意,SQLite在存储大型blob方面效率低下。如果图像是小缩略图,则不是问题,但对于大图像,您应该将图像保存到Documents文件夹,然后只保存数据库中的文件路径。

最后请注意,如果您有一个加载到UIImage的图像,然后通过UIImagePNGRepresentation重新检索,则可能导致数据丢失或文件可能会变得更大。这取决于图像的原始来源。人们通常认为,如果他们UIImagePNGRepresentation,他们保证得到相同的图像,虽然它看起来几乎相同,但它可以在过程中改变(并不总是;它取决于)。如果您有权访问用于设置NSData的原始资产/文件/ UIImage,那么您应该再次参考。


作为一个无关的方面,你真的不应该在数据库中以明文形式存储密码。您应该加密它们或使用keychain来存储密码。

答案 1 :(得分:1)

尝试通过在NSFileManager中创建NSDocument来保存数据库中的图像名称和图像文件夹中的图像。这些是单例实例。您可以将图像保存在与应用程序文档相关的手机记忆文件夹中

您可以在此路径中找到Read/write file in Documents directory problem