2013-10-10 22 views
0

我超级新到ios(Objective-C)和sql和我遵循教程的sqlite(特别是sqlite3)在这里找到:http://www.tutorialspoint.com/ios/ios_sqlite_database.htm 和我实现了一切正确。问题是,如果我尝试使用相同的注册ID(用于查找数据库中的元素的主键)输入信息,它会抱怨密钥不唯一。如何更新sqlite3中的条目?

- (BOOL) saveData:(NSString*)registerNumber name:(NSString*)name 
    department:(NSString*)department year:(NSString*)year; 
    { 
    const char *dbpath = [databasePath UTF8String]; 
    if (sqlite3_open(dbpath, &database) == SQLITE_OK) 
    { 
     NSString *insertSQL = 
     [NSString stringWithFormat:@"insert into studentsDetail (regno,name, department, year) values (\"%d\",\"%@\", \"%@\", \"%@\")",[registerNumber integerValue], name, department, year]; 

     const char *insert_stmt = [insertSQL UTF8String]; 
     sqlite3_prepare_v2(database, insert_stmt,-1, &statement, NULL); 
     int s = sqlite3_step(statement); 
     const char *errmsg = sqlite3_errmsg(database); 
     if (s == SQLITE_DONE) 
     { 
      sqlite3_reset(statement); 
      return YES; 
     } 
     else { 
      sqlite3_reset(statement); 
      return NO; 
     } 
    } 
    return NO; 
} 

我如何去制作SAVEDATA:动作实际更新数据库中的条目,而不只是被拒绝? 谢谢!

+0

数字值不报价走。而字符串值必须使用单引号,而不是双引号。但更重要的是,不要使用'stringWithFormat'来构建查询。正确地使用'sqlite3_bind_xxx'绑定这些值。 – rmaddy

+1

您还需要关闭数据库,因为每次都打开它。你也应该完成这个陈述。没有必要重置语句,因为您没有重复使用它们。您还需要检查'sqlite3_prepare_v2'的返回值。使用'sqlite3_errmsg()'检查任何失败的调用。 – rmaddy

+0

@rmaddy代码的工作原本就是为了引入一个简单的sql数据库结构,但我想扩展它,这样如果我尝试输入一个现有的reg id,它将用新的覆盖剩下的属性。我看看使用绑定函数,但在格式方面,我相当肯定,对于obj-c,我使用正确的语法来处理字符串和数字,但如果我错了,请纠正我的错误。 – CoderNinja

回答

0

“我希望把它扩大,这样如果我尝试进入现有的REG ID,它 会用新的覆盖其余属性”

如果这是您要完成那么你不应该使用INSERT语句。主键的作用是用相同的主键保护数据库不受重复行的影响。当你这样看时,拒绝是合适的。

你真正想要的是使用INSERT OR REPLACE

如果你是一个初学者到SQL和客观的C,我建议我创建的是针对初学者的一个SQLite包装:TankDB

编辑:

代码示例:

插入或更换INTO studentsDetail(REGNO,姓名,部门,年份)值(\ “%d \”,\ “%@ \”,\ “%@ \” ,\“%@ \”)“

请参阅this question以确保您实际上并不想使用'UPSERT'。请注意,INSERT OR REPLACE不会使用新信息更新现有行。它会完全删除现有的行并将其替换。

EDIT2:打开,准备工序,最终确定,关闭

const char *dbpath = [_databasePath UTF8String]; 
if(sqlite3_open(dbpath, &_database) == SQLITE_OK) { 
    const char *command = [query UTF8String]; 

    // Perform the query 
    if (sqlite3_prepare_v2(_database, command, -1, &selectstmt, NULL) == SQLITE_OK) { 

     // For each row returned 
     while (sqlite3_step(selectstmt) == SQLITE_ROW) { 
      // Do stuff 
     } 
    } 
    sqlite3_finalize(selectstmt); 
} 

sqlite3_close (_database); 
+0

我如何更改我的代码以便它使用REPLACE? insert_stmt? – CoderNinja

+0

用正确的语法编辑答案。 – jnortey

+0

如果INSERT OR REPLACE只是删除并重新插入,主键会改变,但除此之外,功能是一样的吗?这正是我所期待的,谢谢帮助我意识到我在做错什么 – CoderNinja