【问题标题】:SQLite3 update not workingSQLite3 更新不起作用
【发布时间】:2011-09-24 17:52:42
【问题描述】:

我正在尝试对我的 sqlite3 表执行更新命令。但它不起作用:

+(void)updateContact:(Contact *)c withOriginalFirst:(NSString *)originalFirst originalLast:(NSString *)originalLast originalBriefDescription:(NSString *)originalBriefDescription {

    sqlite3 *database;
    if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {

        NSString *cmd = [NSString stringWithFormat:@"update contacts set first='%@', last='%@', briefDescription='%@' where first='%@' and last='%@' and briefDescription='%@';",
                         [c first],[c last],[c briefDescription],originalFirst,originalLast,originalBriefDescription];
        const char * sql = [cmd UTF8String];
        sqlite3_stmt *compiledStatement;
        if(sqlite3_prepare_v2(database, sql, -1, &compiledStatement, NULL) == SQLITE_OK) {
            NSLog(@"updateContact SUCCESS - executed command %@",cmd);
        }
        else {
            NSLog(@"updateContact FAILED - failed to execute command %@",cmd);
        }

        sqlite3_finalize(compiledStatement);

    }
    else {
        NSLog(@"pdateContact FAILED - failed to open database");
    }

    sqlite3_close(database);

    NSLog(@"After update, contacts = %@",[SQLMaster getContactsFromDatabase]);

}

我看到打印了“updateContact SUCCESS - 已执行命令...”。但是表格没有更新。我做错了什么?

【问题讨论】:

    标签: iphone ios sqlite


    【解决方案1】:

    一些事情:

    你的databasePath指向哪里?确保它指向包中的文档路径,而不是直接指向项目中的外部数据库。此外,请确保正确放置步骤语句。

    +(void)updateContact:(Contact *)c withOriginalFirst:(NSString *)originalFirst originalLast:(NSString *)originalLast originalBriefDescription:(NSString *)originalBriefDescription {
    
    sqlite3 *database;
    if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
    
        NSString *cmd = [NSString stringWithFormat:@"update contacts set first='%@', last='%@', briefDescription='%@' where first='%@' and last='%@' and briefDescription='%@';",
                         [c first],[c last],[c briefDescription],originalFirst,originalLast,originalBriefDescription];
        const char * sql = [cmd UTF8String];
        sqlite3_stmt *compiledStatement;
        if(sqlite3_prepare_v2(database, sql, -1, &compiledStatement, NULL) == SQLITE_OK) {
            sqlite3_step(compiledStatement); // Here is the added step.
            NSLog(@"updateContact SUCCESS - executed command %@",cmd);
        }
        else {
            NSLog(@"updateContact FAILED - failed to execute command %@",cmd);
        }
    
        sqlite3_finalize(compiledStatement);
    
    }
    else {
        NSLog(@"pdateContact FAILED - failed to open database");
    }
    
        sqlite3_close(database);
        NSLog(@"After update, contacts = %@",[SQLMaster getContactsFromDatabase]);
    
    }
    

    另外,我从 [SQLMaster getContactsFromDatabase] 行看到您正在调用其他数据库方法。确保所有这些数据库调用都达到了 sqlite3_finalize,否则数据库可能不会释放繁忙的处理程序。

    【讨论】:

    • 每次发生这种情况时我都必须重新创建数据库吗?或者应该重新启动与数据库的应用程序端连接。你说的我都做了。这是我进行的第一个数据库调用。数据库路径是正确的。还能是什么?我就是不明白。
    • 除非数据是在设备上手动填充的(有时甚至是这样),否则每当我对应用程序进行重大更改或对数据库功能进行更改时,我总是会从设备或模拟器中删除应用程序包。这会将数据库的新副本迁移到您的模拟器或设备。我觉得这是最安全的方法。
    • 我是否也应该每次都关闭数据库?
    • 这取决于。如果您经常调用数据库和大量行,这可能会影响性能,因为它会缓存数据。关闭数据库将释放缓存。如果您不经常调用您的数据库或没有处理大量数据,那么您应该可以让您的数据库连接保持打开状态,直到应用程序关闭。请确保您定期重置和完成您的陈述。
    • 如果您修改缓存大小,也可以提高性能。初始化数据库后,您可以使用以下代码执行此操作: const char *pragma = "PRAGMA cache_size = 25"; if (sqlite3_exec(database, pragma, NULL, NULL, NULL) != SQLITE_OK) { // NSAssert1 消息 }
    【解决方案2】:

    这可能对你有帮助……

      +(void)updateContact:(Contact *)c withOriginalFirst:(NSString *)originalFirst originalLast:(NSString *)originalLast originalBriefDescription:(NSString *)originalBriefDescription 
    
        {
        if(sqlite3_open([databasePath UTF8String],&myDatabase)==SQLITE_OK)
    {
        sqlite3_stmt *compiledStmt;
        NSString  *sqlStmt=[NSString stringWithFormat:@"UPDATE contacts SET first =?, last =? , briefDescription =?, briefDescription =? WHERE first=?,last=?,briefDescription=?;"];
    
        if(sqlite3_prepare_v2(myDatabase, [sqlStmt UTF8String],-1,&compiledStmt, NULL)==SQLITE_OK)
        {
    
             NSLog(@"updateding......cycle");
        sqlite3_bind_text(compiledStmt,1, [[c first] UTF8String],-1,SQLITE_TRANSIENT);
            sqlite3_bind_text(compiledStmt,2, [[c last] UTF8String],-1,SQLITE_TRANSIENT);
    
         sqlite3_bind_text(compiledStmt,3, [[c briefDescription] UTF8String],-1,SQLITE_TRANSIENT);  
    
       sqlite3_bind_text(compiledStmt,4, [originalFirst UTF8String],-1,SQLITE_TRANSIENT);
    
       sqlite3_bind_text(compiledStmt,5, [originalLast UTF8String],-1,SQLITE_TRANSIENT);
    
        sqlite3_bind_text(compiledStmt,6, [originalBriefDescription UTF8String],-1,SQLITE_TRANSIENT);
        }
        sqlite3_step(compiledStmt);
        sqlite3_close(database);
    }
    
    
    
      }
    

    【讨论】:

      【解决方案3】:

      您准备了语句但没有执行它。尝试 int sqlite3_step(sqlite3_stmt*);准备之后。

      【讨论】:

      • SQLITE_BUSY 表示数据库引擎无法获取完成工作所需的数据库锁。是否有其他进程正在访问数据库文件,或者您是否有其他与数据库的连接?
      • 它不工作。为什么会被锁定?没有其他东西可以访问这个数据库。
      • 关于 iphone 的两个类似报告。重新启动设备修复了一个。 thread 1thread 2
      • 重启无效。我重新启动了电脑和手机。另外,我已经接到了 finalize 电话。
      猜你喜欢
      • 1970-01-01
      • 2012-11-08
      • 2018-07-21
      • 1970-01-01
      • 2019-08-09
      • 2013-06-23
      • 2013-12-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多