Objective c FMDB:添加新列并插入数据
在我的应用程序中,我正在使用Objective c FMDB:添加新列并插入数据,objective-c,sqlite,fmdb,Objective C,Sqlite,Fmdb,在我的应用程序中,我正在使用FMDatabase。我试图将新的列添加到现有的表,然后在该列中插入数据。当我通过altertable添加列时,我没有收到任何错误,但是当我尝试在表中插入数据时,我收到错误,抱怨新添加的列不存在 这是我的密码 NSString *databasePath = [myDB getPlacesDBPath]; FMDatabase *db = [FMDatabase databaseWithPath:databasePath]; if (![db open]) {
FMDatabase
。我试图将新的列
添加到现有的表
,然后在该列中插入数据。当我通过altertable
添加列时,我没有收到任何错误,但是当我尝试在表中插入数据时,我收到错误,抱怨新添加的列不存在
这是我的密码
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];
我得到了以下错误:
error : Error Domain=FMDatabase Code=1 "table MYPLACES has no column named placeName" UserInfo=0xe340920 {NSLocalizedDescription=table MYPLACES has no column named placeName}
有什么问题吗?如何知道为什么不添加新列?我在上面的简化代码示例中看不到任何东西可以解释您报告的错误。问题可能存在于其他地方(或者,在简化代码示例的过程中,您消除了问题的根源)
话虽如此,我还是有一些反应:
你说:
我试图将这个查询的结果设置为“BOOL Success”并打印结果,结果是肯定的
我不知道怎么可能,因为executeQuery
返回的是FMResultSet
而不是BOOL
。不过,这是没有意义的,因为您的altertable
语句应该使用executeUpdate
而不是executeQuery
执行。(后者应该仍然有效,但前者更符合逻辑。)
我不明白你为什么删除错误检查。这是确定问题的最佳方式
完全不相关,但在构建SQL时不应使用stringWithFormat
。您可能会遇到由于意外输入而导致的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];
由于我不知道是什么导致了您描述的问题,我只能建议您在调试器中单步执行此代码,并确保它遵循您认为的路径。Swift 3代码:
let db = FMDatabase(path: Util.getPath(databasePath)
guard db != nil else { return }
db!.open()
if !(db!.columnExists("tableName", columnName: "USERID")) {
let alterTable = "ALTER TABLE tableName ADD COLUMN USERID TEXT"
if db!.executeUpdate(alterTable, withArgumentsIn: nil) {
printf(“new column added”)
}
else {
printf(“issue in operation”)
}
db!.close()
可能有人需要帮助。
继续编码..问题在于-[FMDatabase executeQuery:]不执行提交的指令,它只准备语句
要执行它们,您需要执行“步骤”
在FMDB中,由-[FMResultSet next]在内部通过调用sqlite3_步骤()完成
因为-executeUpdate:(与-executeQuery:)为您完成这项工作并完成语句,所以它可能更适合于此目的
因此,如果您确实需要使用-executeQuery:
FMResultSet *rs = [db executeQuery:@"ALTER TABLE MYPLACES ADD COLUMN placeName TEXT"];
[rs nextWithError:&error]; // error handling is recommended here
[rs close];
但是-executeUpdate:更简洁吗
BOOL success = [db executeUpdate:@"ALTER TABLE MYPLACES ADD COLUMN placeName TEXT"];
谢谢你清晰、有条理、简单的回答。我不知道到底是什么问题,但使用executeUpdate而不是executeQuery解决了问题。