【问题标题】:Insert Query not working (FMDB)插入查询不起作用(FMDB)
【发布时间】:2015-06-05 15:27:56
【问题描述】:

这是我用来将记录插入到 sqlite 表中的代码

FMDatabase *dataBase = [self openDatabase];
    [dataBase open];
    if ([dataBase open] != YES) {
        NSLog(@"DB Error %d: %@", [dataBase lastErrorCode], [dataBase lastErrorMessage]);
    //VERY IMPORTANT
    }

    BOOL success= [dataBase executeUpdate:@"Insert into CrewUnits (pkCrewUnits,fkUnits,fkAgencyVehicles,fkLookupCodes_PrimaryRole, fkLookupCodes_LevelOfCare, PrimaryUnit) values (?, ?, ?, ?, ?, ?);", pkCrewUnits, fkUnits, fkAgencyVehicle, fkLookupCodes_PrimaryRole, fkLookupCodes_LevelOfCare, [NSNumber numberWithInt:1]];
    NSLog(success ?@"YES" :@"NO");
     NSLog(@"Error %d: %@", [dataBase lastErrorCode], [dataBase lastErrorMessage]);
   FMResultSet*resultSet= [dataBase executeQuery:@"select * from CrewUnits"];
    NSLog(@"ResultSet : %@", [resultSet resultDictionary]);

    [dataBase close];

数据库路径

- (FMDatabase *)openDatabase
{

    NSLog(@"Open Database");
    NSString *documents_dir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString *db_path = [documents_dir stringByAppendingPathComponent:[NSString stringWithFormat:@"HPSix_05BD.db"]];    // DatabasePath
    FMDatabase *db = [FMDatabase databaseWithPath:db_path];
    if (![db open])
        NSLog(@"Failed to open database!!!!!");
    return db;
}

我使用相同的逻辑从适合我的表中获取数据。但我无法插入记录。我不知道我在这里做错了什么。

【问题讨论】:

  • 您是否收到错误或异常? pkCrewUnits、fkUnits、fkAgencyVehicle、fkLookupCodes_PrimaryRole、fkLookupCodes_LevelOfCare 都是对象而不是简单类型吗?
  • 错误 0:不是错误
  • 它们实际上是 GUID,因为 sqlite 不支持 GUID,它们是字符串。 @edwardmp

标签: ios sqlite fmdb


【解决方案1】:

两个问题:

  1. 您拨打了三遍open。一次在openDatabase 中,两次在调用它的代码中。

    所以,如果可以,让您的 open 例程打开数据库,但如果不能,则返回 nil

    - (FMDatabase *)openDatabase
    {
        NSLog(@"Open Database");
        NSString *documents_dir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
        NSString *db_path = [documents_dir stringByAppendingPathComponent:[NSString stringWithFormat:@"HPSix_05BD.db"]];    // DatabasePath
        FMDatabase *db = [FMDatabase databaseWithPath:db_path];
        if (![db open]) {
            NSLog(@"Failed to open database!!!!!");
            return nil;
        }
        return db;
    }
    

    然后检查结果:

    FMDatabase *dataBase = [self openDatabase];
    if (!dataBase) {
        // quit; note, no point in checking error message as it only returns meaningful messages if you have an open database
    }
    
  2. 调用executeQuery后,必须调用next

    FMResultSet *resultSet = [dataBase executeQuery:@"select * from CrewUnits"];
    if ([resultSet next]) {
        NSLog(@"ResultSet : %@", [resultSet resultDictionary]);
    } else {
        NSLog(@"No data found");
    }
    

【讨论】:

    【解决方案2】:

    我想我看到了问题所在。您在运行 SELECT 查询后提交。

    您必须在 UPDATE 查询之后立即提交。当您像现在选择时那样执行此操作时,UPDATE 查询尚未提交,因此不会返回。

    [dataBase beginTransaction];
    BOOL success= [dataBase executeUpdate:@"Insert into CrewUnits (pkCrewUnits,fkUnits,fkAgencyVehicles,fkLookupCodes_PrimaryRole, fkLookupCodes_LevelOfCare, PrimaryUnit) values (?, ?, ?, ?, ?, ?);", pkCrewUnits, fkUnits, fkAgencyVehicle, fkLookupCodes_PrimaryRole, fkLookupCodes_LevelOfCare, [NSNumber numberWithInt:1]];
    [dataBase commit]; // commit the query
    NSLog(success ?@"YES" :@"NO");
    NSLog(@"Error %d: %@", [dataBase lastErrorCode], [dataBase lastErrorMessage]);
    // now at this point the transaction has been committed and can be selected
    FMResultSet*resultSet= [dataBase executeQuery:@"select * from CrewUnits"];
    NSLog(@"ResultSet : %@", [resultSet resultDictionary]);
    

    还有according to FMDB docs:

    参数必须以冒号开头。 SQLite 本身支持其他 字符,但在内部字典键带有前缀 冒号,不要在字典键中包含冒号。

    因此这行代码必须重写为:

    BOOL success= [dataBase executeUpdate:@"Insert into CrewUnits (pkCrewUnits,fkUnits,fkAgencyVehicles,fkLookupCodes_PrimaryRole, fkLookupCodes_LevelOfCare, PrimaryUnit) values (:pkCrewUnits,:fkUnits,:fkAgencyVehicles,:fkLookupCodes_PrimaryRole, :fkLookupCodes_LevelOfCare, :PrimaryUnit);", pkCrewUnits, fkUnits, fkAgencyVehicle, fkLookupCodes_PrimaryRole, fkLookupCodes_LevelOfCare, [NSNumber numberWithInt:1]];
    

    最后根据您使用next 循环结果的文档:

    while ([resultSet next]) {
        //retrieve values for each record
    }
    

    【讨论】:

    • 我也试过了。我的错误日志是 Error 0: not an error
    • 提及您当时的尝试并停止浪费人们的时间。文档指定了这一点,所以你在做什么似乎是错误的
    • FWIW,SQL 中的 ? 占位符很好。 FMDB 也支持以冒号为前缀的参数与参数字典相结合,但 OP 的原始简单 ? 具有值数组的占位符也非常好(而且更可取,恕我直言)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-19
    • 1970-01-01
    • 1970-01-01
    • 2018-11-28
    相关资源
    最近更新 更多