【问题标题】:Objective C Sqlite Update Query Based on ID基于ID的Objective C Sqlite更新查询
【发布时间】:2016-04-12 22:50:36
【问题描述】:

尝试在不使用包装器的情况下学习 Sqlite,并且已经管理了大多数事情,但我真的停留在 UPDATE 查询上

我正在尝试根据其 _ID 编号更新一列中的字符串,该编号是主键并且是唯一的。

我已经尝试了来自 google 的各种代码。这个说它已经工作了,但是当我检查该列时没有更新

这里是代码

            NSDateFormatter *formatter;
            NSString        *dateString;
            formatter = [[NSDateFormatter alloc] init];
            [formatter setDateFormat:@"dd-MM-yyyy HH:mm"];
            dateString = [formatter stringFromDate:[NSDate date]];
            NSString *IDCODE = code.stringValue;
           NSInteger b = [IDCODE integerValue];
            sqlite3 *contactDB; //Declare a pointer to sqlite database structure
            const char *dbpath = [dbPath UTF8String]; // Convert NSString to UTF-8
            if (sqlite3_open(dbpath, &contactDB) == SQLITE_OK)
            {
                //Database opened successfully
                NSString *databaseName = @"vistorlog.db";
                // Get the path to the documents directory and append the databaseName
                NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
                NSString *documentsDir = [documentPaths objectAtIndex:0];
                NSString *databasePath = [documentsDir stringByAppendingPathComponent:databaseName];
                const char *dbPath=[databasePath UTF8String];
                if (sqlite3_open(dbPath, &myDB)==SQLITE_OK) {
                    NSLog(@"database Opened");
                    const char* updateQuery="update LOG set TIMEOUT='22/03/19' where _ID=1";
                    sqlite3_stmt *stmt;
                    if (sqlite3_prepare_v2(myDB, updateQuery, -1, &stmt, NULL)==SQLITE_OK) {
                        NSLog(@"Query Executed");
                    }else{
                         NSLog(@"Query NOT Executed");
                                               }
                }
                sqlite3_close(myDB);
                }
                else {
                //Failed to open database
            }

它打开数据库vistorlog.db ok。有一个名为 LOG 的表,有一个名为 TIMEOUT 的列,我希望在其中更新字符串,还有一个名为 _ID 的列,这是我查询的基础,但它不会更新

最终我希望更新语句使用字符串变量 dateString 作为要更新的字符串,使用 b 作为 _ID 的整数变量

任何想法我哪里出错了?

任何帮助表示赞赏

标记

编辑

更新查询的工作代码

sqlite3 *contactDB; //Declare a pointer to sqlite database structure
            const char *dbpath = [dbPath UTF8String]; // Convert NSString to UTF-8
            if (sqlite3_open(dbpath, &contactDB) == SQLITE_OK)
            {
                //Database opened successfully
                NSString *databaseName = @"vistorlog.db";
                // Get the path to the documents directory and append the databaseName
                NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
                NSString *documentsDir = [documentPaths objectAtIndex:0];
                NSString *databasePath = [documentsDir stringByAppendingPathComponent:databaseName];
                const char *dbPath=[databasePath UTF8String];
                if (sqlite3_open(dbPath, &myDB)==SQLITE_OK) {
                    NSLog(@"database Opened");

// define dateString and IDCODE as strings before this
                    const char *updateQuery = "Update log set TIMEOUT=? where _ID=?";
                    sqlite3_stmt *stmt;
                    // Prepare Stment
                    if (sqlite3_prepare_v2(myDB, updateQuery, -1, &stmt, NULL) == SQLITE_OK) {
                        sqlite3_bind_text(stmt, 1, [dateString UTF8String], -1, SQLITE_TRANSIENT);
                        sqlite3_bind_text(stmt, 2, [IDCODE UTF8String], -1, SQLITE_TRANSIENT);                            if(sqlite3_step(stmt) == SQLITE_DONE) {
                            NSLog(@"Query Executed");
                        } else {
                            NSLog(@"Query NOT Executed: %s", sqlite3_errmsg(myDB));
                        }
                        sqlite3_finalize(stmt);

                    }else{
                        NSLog(@"Statement NOT Prepared: %s", sqlite3_errmsg(myDB));
                    }
                }
                sqlite3_close(myDB);
                }
                else {
                //Failed to open database
            }

别忘了导入 sqlite3.h

标记

【问题讨论】:

  • TIMEOUT是什么类型的字段?您还可以在您的 sqlite3_prepare_v2 语句之后打印出使用[NSString stringWithUTF8String:sqlite3_errmsg(myDB)] 生成的错误消息。这至少应该告诉你更新调用发生了什么错误。
  • 为什么要给sqlite3_open打两次电话?为什么只关闭其中一个?
  • 所有字段都是文本,除了 _ID 是一个整数

标签: objective-c sqlite sql-update


【解决方案1】:

您只是在准备语句,而不是实际执行它。

执行sqlite3_prepare_v2后需要执行sqlite3_step()

if (sqlite3_prepare_v2(myDB, updateQuery, -1, &stmt, NULL) == SQLITE_OK) {
    if(sqlite3_step(stmt) == SQLITE_DONE) {
        NSLog(@"Query Executed");       
    } else {
        NSLog(@"Query NOT Executed: %s", sqlite3_errmsg(myDB));
    }
    sqlite3_finalize(stmt);

}else{
    NSLog(@"Statement NOT Prepared: %s", sqlite3_errmsg(myDB));
}

【讨论】:

  • 并且你需要在完成准备好的语句后完成它。
  • 好点,但没有完成语句并不能阻止更新行,它只会导致资源泄漏。
  • 向每个else 分支添加对sqlite3_errmsg 的调用,以展示正确的错误日志记录。
  • 我改了。这里的重点不是编写完美的可交付代码,这里的重点是从概念上讲,这是将数据导入数据库所需要的。
  • 是的,但是太多的人(OP 和未来的读者)会简单地复制和粘贴。最好展示一个适当的例子来更好地帮助别人。有太多糟糕的答案导致糟糕的代码。您的答案越好,对未来读者(以及您的声誉)的帮助就越大。
猜你喜欢
  • 1970-01-01
  • 2012-01-25
  • 2016-01-16
  • 1970-01-01
  • 2018-11-02
  • 1970-01-01
  • 1970-01-01
  • 2015-01-25
  • 1970-01-01
相关资源
最近更新 更多