-1

我想使用此查询存储带有图像的数据,一切都正确更新,但图像列始终为空。我不知道此查询有什么问题。请任何人帮我解决它。我是 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");

    }
4

2 回答 2

4

请参阅https://stackoverflow.com/a/17994313/1271826,了解如何使用sqlite3_bind_blob将您的数据存储NSData在数据库中的示例。

此外,您绝对应该避免使用stringWithFormat用于构建一般的 SQL 语句。如果地址是123 O'Brian WayorMartha's Vineyard怎么办?该撇号会过早终止您插入的字符串。当你去插入Jimmy "The Greek" Snyder或时,双引号并不好Dwayne "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文件夹中,然后只将文件路径保存在数据库中。

最后,请注意,如果您将图像加载到 aUIImage中,然后通过 重新检索UIImagePNGRepresentation,这可能会导致数据丢失或文件可能会变得相当大。这取决于图像的原始来源。人们通常认为,如果他们这样做UIImagePNGRepresentation,就可以保证获得相同的图像,虽然它可能看起来几乎相同,但可以在此过程中进行更改(并非总是如此;这取决于)。如果您有权访问用于NSData设置的原始资产/文件/ UIImage,则应返回该内容。


顺便说一句,您也不应该在数据库中以明文形式存储密码。您应该加密它们或使用钥匙串来存储密码。

于 2013-08-29T07:06:04.553 回答
1

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

示例您可以在此路径中找到Documents 目录中的读/写文件问题

于 2013-08-29T06:39:26.773 回答