在sqlite DB中获取错误错误:ios 8中的未知错误

时间:2015-08-13 17:18:34

标签: ios objective-c sqlite appdelegate

我正在使用sqlite DB来保存数据。我希望保存应用程序的应用程序状态生命周期。因为我使用sqlite .i创建了两个列的表。我也能保存数据。但有一段时间我收到此错误DB错误:未知错误。

**DB Error: unknown error**

无法执行查询。

-(void)executeQuery:(NSString *)query{
    // Run the query and indicate that is executable.
    [self runQuery:[query UTF8String] isQueryExecutable:YES];
}


-(void)runQuery:(const char *)query isQueryExecutable:(BOOL)queryExecutable{
    // Create a sqlite object.
    sqlite3 *sqlite3Database;

    // Set the database file path.
    NSString *databasePath = [self.documentsDirectory stringByAppendingPathComponent:self.databaseFilename];

    // Initialize the results array.
    if (self.arrResults != nil) {
        [self.arrResults removeAllObjects];
        self.arrResults = nil;
    }
    self.arrResults = [[NSMutableArray alloc] init];

    // Initialize the column names array.
    if (self.arrColumnNames != nil) {
        [self.arrColumnNames removeAllObjects];
        self.arrColumnNames = nil;
    }
    self.arrColumnNames = [[NSMutableArray alloc] init];


    // Open the database.
    BOOL openDatabaseResult = sqlite3_open([databasePath UTF8String], &sqlite3Database);
    if(openDatabaseResult == SQLITE_OK) {
        // Declare a sqlite3_stmt object in which will be stored the query after having been compiled into a SQLite statement.
        sqlite3_stmt *compiledStatement;

        // Load all data from database to memory.
        BOOL prepareStatementResult = sqlite3_prepare_v2(sqlite3Database, query, -1, &compiledStatement, NULL);
        if(prepareStatementResult == SQLITE_OK) {
            // Check if the query is non-executable.
            if (!queryExecutable){
                // In this case data must be loaded from the database.

                // Declare an array to keep the data for each fetched row.
                NSMutableArray *arrDataRow;

                // Loop through the results and add them to the results array row by row.
                while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
                    // Initialize the mutable array that will contain the data of a fetched row.
                    arrDataRow = [[NSMutableArray alloc] init];

                    // Get the total number of columns.
                    int totalColumns = sqlite3_column_count(compiledStatement);

                    // Go through all columns and fetch each column data.
                    for (int i=0; i<totalColumns; i++){
                        // Convert the column data to text (characters).
                        char *dbDataAsChars = (char *)sqlite3_column_text(compiledStatement, i);

                        // If there are contents in the currenct column (field) then add them to the current row array.
                        if (dbDataAsChars != NULL) {
                            // Convert the characters to string.
                            [arrDataRow addObject:[NSString  stringWithUTF8String:dbDataAsChars]];
                        }

                        // Keep the current column name.
                        if (self.arrColumnNames.count != totalColumns) {
                            dbDataAsChars = (char *)sqlite3_column_name(compiledStatement, i);
                            [self.arrColumnNames addObject:[NSString stringWithUTF8String:dbDataAsChars]];
                        }
                    }

                    // Store each fetched data row in the results array, but first check if there is actually data.
                    if (arrDataRow.count > 0) {
                        [self.arrResults addObject:arrDataRow];
                    }
                }
            }
            else {
                // This is the case of an executable query (insert, update, ...).

                // Execute the query.
                BOOL executeQueryResults = sqlite3_step(compiledStatement);
                if (executeQueryResults == SQLITE_DONE) {
                    // Keep the affected rows.
                    self.affectedRows = sqlite3_changes(sqlite3Database);

                    // Keep the last inserted row ID.
                    self.lastInsertedRowID = sqlite3_last_insert_rowid(sqlite3Database);
                }
                else {
                    // If could not execute the query show the error message on the debugger.
                    NSLog(@"DB Error: %s", sqlite3_errmsg(sqlite3Database));
                }
            }
        }
        else {
            // In the database cannot be opened then show the error message on the debugger.
            NSLog(@"%s", sqlite3_errmsg(sqlite3Database));
        }

        // Release the compiled statement from memory.
        sqlite3_finalize(compiledStatement);

    }

    // Close the database.
    sqlite3_close(sqlite3Database);
}
-(void)saveInfo{

    // Prepare the query string.
    NSString *query = [NSString stringWithFormat:@"insert into processInfo values(null, '%@', '%@')", _timeFormatter, _process];

    // Execute the query.
    [self.dbManager executeQuery:query];

    // If the query was successfully executed then pop the view controller.
    if (self.dbManager.affectedRows != 0) {
        NSLog(@"Query was executed successfully. Affected rows = %d", self.dbManager.affectedRows);


    }
    else{
        NSLog(@"Could not execute the query.");
    }

}


- (void)dateAndTime {
    if(!self.dateFormatter) {
        self.dateFormatter = [[NSDateFormatter alloc] init];
    }
    [self.dateFormatter setDateFormat:@"yyyy-MM-dd hh:mm:ss"];
}

//call back
static void displayStatusChanged(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo)
{
    // the "com.apple.springboard.lockcomplete" notification will always come after the "com.apple.springboard.lockstate" notification
    CFStringRef nameCFString = (CFStringRef)name;
    NSString *lockState = (__bridge NSString*)nameCFString;
    NSLog(@"Darwin notification NAME = %@",name);

    if([lockState isEqualToString:@"com.apple.springboard.lockcomplete"])
    {
        NSLog(@"DEVICE LOCKED");


        //Logic to disable the GPS
    }
    else
    {
        NSLog(@"LOCK STATUS CHANGED");
        //Logic to enable the GPS
    }
}

-(void)registerforDeviceLockNotif
{
    //Screen lock notifications
    CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), //center
                                    NULL, // observer
                                    displayStatusChanged, // callback
                                    CFSTR("com.apple.springboard.lockcomplete"), // event name
                                    NULL, // object
                                    CFNotificationSuspensionBehaviorDeliverImmediately);

    CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), //center
                                    NULL, // observer
                                    displayStatusChanged, // callback
                                    CFSTR("com.apple.springboard.lockstate"), // event name
                                    NULL, // object
                                    CFNotificationSuspensionBehaviorDeliverImmediately);
}


- (void)applicationWillResignActive:(UIApplication *)application {


    NSLog(@"\t ----- App will tResignActive  %@ -------",[self.dateFormatter stringFromDate:[NSDate date]]);

}

- (void)applicationDidEnterBackground:(UIApplication *)application {


     NSLog(@"\t ----- App in Background  at %@ -------",[self.dateFormatter stringFromDate:[NSDate date]]);


    _timeFormatter=[self.dateFormatter stringFromDate:[NSDate date]];
    _process=@"Background";
    [self saveInfo];


    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}

- (void)applicationWillEnterForeground:(UIApplication *)application {


     NSLog(@"\t ----- App in Forground %@ -------",[self.dateFormatter stringFromDate:[NSDate date]]);

    _timeFormatter=[self.dateFormatter stringFromDate:[NSDate date]];
    _process=@"Forground";
    [self saveInfo];


}

- (void)applicationDidBecomeActive:(UIApplication *)application {

     NSLog(@"\t ----- App will tResignActive  %@ -------",[self.dateFormatter stringFromDate:[NSDate date]]);


    [self saveInfo];


}

- (void)applicationWillTerminate:(UIApplication *)application {


    NSLog(@"\t ----- App will terminate %@ -------",[self.dateFormatter stringFromDate:[NSDate date]]);

    _timeFormatter=[self.dateFormatter stringFromDate:[NSDate date]];
    _process=@"terminate";

    [self saveInfo];

}

1 个答案:

答案 0 :(得分:6)

直接进入您的DBmanager文件,您可以在其中执行有关查询执行的所有代码。

你只需在那里做一个改变。写这样的代码

// Execute the query.
int executeQueryResults = sqlite3_step(compiledStatement);

注意:而不是Bool只需替换int。

这里的工作很好......我希望它对你有所帮助。