有关如何使用 sqlite3_bind_blob 将 NSData 存储在数据库中的示例,请参阅 https://stackoverflow.com/a/17994313/1271826。
此外,您绝对应该避免使用stringWithFormat 来构建一般的SQL 语句。如果地址是123 O'Brian Way 或Martha'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 文件夹,然后仅将文件路径保存在数据库中。
最后,请注意,如果您将图像加载到UIImage,然后通过UIImagePNGRepresentation 重新检索,这可能会导致数据丢失或文件可能会变得相当大。这取决于图像的原始来源。人们经常假设如果他们这样做UIImagePNGRepresentation,他们肯定会得到相同的图像,虽然它可能看起来几乎相同,但它可以在这个过程中改变(并不总是;这取决于)。如果您可以访问用于设置 UIImage 的原始资产/文件/NSData,则应该返回该内容。
顺便说一句,您也不应该在数据库中以明文形式存储密码。您应该加密它们或使用keychain 来存储密码。