Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在ios上的SQLite数据库中查找条目_Ios_Sqlite - Fatal编程技术网

在ios上的SQLite数据库中查找条目

在ios上的SQLite数据库中查找条目,ios,sqlite,Ios,Sqlite,我遵循了一个关于创建SQLite数据库、存储和查找内容的教程。 我没有做的是创建接口,因为控制台日志记录可以快得多。 (这也不要求其他人构建interace,但别忘了导入库!) 这是一个教程,以备不时之需: 我找不到数据,有人知道它可能是什么吗 - (void) findContact { const char *dbpath = [_databasePath UTF8String]; sqlite3_stmt *statement; if (sqlite3_open

我遵循了一个关于创建SQLite数据库、存储和查找内容的教程。 我没有做的是创建接口,因为控制台日志记录可以快得多。 (这也不要求其他人构建interace,但别忘了导入库!)

这是一个教程,以备不时之需:

我找不到数据,有人知道它可能是什么吗

- (void) findContact {
    const char *dbpath = [_databasePath UTF8String];
    sqlite3_stmt *statement;

    if (sqlite3_open(dbpath, &_contactDB) == SQLITE_OK) {

        NSString *querySQL = [NSString stringWithFormat:
                              @"SELECT adress, phone FROM contacts WHERE name=\"%@\"", @"DoekeW"];

        const char *query_stmt = [querySQL UTF8String];

        if(sqlite3_prepare_v2(_contactDB, query_stmt, -1, &statement, NULL) == SQLITE_OK) {
            if(sqlite3_step(statement) == SQLITE_ROW) {
                NSString *adressField = [[NSString alloc] initWithUTF8String:
                                         (const char*) sqlite3_column_text(statement, 0)];
                NSString *phoneField = [[NSString alloc] initWithUTF8String:
                                        (const char*) sqlite3_column_text(statement, 1)];
                NSLog(@"adressField: %@ phoneField: %@", adressField, phoneField);
            }
            else {
                NSLog(@"no match");
            }
            sqlite3_finalize(statement);
        }
        else {
            // 1, whatever that is
            NSLog(@"hmm %d", sqlite3_prepare_v2(_contactDB, query_stmt, -1, &statement, NULL));
        }
        sqlite3_close(_contactDB);
    }
}
以下是完整的代码:

.h文件:

#import <UIKit/UIKit.h>
#import <sqlite3.h>

@interface IGViewController : UIViewController

@property (strong, nonatomic) NSString *databasePath;
@property (nonatomic) sqlite3 *contactDB;

@end

您在
findContact
中有一个
NSLog
语句,其中说:

NSLog(@"hmm %d", sqlite3_prepare_v2(_contactDB, query_stmt, -1, &statement, NULL));
你肯定不想在失败后再做准备。您只想检索错误消息。因此,它应该是:

NSLog(@"prepare failed: %s", sqlite3_errmsg(_contactDB));
如果这样做,您将收到一条错误消息,指出SQL语句中的
地址拼写错误

坦率地说,实际上每个SQLite调用都应该检查其结果,如果不是
SQLite\u OK
(或者
SQLite\u ROW
或者
SQLite\u DONE
对于
sqlite3\u步骤
)应该报告

当您采用
sqlite3\u errmsg
时,您会更快地发现错误。让SQLite准确地告诉您问题所在


另外,我还建议:

  • 我还建议您不要使用
    stringWithFormat
    构建SQL语句。例如,如果该个人的名字是德韦恩“岩石”约翰逊,您就会遇到问题。相反,您应该使用
    占位符。(您也容易受到SQL注入攻击。)底线,而不是:

    NSString *insertSQL = [NSString stringWithFormat:
                           @"INSERT INTO CONTACTS (name, address, phone) VALUES (\"%@\", \"%@\", \"%@\")",
                           @"DoekeW", @"Molenstraat", @"483577"];
    
    const char *insert_stmt = [insertSQL UTF8String];
    sqlite3_prepare_v2(_contactDB, insert_stmt, -1, &statement, NULL);
    if(sqlite3_step(statement) == SQLITE_DONE) {
        NSLog(@"saved data!");
    }
    else {
        NSLog(@"something wrong, no data saved");
    }
    sqlite3_finalize(statement);
    
    你应使用:

    const char *insert_stmt = "INSERT INTO CONTACTS (name, address, phone) VALUES (?, ?, ?)";
    
    if (sqlite3_prepare_v2(_contactDB, insert_stmt, -1, &statement, NULL) != SQLITE_OK)
        NSLog(@"%s: prepare error: %s", __FUNCTION__, sqlite3_errmsg(_contactDB));
    
    if (sqlite3_bind_text(statement, 1, [@"DoekeW" UTF8String], -1, NULL) != SQLITE_OK)
        NSLog(@"%s: bind 1 error: %s", __FUNCTION__, sqlite3_errmsg(_contactDB));
    
    if (sqlite3_bind_text(statement, 2, [@"Molenstraat" UTF8String], -1, NULL) != SQLITE_OK)
        NSLog(@"%s: bind 2 error: %s", __FUNCTION__, sqlite3_errmsg(_contactDB));
    
    if (sqlite3_bind_text(statement, 3, [@"483577" UTF8String], -1, NULL) != SQLITE_OK)
        NSLog(@"%s: bind 3 error: %s", __FUNCTION__, sqlite3_errmsg(_contactDB));
    
    if(sqlite3_step(statement) == SQLITE_DONE) {
        NSLog(@"saved data!");
    }
    else {
        NSLog(@"%s: step error: %s", __FUNCTION__, sqlite3_errmsg(_contactDB));
    }
    
    sqlite3_finalize(statement);
    
    基本上,使用将值绑定到那些
    占位符,并完全消除
    stringWithFormat
    SELECT
    语句的
    WHERE
    子句也是如此

  • 我支持Anupdas关于使用的建议。它使SQLite编码更加容易


  • 我建议您试用FMDB,使用sqlite要容易得多,而且他们有cocoapods的podspec,所以安装非常简单。极好的
    const char *insert_stmt = "INSERT INTO CONTACTS (name, address, phone) VALUES (?, ?, ?)";
    
    if (sqlite3_prepare_v2(_contactDB, insert_stmt, -1, &statement, NULL) != SQLITE_OK)
        NSLog(@"%s: prepare error: %s", __FUNCTION__, sqlite3_errmsg(_contactDB));
    
    if (sqlite3_bind_text(statement, 1, [@"DoekeW" UTF8String], -1, NULL) != SQLITE_OK)
        NSLog(@"%s: bind 1 error: %s", __FUNCTION__, sqlite3_errmsg(_contactDB));
    
    if (sqlite3_bind_text(statement, 2, [@"Molenstraat" UTF8String], -1, NULL) != SQLITE_OK)
        NSLog(@"%s: bind 2 error: %s", __FUNCTION__, sqlite3_errmsg(_contactDB));
    
    if (sqlite3_bind_text(statement, 3, [@"483577" UTF8String], -1, NULL) != SQLITE_OK)
        NSLog(@"%s: bind 3 error: %s", __FUNCTION__, sqlite3_errmsg(_contactDB));
    
    if(sqlite3_step(statement) == SQLITE_DONE) {
        NSLog(@"saved data!");
    }
    else {
        NSLog(@"%s: step error: %s", __FUNCTION__, sqlite3_errmsg(_contactDB));
    }
    
    sqlite3_finalize(statement);