ios - SQLite 数据库不可写

标签 ios database sqlite

我有一个使用 Firefox SQLite Manager 插件创建的预填充 SQLite 数据库。 我已将数据库包含到我的项目中,添加到目标并复制到目标组的文件夹中。然后我创建了这个函数来复制文档文件夹中的数据库:

-(void) createEditableDatabase{
    BOOL success;
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSError *error;
    NSString *writableDB = [[NSHomeDirectory() stringByAppendingPathComponent:@"Documents"] stringByAppendingPathComponent:@"DB.sqlite"];
    success = [fileManager fileExistsAtPath:writableDB];
    if (success){
        return;
    }
    NSString *defaultPath = [[[NSBundle mainBundle] resourcePath]  stringByAppendingPathComponent:@"DB.sqlite"];
    error = nil;
    success = [fileManager copyItemAtPath:defaultPath toPath:writableDB error:&error];
    if (!success){
        NSAssert1(0, @"Failed to create writable database file:%@", [error localizedDescription]);
    }
    if (error){
        NSLog(@"error = %@", [error localizedDescription]);
    }
}

然后我在 -(void)viewDidLoad 中调用此函数,如果我 checkin 模拟器文件夹,一旦启动应用程序,就会出现数据库的副本。 该应用程序运行良好,我可以使用从数据库检索的数据填充 UICollectionView 。 然后,当我尝试插入一些数据时,我没有收到错误,但没有数据添加到数据库中。 这是我在 MyViewController.h 中使用的代码:

@property (nonatomic) NSString *DBPath;
@property (nonatomic) sqlite3 *myAppSQLITE;

这是我在 MyViewController.m 中使用的代码:

-(IBAction)done:(id)sender{
    DBPath = [[NSHomeDirectory() stringByAppendingPathComponent:@"Documents"] stringByAppendingPathComponent:@"DB.sqlite"];
    const char *dbpath = [DBPath UTF8String];
    sqlite3_stmt *statement;
    if (sqlite3_open(dbpath, &myAppSQLITE) == SQLITE_OK){
        NSString *querySQL = [NSString stringWithFormat:@"INSERT INTO myTable (name, age) VALUES('frank',30);"];
        const char *query_stmt = [querySQL UTF8String];
        if (sqlite3_prepare_v2(myAppSQLITE, query_stmt, -1, &statement, NULL) == SQLITE_OK){
            sqlite3_finalize(statement);
        }
        sqlite3_close(myAppSQLITE);
    }
}

我没有收到错误/警告,但数据从未更新,即使使用 [self.collectionView reloadData]; 也是如此。如果我在 Firefox 中使用 SQLite Manager 运行相同的查询,一切都会正常。如果我使用 SQLite Manager 打开 Simulator Documents 文件夹内的数据库,则数据库完好无损,没有更新的数据。我用 iPad 运行该应用程序得到了相同的结果。 我该如何解决这个问题? 预先感谢您。

P.S:David的建议是正确的,这是创建可编辑数据库的更好方法:

- (void) createEditableDatabase{
    BOOL success;
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSError *error;
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:@"DB.sqlite"];
    success = [fileManager fileExistsAtPath:writableDBPath];
    if (success){
        return;
    }
    NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"DB.sqlite"];
    success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
    if (!success) {
        NSAssert1(0, @"Failed to create writable database file with message '%@'.", [error localizedDescription]);
    }
}

P.S2:这可能是一个适当的错误检查,让我知道它是否正确。

int rc;
while ((rc = sqlite3_step(statement)) == SQLITE_ROW){
    NSLog(@"ROW");
}
if (rc != SQLITE_DONE){
    NSLog(@"%s: step error: %d: %s", __FUNCTION__, rc, sqlite3_errmsg(myAppSQLite));
}

最佳答案

您实际上从未通过调用sqlite3_step来执行查询。

你想要:

if (sqlite3_prepare_v2(myAppSQLITE, query_stmt, -1, &statement, NULL) == SQLITE_OK){
    sqlite3_step(statement); // add appropriate error checking
    sqlite3_finalize(statement);
}

关于ios - SQLite 数据库不可写,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23369131/

相关文章:

ios - Firebase 在 Swift 3 中处理其中包含字典的子快照

ios - 从 iOS 8.2 开始,时间准确性有所提高?

python - 将超链接嵌入到数据集中带有 HTML 的列中

android - 比较android中的两个Arraylists

ios - NSURLSession/NSURLConnection HTTP 加载在 Swift 4 上失败

iOS Swift 检测键盘事件

mysql - 创建存储过程时出错

C++ SQLite3 在更新后立即返回一个空查询

android - 如何创建 Android 数据库应用程序?

ios - 如何检查记录是否存在于 SQLite 数据库中的表中?