Ios SQLite电话簿插入失败

Ios SQLite电话簿插入失败,ios,sqlite,Ios,Sqlite,在下面的代码中,注释掉的代码有效 但是使用DBMgr类的saveData方法会导致“添加联系人失败” 我想看到“联系人添加”代替 您应该检查所有SQLite调用的结果代码,如果失败,请记录错误: - (NSInteger) saveData:(NSString *) querySQL{ NSInteger result = 1; sqlite3_stmt *statement; const char *dbpath = [databasePath UTF8String];

在下面的代码中,注释掉的代码有效

但是使用
DBMgr
类的
saveData
方法会导致“添加联系人失败”

我想看到“联系人添加”代替


您应该检查所有SQLite调用的结果代码,如果失败,请记录错误:

- (NSInteger) saveData:(NSString *) querySQL{
    NSInteger result = 1;
    sqlite3_stmt *statement;
    const char *dbpath = [databasePath UTF8String];

    if(sqlite3_open(dbpath, &contactDB) == SQLITE_OK)
    {
        NSString *insertSQL = querySQL;

        const char *insert_stmt = [insertSQL UTF8String];

        if (sqlite3_prepare_v2(contactDB, insert_stmt, -1, &statement, NULL) != SQLITE_OK)
            NSLog(@"%s: prepare failed: %s", __FUNCTION__, sqlite3_errmsg(contactDB));
        else
        {
            if(sqlite3_step(statement) == SQLITE_DONE)
            {
                result = 0;
            }else{
                NSLog(@"%s: step failed: %s", __FUNCTION__, sqlite3_errmsg(contactDB));
            }
            sqlite3_finalize(statement);
        }

        sqlite3_close(contactDB);
    } else {
        NSLog(@"%s: open failed", __FUNCTION__);
    }

    return result;
}
除非您查看
sqlite3\u errmsg
,否则您只是在猜测。并检查
sqlite3\u prepare\u v2
返回代码,就像我上面所做的那样(因为这很可能是问题的初始迹象)


另外两个无关的观察结果:

  • 应初始化
    DBMgr
    ,例如:

    DBMgr *dbmgr = [[DBMgr alloc] init];
    
  • 您正在使用
    stringWithFormat
    构建
    INSERT
    语句。这非常危险,您应该在SQL中使用
    占位符:

    const char *insSQL = "INSERT INTO CONTACTS (name,address,phone) VALUES (?, ?, ?)";
    sqlite3_prepare_v2(contactDB, insSQL, -1, &statement, NULL);
    
    然后,在准备好该语句后,您应该使用该函数将值分配给这三个占位符,例如

    sqlite3_bind_text(statement, 1, [name.text    UTF8String], -1, SQLITE_TRANSIENT);
    sqlite3_bind_text(statement, 2, [address.text UTF8String], -1, SQLITE_TRANSIENT);
    sqlite3_bind_text(statement, 3, [phone.text   UTF8String], -1, SQLITE_TRANSIENT);
    
    顺便说一下,如果要指定
    NULL
    ,可以调用
    sqlite3\u bind\u NULL
    ,而不是
    sqlite3\u bind\u text

    显然,请检查每个返回代码,以确保您为每个返回了
    SQLITE\u OK
    ,如果失败,请再次记录
    sqlite3\u errmsg

    我知道这一更改需要对代码进行一些重构,但使用
    sqlite3\u bind\u text
    避免SQL注入攻击和错误非常重要,因为如果用户键入包含引号的值,就会导致这些攻击和错误


  • 顺便说一下,如果你在上面查看并意识到需要大量的代码来正确地完成这项工作,你可能需要考虑使用它可以显著简化你的生活。

    我不知道什么是<代码> DBMgr < /Cord>类,但是也许你需要做代码> dBMGR*dBMGR= [[dBMGR OLLC] init ];<代码>而不仅仅是
    alloc
    .thx!!我解决了这个问题!!!!!原因是..

    -(void)initDB:(NSString*)dbPath:(sqlite3*)contDB{
    self.databasePath=dbPath;
    self.contactDB=contDB;
    }
    我很高兴你解决了你的问题。顺便说一句,别忘了调用
    [super init]
    sqlite3_bind_text(statement, 1, [name.text    UTF8String], -1, SQLITE_TRANSIENT);
    sqlite3_bind_text(statement, 2, [address.text UTF8String], -1, SQLITE_TRANSIENT);
    sqlite3_bind_text(statement, 3, [phone.text   UTF8String], -1, SQLITE_TRANSIENT);