0

好的,所以我不确定如何命名这个问题,但我可以解释我的问题是什么。我正在创建一个网络浏览器,并使用一个 sqlite 数据库来存储历史记录。当页面完成加载我的方法时:

-(void)addHistory:(NSString*)title address:(NSString*)url{
    sqlite3_stmt    *statement;
    const char *dbpath = [_databasePath UTF8String];

     if (sqlite3_open(dbpath, &_historyDB) == SQLITE_OK)
     {
         NSString *updateSQL = [NSString stringWithFormat:
                                @"UPDATE HISTORY SET title='%@' WHERE url='%@'", title, url];

         const char *update_stmt = [updateSQL UTF8String];

         sqlite3_stmt *stmt;
         if (sqlite3_prepare_v2(_historyDB, update_stmt, -1, &stmt, NULL)==SQLITE_OK) {
             NSLog(@"Updated");
         }else{
             NSString *insertSQL =
             [NSString stringWithFormat:
              @"INSERT INTO HISTORY (title, url, visits, date, search) VALUES (\"%@\", \"%@\", \"%@\", \"%@\", \"%@\")",
              title, url, @"todo", @"todo", [NSString stringWithFormat:@"%@ %@", title, url]];

             const char *insert_stmt = [insertSQL UTF8String];
             sqlite3_prepare_v2(_historyDB, insert_stmt,
                                -1, &statement, NULL);
             if (sqlite3_step(statement) == SQLITE_DONE)
             {
                 NSLog(@"Added Entry");
             } else {
                 NSLog(@"Coundn't Add Entry");
             }
             sqlite3_finalize(statement);
         }
         sqlite3_close(_historyDB);
    }
}

我假设如果更新失败(因为 url 不存在于表中),它将移动到 else 语句并添加密钥。这背后的主要思想是更新网页的标题,一旦工作,更新其他字段,如上次访问、查看次数等。

我尝试了各种不同的方法,但似乎无法达到预期的效果。

4

2 回答 2

0

我最终切换到FMDB,这是一个出色的 SQLite 的 Objective-C 包装器。然后我执行了一个SELECT语句,其中 url 匹配当前的,如果它返回一个值我更新数据库,如果不是,我只是添加到它。

于 2013-11-12T13:01:42.363 回答
0

要执行更新语句,您必须调用sqlite3_step该语句。要了解更新了多少记录,请调用sqlite3_changes

您必须处理sqlite3_prepare_v2调用返回的任何错误。

你必须sqlite3_finalize呼吁stmt

任何带有'URL 或标题的网站都会破坏您的 SQL 语句;要避免SQL 注入攻击,请使用参数

于 2013-11-11T15:41:11.617 回答