简体   繁体   English

SQLite数据库不会更新

[英]SQLite database doesn't get updated

I have a database that has a student entity: 我有一个拥有学生实体的数据库:

create table student ( name varchar(20) not null,
                       surname varchar(20) not null,
                       studentId integer primary key );

In my app delegate when the application starts I load all the tuples from the database and display them to a table view. 在应用程序启动时我的app委托中,我从数据库加载所有元组并将它们显示到表视图中。
When the app delegate receiver the applicationWillResignActive event it saves all the tuples to the database.It saves only the tuples that have been added, there isn't the possibility to edit the tuples so that's fine. 当app委托接收者applicationWillResignActive事件时,它将所有元组保存到数据库。它只保存已添加的元组,没有可能编辑元组,所以没关系。
When the app delegate receives the applicationWillEnterForeground event it reads the tuples from the database. 当app委托收到applicationWillEnterForeground事件时,它会从数据库中读取元组。

The problem: This works only inside a single launch of the application.Let's say that I launch the application through Xcode, then I enter I add an element and enter in background.Afterwards I reactivate the application, it goes in foreground, and it loads successfully all the tuples. 问题:这只能在应用程序的单个启动中运行。让我说我通过Xcode启动应用程序,然后我输入我添加一个元素并输入后台。之后我重新激活应用程序,它进入前台,然后加载成功的所有元组。
But at the next launch of the application (stopping it from lldb and launching it again) the tuples are the same as before the first launch. 但是在下一次启动应用程序时(从lldb停止并再次启动它),元组与第一次启动时相同。

I created a wrapper class for the student entity, named Student, with these properties: 我为学生实体创建了一个包装类,名为Student,具有以下属性:

@property (nonatomic, copy, readwrite) NSString* name;
@property (nonatomic, copy , readwrite) NSString* surname;
@property (nonatomic, strong, readwrite) NSNumber* studentId;
@property (nonatomic, readwrite, getter= isNew) BOOL new;

I check that the fields are not nil and that the entity integrity is not violated. 我检查字段不是nil并且不违反实体完整性。
The only significative method that I use is this: 我使用的唯一有意义的方法是:

- (NSString*) sqlInsertionString;

It creates the string necessary to insert the tuple.Tested and works. 它创建插入元组所必需的字符串。测试和工作。

So that's how I update the database: 这就是我更新数据库的方式:

- (void) updateStudents : (NSMutableArray*) students
{
    sqlite3* database;
    sqlite3_stmt* statement;
    BOOL needsFinalize=NO;
    if(!databasePath)
    {
        NSBundle* bundle=[NSBundle mainBundle];
        databasePath= [bundle pathForResource: @"test" ofType: @"db"];
    }
    if(sqlite3_open([databasePath UTF8String], &database)!=SQLITE_OK)
    {
        NSString* problem= [NSString stringWithFormat: @"%s",sqlite3_errmsg(database)];
        @throw [NSException exceptionWithName: @"Failed to open the database" reason: problem userInfo: nil];
    }
    for(Student * s in students)
    {
        if(s.isNew)
        {
            NSString* sqlString= [s sqlInsertionString];
            if(sqlite3_prepare_v2(database, [sqlString UTF8String], -1, &statement, NULL)!= SQLITE_OK)
            {
                @throw [NSException exceptionWithName: @"Problem performing the query" reason: @"Unknown" userInfo: nil];
            }
            if(sqlite3_step(statement)!=SQLITE_DONE)
            {
                @throw [NSException exceptionWithName: @"Problem performing the query" reason: @"Unknown" userInfo:nil];
            }
            sqlite3_reset(statement);
            needsFinalize=YES;
        }
    }
    if(needsFinalize && sqlite3_finalize(statement)!=SQLITE_OK)
    {
        @throw [NSException exceptionWithName: @"Failed to close the statement resource" reason: @"Unknown" userInfo:nil];
    }
    if(sqlite3_close(database)!= SQLITE_OK)
    {
        @throw [NSException exceptionWithName: @"Failed to close the database" reason: @"Unknown" userInfo: nil];
    }
}

But it doesn't get really updated, only inside the application it appears to be updated, but the file always remains the same. 但它没有真正更新,只在应用程序内部看起来更新,但文件始终保持不变。

The problem is that you're opening the database from the bundle. 问题是您要从捆绑包中打开数据库。 You can't make (persistent) modifications to that. 你无法对其进行(持久)修改。 The standard solution is to check for the database in your Documents folder, if there, use it, if not, copy from bundle to Documents and then open the database from Documents . 标准解决方案是检查Documents文件夹中的数据库,如果有,请使用它,如果没有,请从bundle复制到Documents ,然后从Documents打开数据库。

See Unable to connect SQLite Database in iOS 请参阅无法在iOS中连接SQLite数据库

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM