iOS SQLite Blob 数据正在保存 NULL

标签 ios objective-c sqlite blob nsdata

我正在尝试使用此代码插入 SignatureView 的 BLOB 数据,但是当我实际浏览数据库时,出现的是 null 而不是数据。 我的签名表架构如下。

create table sign(id integer primary key AUTOINCREMENT, image blob,invoiceid integer);

-(void)storeImageData:(NSData *)imageData withInvoiceID:(NSInteger)invoiceID{

    NSString *dbPath = [[[NSBundle mainBundle] resourcePath ]stringByAppendingPathComponent:@"database.sqlite3"];
    const char *dbpath = [dbPath UTF8String];
    sqlite3 *contactDB;

    sqlite3_stmt    *statement;

    NSLog(@"%@",dbPath);
    if (sqlite3_open(dbpath, &contactDB) == SQLITE_OK)
    {
        int invoiceIDINT = (int)invoiceID;
    //
        NSString *insertSQL = [NSString stringWithFormat: @"INSERT INTO sign (image,invoiceid) VALUES (?,%d)", invoiceIDINT];

        const char *insert_stmt = [insertSQL UTF8String];

        sqlite3_prepare_v2(contactDB, insert_stmt, -1, &statement, NULL);
        if (sqlite3_step(statement) == SQLITE_DONE)
        {
            sqlite3_bind_blob(statement, 2, [imageData bytes], [imageData length], SQLITE_TRANSIENT);
            sqlite3_step(statement);

        } else {
            const char *Error = sqlite3_errmsg(database);
            NSString *error = [[NSString alloc]initWithUTF8String:Error];
            UIAlertView *view = [[UIAlertView alloc]initWithTitle:@"Error2" message:[NSString stringWithFormat:@"Last inserted ID: %@",error] delegate:nil cancelButtonTitle:@"Cancel" otherButtonTitles:nil, nil];
            [view show];
        }
        sqlite3_finalize(statement);
        sqlite3_close(contactDB);
    }


}

最佳答案

  1. 始终检查 sqlite3_prepare_v2 的结果。如果失败,请使用 sqlite3_errmsg 记录问题。
  2. 仅在 sqlite3_prepare_v2 成功时调用 sqlite3_finalize
  3. Blob 得到 NULL,因为您对 sqlite3_bind_blob 的调用传递了错误的列索引。它应该是 1,而不是 2,因为您想绑定(bind)到 INSERT 语句中的第一个 ?
  4. 为什么不一致?为什么要使用 stringWithFormat 设置 invoiceid 列的值,然后使用 sqlite_bind_xxx 设置 image 列的值?你应该绑定(bind)两者。切勿使用 stringWithFormat 构建查询。
  5. 你调用 sqlite3_step 两次。只调用一次并在调用前绑定(bind)您的值。
  6. 您似乎正在向应用程序资源包内的数据库写入数据。你不能在真实设备上这样做。它适用于模拟器,但不适用于真实的 iOS 设备。您需要将数据库文件放在 Documents 文件夹中。

考虑到以上所有内容,您的代码应该是这样的:

-(void)storeImageData:(NSData *)imageData withInvoiceID:(NSInteger)invoiceID{
    // This is wrong - you need to update this to use the Documents folder
    NSString *dbPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"database.sqlite3"];
    const char *dbpath = [dbPath UTF8String];
    NSLog(@"%@",dbPath);

    sqlite3 *contactDB;
    if (sqlite3_open(dbpath, &contactDB) == SQLITE_OK)
    {
        const char *insert_stmt = "INSERT INTO sign (image, invoiceid) VALUES (?, ?)";

        sqlite3_stmt *statement;
        if (sqlite3_prepare_v2(contactDB, insert_stmt, -1, &statement, NULL) == SQLITE_OK) {
            sqlite3_bind_blob(statement, 1, [imageData bytes], [imageData length], SQLITE_TRANSIENT);
            sqlite3_bind_int(statement, 2, (int)invoiceID);

            if (sqlite3_step(statement) == SQLITE_DONE) {
                // Row inserted successfully
            } else {
                const char *Error = sqlite3_errmsg(contactDB);
                NSString *error = [[NSString alloc] initWithUTF8String:Error];
                UIAlertView *view = [[UIAlertView alloc] initWithTitle:@"Error2" message:[NSString stringWithFormat:@"Last inserted ID: %@",error] delegate:nil cancelButtonTitle:@"Cancel" otherButtonTitles:nil, nil];
                [view show];
            }

            sqlite3_finalize(statement);
        } else {
            NSLog(@"Unable to prepare statement %s: %s", insert_stmt, sqlite3_errmsg(contactDB));
        }

        sqlite3_close(contactDB);
    } else {
        NSLog(@"Unable to open database at path %@: %s", dbPath, sqlite3_errmsg(contactDB));
    }
}

关于iOS SQLite Blob 数据正在保存 NULL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36783244/

相关文章:

c++ - 使用 qt 在 SQLITE 数据库中插入多行

ios - ObjectiveC mutableCopy 如何在 swift 中工作

ios - 我应该有自己的服务器来存储用户通过我的应用程序发布的照片​​吗?

ios - UINavigationController 中的 UITabBarController 中的 UITableViewController

IOS/objective-C : How to Access JSON within parentheses

c++ - 无法在 SQLite 的命令行上访问表

ios - 如果使用核心图散点图中只有一个值,如何显示单个点

ios - 使用 Masonry 在它的 super View 中居中 View

ios - 模型 NSArray 是可变的还是不可变的?

python - 管理、查询和拆分、合并、应用多个本地 csv 数据文件?可能使用数据库?