FMDB:添加新列并插入数据

Saw*_*san 7 sqlite objective-c fmdb

在我的应用程序中,我正在使用FMDatabase.我正在尝试向该列添加新column的现有数据,table然后添加insert数据.当我添加列时Alter Table,我没有错误,但是当我尝试在表中插入数据时,我收到错误抱怨新添加的列不存在.

这是我的代码

NSString *databasePath = [myDB getPlacesDBPath];

FMDatabase *db = [FMDatabase databaseWithPath:databasePath];

if (![db open])
{
    return ;
}

if (![db columnExists:@"placeName" inTableWithName:@"MYPLACES"])
{
    [db executeQuery:@"ALTER TABLE MYPLACES ADD COLUMN placeName TEXT"];
    // I tried to set the result of this query in "BOOL Success" and print the results and I got YES    
}

//Note: I have more than 12 columns but I didn't post all of them here
NSString *insertSQL = [NSString stringWithFormat: @"INSERT INTO  MYPLACES  ( placeID ,  placeName)  VALUES (\"%@\", \"%@\")", placeIDValue, placeNameValue ];

[db executeUpdate:insertSQL];

if ([db hadError]) {
    NSLog(@"error : %@",[db lastError]);
}

[db close];
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

error : Error Domain=FMDatabase Code=1 "table MYPLACES has no column named placeName" UserInfo=0xe340920 {NSLocalizedDescription=table MYPLACES has no column named placeName}
Run Code Online (Sandbox Code Playgroud)

有什么问题?如何知道为什么没有添加新列?

Rob*_*Rob 14

我在上面的简化代码示例中没有看到任何内容来解释您报告的错误.问题可能在其他地方(或者,在简化代码示例的过程中,您消除了问题的根源).

话虽如此,我有几个反应:

  1. 你说:

    我尝试在"BOOL Success"中设置此查询的结果并打印结果,我得到了YES

    我不知道那是怎么可能的,因为executeQuery返回的FMResultSet不是a BOOL.但是,这是没有意义的,因为你的ALTER TABLE陈述应该executeUpdate没有executeQuery.(后者应该仍然有效,但前者更合乎逻辑.)

  2. 我不明白为什么你删除了错误检查.这是识别问题的最佳方式.

  3. 完全不相关,但stringWithFormat在构建SQL时不应该使用.您可以打开由于意外输入导致的SQL失败(例如,如果您的某个值在其中有双引号,那该怎么办).更糟糕的是,你暴露自己的SQL注入攻击.相反,?在SQL中使用占位符,然后将值作为参数传递给executeUpdate(或executeQuery)方法.

所以,以下代码对我来说很好:

BOOL success;

FMDatabase *db = [FMDatabase databaseWithPath:databasePath];

if (![db open])
{
    NSLog(@"open failed");
    return;
}

if (![db columnExists:@"placeName" inTableWithName:@"MYPLACES"])
{
    success = [db executeUpdate:@"ALTER TABLE MYPLACES ADD COLUMN placeName TEXT"];
    NSAssert(success, @"alter table failed: %@", [db lastErrorMessage]);
}

NSString *insertSQL = @"INSERT INTO  MYPLACES  (placeID, placeName)  VALUES (?, ?)";
success = [db executeUpdate:insertSQL, placeIDValue, placeNameValue];
NSAssert(success, @"insert failed: %@", [db lastErrorMessage]);

[db close];
Run Code Online (Sandbox Code Playgroud)

由于我没有看到会导致您描述的问题的原因,我只建议您在调试器中单步执行此代码并确保它遵循您认为的路径.