有人能看到我的sql prepare语句的问题吗?

时间:2013-10-30 22:48:18

标签: ios sqlite

大家阿罗哈,

我正在重写我的一些应用程序,这次是使用故事板和iOS 7编码。因此,我有兴趣从头开始。基本上,这些是从SQLite数据库中提取单词及其定义的应用程序,在表格视图中显示单词,然后允许用户点击单词以在另一个视图控制器中查看其定义。我的问题是,虽然我可以打开数据库,但我从未通过sql prepare语句。这是代码:

    - (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.

    // Set up the database variable
    databaseName = @"MilSpeak.db";

    // Get the path to the documents directory and append the database
    NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDir = [documentPaths objectAtIndex:0];
    databasePath = [documentsDir stringByAppendingPathComponent:databaseName];
    NSLog(@"databasePath returns: %@", databasePath);


    // Execute the "checkDatabaseStatus" method
    [self checkDatabaseStatus];


    // Query the database for all object records and construct the navyTerms array
    [self runDatabaseQuery];

}

    - (void)checkDatabaseStatus {
    // Create a File Manager object to check the status of the database
    NSFileManager *fileManager = [NSFileManager defaultManager];
    if ([fileManager fileExistsAtPath:databasePath] == YES) {
        NSLog(@"Database exists");
    }
}

    - (void)runDatabaseQuery {
    // Set up the database object

    // Initialize the navyTerms array
    wordArray = [[NSMutableArray alloc] init];
    definitionArray = [[NSMutableArray alloc] init];

    // Open the database from the device's filesystem
    if (sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
        NSLog(@"Opening the database for SQL pull");

        // Set up the SQL statement and compile if for faster access
        const char *sqlStatement = "select * from terms where usn = 'Y' or usn = 'y' order by word asc";
        sqlite3_stmt *compiledStatement;

        if (sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
            // Loop through the results and add them to wordArray and definitionArray
            NSLog(@"Stepping through the database rows");
            while (sqlite3_step(compiledStatement) == SQLITE_ROW) {
                // Read the database from the resulting row(s)
                NSString *aWord = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
                NSString *aDefinition = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];

                // Populate the arrays with the values from the database pulls
                [wordArray addObject:aWord];
                NSLog(@"word: %@", aWord);
                [definitionArray addObject:aDefinition];
            }
        }
        else {
            NSLog(@"There is a problem with the sqlite3_prepare_v2 statement.");
        }
        // Release the compiled statement from memory
        sqlite3_finalize(compiledStatement);

        // Count the contents of the database arrays
        NSLog(@"wordArray contains %lu items", (unsigned long)[wordArray count]);
        NSLog(@"definitionArray contains %lu items", (unsigned long)[definitionArray count]);
        allTerms = [NSDictionary dictionaryWithObjects:wordArray
                                               forKeys:definitionArray];
        NSLog(@"allTerms contains %lu items", (unsigned long)[allTerms count]);
    }

    // Close the database
    sqlite3_close(database);
}

我不确定代码的粘贴(结束大括号)发生了什么,但它就在那里,我知道数据库存在且有条目 - 我用终端来调用条款表的内容

showing terminal access to the database - 4714 entries

第一个号码是一个自动号码,所以我应该在我的表格视图中看到4,714个条目。更重要的是,如果你看一下runDatabaseQuery方法的代码,你会倾向于使用大量的日志语句来检查某些条件。我把一个作为其他的东西放到sql prepare if语句中,这就是触发的内容。

Logs from a sample run

出于某种原因,我的应用程序不喜欢该声明。如果有人能给我任何帮助来解决这个问题,我将永远感激不尽。提前感谢任何回复。

在另一位用户的建议之后,我输入了一个sql_error语句。这是新的runDatabaseQuery方法:

- (void)runDatabaseQuery {
    // Set up the database object

    // Initialize the navyTerms array
    wordArray = [[NSMutableArray alloc] init];
    definitionArray = [[NSMutableArray alloc] init];

    // Open the database from the device's filesystem
    if (sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
        NSLog(@"Opening the database for SQL pull");

        // Set up the SQL statement and compile if for faster access
        const char *sqlStatement = "select * from terms where usn = 'Y' or usn = 'y' order by word asc";
        sqlite3_stmt *compiledStatement;

        if (sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
            // Loop through the results and add them to wordArray and definitionArray
            NSLog(@"Stepping through the database rows");
            while (sqlite3_step(compiledStatement) == SQLITE_ROW) {
                // Read the database from the resulting row(s)
                NSString *aWord = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
                NSString *aDefinition = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];

                // Populate the arrays with the values from the database pulls
                [wordArray addObject:aWord];
                NSLog(@"word: %@", aWord);
                [definitionArray addObject:aDefinition];
            }
        }
        else {
            NSLog(@"There is a problem with the sqlite3_prepare_v2 statement.");
            NSLog(@"%s SQLITE_ERROR '%s' (%1d)", __FUNCTION__, sqlite3_errmsg(database), sqlite3_errcode(database));
        }
        // Release the compiled statement from memory
        sqlite3_finalize(compiledStatement);

        // Count the contents of the database arrays
        NSLog(@"wordArray contains %lu items", (unsigned long)[wordArray count]);
        NSLog(@"definitionArray contains %lu items", (unsigned long)[definitionArray count]);
        allTerms = [NSDictionary dictionaryWithObjects:wordArray
                                               forKeys:definitionArray];
        NSLog(@"allTerms contains %lu items", (unsigned long)[allTerms count]);
    }

    // Close the database
    sqlite3_close(database);
}

结果日志语句毫无意义。此数据库中只有一个表,名为terms,但显然,我的app无法识别表:

log statements from sample run

我使用了终端并获得了以下内容:

terminal verification of terms table in database

所以我很困惑这里到底发生了什么。任何和所有帮助将不胜感激。

我遵循了@ maddy关于更改sql open语句的建议:

if (sqlite3_open_v2([databasePath UTF8String], &database, SQLITE_OPEN_READONLY, NULL) == SQLITE_OK) {

仍然得到了相同的结果。在viewDidLoad和checkDatabaseStatus方法中,我试图验证数据库是否在正确的位置,但也许我没有正确地执行此操作。我将再次回顾代码,看看我可能错过了什么。

1 个答案:

答案 0 :(得分:0)

我不确定发生了什么,但现在可行了。我稍微调整了checkDatabaseStatus方法,添加了一个复制命令以确保数据库在正确的位置。那段代码在这里:

    - (void)checkDatabaseStatus {
    // Create a File Manager object to check the status of the database
    NSFileManager *fileManager = [NSFileManager defaultManager];
    // Get the path to the database in the application package
    NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:databaseName];

    if ([fileManager fileExistsAtPath:databasePathFromApp] == YES) {
        NSLog(@"Database exists");
    }
    else {
        NSLog(@"Dude, where's my database?");
    }

    // Copy in the database from the application package
    [fileManager copyItemAtPath:databasePathFromApp
                         toPath:databasePath
                          error:nil];
    if ([fileManager fileExistsAtPath:databasePath] == YES) {
        NSLog(@"Database exists");
    }
    else {
        NSLog(@"Dude, again, where's my database?");
    }
}

再次感谢Maddy。您对数据库位置的问题可能就是这样做的,但现在它运行得很好! (至少到目前为止:D)我现在必须弄清楚我想对所有数据做些什么。