我使用以下语句创建了一个sqlite表:
"CREATE TABLE IF NOT EXISTS reminders (ID INTEGER PRIMARY KEY,Name VARCHAR(64), Event VARCHAR(64), Date VARCHAR(64), Bfr VARCHAR(64), Val VARCHAR(64),Num VARCHAR(64), Bod VARCHAR(400) ,Grp VARCHAR(64))";
我已成功从sqlite数据库中插入数据和检索数据,并以编程方式在视图提醒中显示提醒!
但是我对从sqlite数据库删除记录感到震惊。我的意思是我使用了一个模型类来保存名称,事件,日期等值......在添加提醒页面时,我已经为变量分配了值在模型类中声明,即
textField.text = remClass.Name等..
我的描述可能听起来令人困惑,但上述信息对于轻松回答这个问题总是有用的。
我添加了提醒页面,用户输入数据并单击保存,然后将数据插入到数据库中。在“查看提醒”页面中,用户可以查看已保存的提醒。有三种不同的方式可以查看提醒: viewAll,viewMonthly,viewGroup.Now在视图中我可以使用以下语句显示每个提醒的唯一ID:
ReminderClass *loadedReminder = [[ReminderClass alloc] init];
loadedReminder.reminderID = sqlite3_column_int(statement, 0);
其中提醒类是一个模型类,它包含在添加提醒页面中输入的所有值。
为了显示保存的提醒,我使用了一个数组并在检索每一行后添加了模型类对象,即。 id,名称,事件,日期等。并相应地填充表视图。如果我保存3个提醒,那么部分是3个明智的等等......
现在,如果我单击视图组提醒页面中的编辑按钮,那么我们就知道可以通过单击左侧的方向按钮来删除表格视图的行(部分)。
如果我删除了该行,请说出一行提醒。然后还应该从sqlite数据库中删除与该提醒相对应的数据。
我怎么能这样做,我已经完成了类似于我的要求的link声音。但是它不起作用。
最后,我实现了以下代码进行删除:
if (editingStyle == UITableViewCellEditingStyleDelete)
{
[self.grpArray objectAtIndex:indexPath.section];
if(sqlite3_open([databasePath UTF8String], &remindersDB)==SQLITE_OK)
{
sqlite3_stmt *compiledstatement;
int pk = sqlite3_column_int(compiledstatement, 0);
NSString *querySQL = [NSString stringWithFormat:@"delete from reminders where ID = %i",pk];
const char *sqlstmt=[querySQL UTF8String];
if(sqlite3_prepare_v2(remindersDB, sqlstmt, -1, &compiledstatement, NULL)==SQLITE_OK)
{
if(SQLITE_DONE != sqlite3_step(compiledstatement))
NSAssert1(0,@"Error while creating delete statement => %s",sqlite3_errmsg(remindersDB));
}
NSLog(@"delete DONE");
sqlite3_finalize(compiledstatement);
}
sqlite3_close(remindersDB);
[self.gTable reloadData];
}
检索代码:
-(void)loadgReminders
{
EventsReminderAppDelegate *appDelegate = (EventsReminderAppDelegate *)[[UIApplication sharedApplication]delegate];
NSLog(@"String = %@",appDelegate.groupString);
self.grpArray = nil;
self.grpArray = [[NSMutableArray alloc]init];
//Retrieve the group of reminder
const char *thePath = [self.databasePath UTF8String];
sqlite3_stmt *statment;
if (sqlite3_open(thePath, &remindersDB) == SQLITE_OK)
{
NSString *getQuery = [NSString stringWithFormat:@"SELECT * FROM reminders WHERE Grp = '%@' ORDER BY Date ASC",appDelegate.groupString];
const char *sqlite_stmt = [getQuery UTF8String];
if (sqlite3_prepare_v2(self.remindersDB, sqlite_stmt, -1, &statment, NULL) == SQLITE_OK)
{
while (sqlite3_step(statment) == SQLITE_ROW)
{
ReminderClass *remind = [[ReminderClass alloc]init];
remind.reminderID = sqlite3_column_int(statment, 0);
**NSLog(@"reminderID=%d",remind.reminderID);**
remind.Name = [[NSString alloc]initWithUTF8String:(const char *)sqlite3_column_text(statment, 1)];
remind.Event = [[NSString alloc]initWithUTF8String:(const char *)sqlite3_column_text(statment, 2)];
remind.Date = [[NSString alloc]initWithUTF8String:(const char *)sqlite3_column_text(statment, 3)];
remind.numDays = [[NSString alloc]initWithUTF8String:(const char *)sqlite3_column_text(statment, 4)];
remind.selString = [[NSString alloc]initWithUTF8String:(const char *)sqlite3_column_text(statment, 5)];
remind.number = [[NSString alloc]initWithUTF8String:(const char *)sqlite3_column_text(statment, 6)];
remind.msgBody = [[NSString alloc]initWithUTF8String:(const char *)sqlite3_column_text(statment, 7)];
remind.remGroup = [[NSString alloc]initWithUTF8String:(const char *)sqlite3_column_text(statment, 8)];
NSDateFormatter *dateFormat = [[[NSDateFormatter alloc]init]autorelease];
[dateFormat setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
NSDate *date = [dateFormat dateFromString:remind.Date];
[dateFormat setDateFormat:@"MMMM dd"];
NSString *dateVal = [dateFormat stringFromDate:date];
remind.Date = dateVal;
[self.grpArray addObject:remind];
[remind release];
}
sqlite3_finalize(statment);
}
sqlite3_close(remindersDB);
}
}
我使用NSLog来检查提醒ID值是否正确显示是否显示为:
但是当我尝试使用删除来检索id值并将id值分配给id =?时,出了什么问题。
它不起作用,我错在哪里?
任何人都可以帮帮我吗?
答案 0 :(得分:2)
编辑:
阅读评论后,您似乎遇到了将内存提醒(ID)与要删除的数据库中的ID对齐的问题。数组索引不一定对应。当您使用insert语句创建提醒时,您必须立即跟随该调用,并调用sqlite3_last_insert_rowid,因为它已生成。然后为它分配模型类reminderId。然后在删除中,只需阅读reminderId即可撰写删除语句。再一次,请记录一切。
http://www.sqlite.org/capi3ref.html#sqlite3_last_insert_rowid
插入后,如果您选择了提醒列表,请确保选择id列并指定给模型提示符,以便知道要删除的内容。在insert和select情况下,您需要确保最终模型reminderId等于db中生成的id。
INITIAL:
从代码中看起来你正在使用编译语句(这很好),这意味着你调用prepare并保存编译后的语句以便重用。如果您正在重用(无法查看所有代码),请确保在其上调用sqlite3_reset。此外,如果您正在重复使用,则在完全使用它之前,不应该最终确定它。
如果这不是问题,请从注销pk和编写的sql语句开始。确保它符合您的期望。例如,如果它是0并且你说删除pk = 0,那么它不会失败 - 它不会做任何事情,因为没有id为0的行(从1开始)。
之后,尝试使用sqlite3命令行中的相同语句。您可以注销模拟器正在使用的路径。
另外,注销返回代码(只是不要检查SQLITE_DONE。除了错误消息我提供了一个提示。
希望其中一个人指出你正确的方向。
答案 1 :(得分:1)
你可以这样做。这肯定会成功
if (editingStyle == UITableViewCellEditingStyleDelete)
{
NSString *dbPath = [self getDBPath];
NSString *couponIdValue = [listOfCouponId objectAtIndex:indexPath.row];
if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) {
const char *sql = "delete from reminders where ID = ?";
sqlite3_stmt *deletestmt;
if(sqlite3_prepare_v2(database, sql, -1, &deletestmt, NULL) != SQLITE_OK) {
NSAssert1(0, @"Error while creating delete statement. '%s'", sqlite3_errmsg(database));
}
sqlite3_bind_int(deletestmt, 1, [IdValue intValue]);
if (SQLITE_DONE != sqlite3_step(deletestmt))
NSAssert1(0, @"Error while deleting. '%s'", sqlite3_errmsg(database));
sqlite3_reset(deletestmt);
}
在sqlite3_bind_int()方法中传递id的值。