从sqlite3表中提取数据

当用户试图在同一date(date是主键)进行两个或多个条目时,我试图从特定行中提取数据。

在我的.h文件中

@interface PunchClock : UIViewController{ sqlite3 *db; } -(NSString *) filePath; -(void)openDB; -(void) createTable: (NSString *) tableName withField1:(NSString *) field1 withField2:(NSString *) field2 withField3:(NSString *) field3; 

在我的.m文件(不知道是否需要任何以下的代码来解密我的问题,但是不pipe怎么样都不行)

 -(void) createTable: (NSString *) tableName withField1:(NSString *) field1 withField2:(NSString *) field2 withField3:(NSString *) field3; { char *err; NSString *sql=[NSString stringWithFormat:@" CREATE TABLE IF NOT EXISTS '%@'('%@' TEXT PRIMARY KEY,'%@' TEXT,'%@' TEXT);",tableName,field1,field2,field3]; if(sqlite3_exec(db, [sql UTF8String], NULL, NULL, &err) != SQLITE_OK){ sqlite3_close(db); NSAssert(0, @"Could not create table"); }else{ NSLog(@"table created"); } } -(NSString *) filePath{ NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; NSString *path = [documentsDirectory stringByAppendingPathComponent:@"PunchClock.sql"]; return path; } -(void)openDB{ if(sqlite3_open([[self filePath] UTF8String], &db) != SQLITE_OK){ sqlite3_close(db); NSAssert(0, @"Database failed to open"); }else{ NSLog(@"database opened"); } } 

现在,这是我的问题所在。 我可以成功地插入数据,但当用户input数据在同一date(字段1date,我的主键)我想拉出数据更新和更新表。 我卡在我拉行的数据部分(检查意见澄清):

 - (IBAction)save:(id)sender { { NSString *HoursWorked = [NSString stringWithFormat:@"%f", final]; NSString *TotalEarned = [NSString stringWithFormat:@"%f", paidFloat]; NSString *sql = [NSString stringWithFormat:@"INSERT INTO HourLog ('Date', 'HoursWorked','TotalEarned') VALUES ('%@', '%@', '%@')", dbDate , HoursWorked, TotalEarned]; char *err; if(sqlite3_exec(db, [sql UTF8String], NULL, NULL, &err) != SQLITE_OK){ sqlite3_close(db); // NSAssert(0,@"Could not update table"); //primary key already exists [self openDB]; NSString *currentHoursWorked = HoursWorked; NSString *currentTotalEarned = TotalEarned; NSString *previousHoursWorked; NSString *previousTotalEarned; NSString *sql = [NSString stringWithFormat:@"SELECT FROM HourLog WHERE Date = '%@'", dbDate]; sqlite3_stmt *statement; // the if statement below is not being executed for some reason? Can someone see why? if(sqlite3_prepare_v2(db, [sql UTF8String], -1, &statement, nil)==SQLITE_OK){ char *field2 = (char *) sqlite3_column_text(statement, 1); NSString *field2Str = [[NSString alloc]initWithUTF8String:field2]; previousHoursWorked = field2Str; char *field3 = (char *) sqlite3_column_text(statement, 2); NSString *field3Str = [[NSString alloc]initWithUTF8String:field3]; previousTotalEarned = field3Str; } sqlite3_finalize(statement); sqlite3_close(db); NSLog(@"%@", previousHoursWorked); NSLog(@"%@", previousTotalEarned); }else{ NSLog(@"table updated"); } } } 

一些想法:

  1. 如果你的sqlite3_prepare_v2失败,你不会loggingsqlite3_errmsg ,我会想,因为你没有指定从你的SELECT语句返回哪些字段。

    每当你有一个SQLite错误,你应该确保你正在loggingsqlite3_errmsg

  2. 你也永远不会调用sqlite3_step来实际执行SELECT语句。

  3. 最后, sqlite3_column_text返回从0开始的索引,而不是从1开始的索引,所以第一列是0 ,第二列是1 。 正如文档所说,“结果集的最左边一列的索引为0”。

所以,我会认为你会想要的东西,如:

 // replace column_a and column_b with your column names NSString *sql = [NSString stringWithFormat:@"SELECT column_a, column_b FROM HourLog WHERE Date = '%@'", dbDate]; sqlite3_stmt *statement; if(sqlite3_prepare_v2(db, [sql UTF8String], -1, &statement, nil) == SQLITE_OK){ int rc; if ((rc = sqlite3_step(statement)) == SQLITE_ROW) { char *field2 = (char *) sqlite3_column_text(statement, 0); NSString *field2Str = [[NSString alloc]initWithUTF8String:field2]; previousHoursWorked = field2Str; char *field3 = (char *) sqlite3_column_text(statement, 1); NSString *field3Str = [[NSString alloc]initWithUTF8String:field3]; previousTotalEarned = field3Str; } else if (rc != SQLITE_DONE) { NSLog("%s: sqlite3_step failed: %s", __FUNCTION__, sqlite3_errmsg(db)); } } else { NSLog("%s: sqlite3_prepare_v2 failed: %s", __FUNCTION__, sqlite3_errmsg(db)); } 

顺便说一句,虽然你可以做这个SELECT首先看看是否有匹配,如果你find一个UPDATE ,如果没有,做一个INSERT ,它可能会更容易使用SQLite的INSERT OR REPLACE语法。 请参阅INSERT 文档 。