Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/44.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/111.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/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
Iphone iOS:Sqlite数据库错误:由于未捕获异常而终止应用程序';n内部一致性异常';,原因:';准备语句时出错';_Iphone_Ios_Error Handling_Sqlite_Compiler Errors - Fatal编程技术网

Iphone iOS:Sqlite数据库错误:由于未捕获异常而终止应用程序';n内部一致性异常';,原因:';准备语句时出错';

Iphone iOS:Sqlite数据库错误:由于未捕获异常而终止应用程序';n内部一致性异常';,原因:';准备语句时出错';,iphone,ios,error-handling,sqlite,compiler-errors,Iphone,Ios,Error Handling,Sqlite,Compiler Errors,我在应用程序中使用了sqlite DB,我需要同时调用两个查询,但我给出的错误是:由于未捕获的异常“nsInternalInconsistencException”终止应用程序,原因是:“准备语句时出错” 我每10秒运行一次计时器,用于在按钮事件后从DB选择行和在DB中插入行 我的代码片段为: 在视图中,将出现: int result2 = sqlite3_open([dbPath UTF8String], &database); if (result2 != SQLITE_OK) {

我在应用程序中使用了sqlite DB,我需要同时调用两个查询,但我给出的错误是:由于未捕获的异常“nsInternalInconsistencException”终止应用程序,原因是:“准备语句时出错”

我每10秒运行一次计时器,用于在按钮事件后从DB选择行和在DB中插入行

我的代码片段为:

视图中,将出现

int result2 = sqlite3_open([dbPath UTF8String], &database);
if (result2 != SQLITE_OK) {
    NSLog(@"Failure in connecting to the database with result %d",result2);
}
else {
    NSLog(@ "Succesfully opened connection to DB") ;

}
int result = sqlite3_close(database);
if (result != SQLITE_OK){
    NSLog(@"Failure in closing connection to database. Result %d",result);
}
else {
    NSLog(@"Successfully closed DB connection") ;
}
并且在
视图中将消失

int result2 = sqlite3_open([dbPath UTF8String], &database);
if (result2 != SQLITE_OK) {
    NSLog(@"Failure in connecting to the database with result %d",result2);
}
else {
    NSLog(@ "Succesfully opened connection to DB") ;

}
int result = sqlite3_close(database);
if (result != SQLITE_OK){
    NSLog(@"Failure in closing connection to database. Result %d",result);
}
else {
    NSLog(@"Successfully closed DB connection") ;
}
对于插入行的

NSString *queryInsert = [NSString stringWithFormat: @"insert into mail_snoozlist (msgBody,msgSubject, msgSender,msgTo,msgDate,snoozTime) values('%@','%@','%@','%@','%@','%@')",strBody,msgSub,msgFrom,msgTo,strMsgDate,stringFromDate];

    NSLog(@"queryInsert:%@",queryInsert);

    const char *sql = [queryInsert UTF8String];

    if(sqlite3_prepare_v2(database, sql, -1, &statement, NULL) == SQLITE_OK) {
        sqlite3_step(statement);
        sqlite3_reset(statement);

    } else {

        NSAssert1(0,@"error preparing statement",sqlite3_errmsg(database));
        return;
    }

    sqlite3_finalize(statement);
NSString *querySQL2 = [NSString stringWithFormat: @"Select * from mail_snoozlist WHERE snoozTime = '%@'",_snoozTime];

    NSLog(@"querySql:%@",querySQL2);

    if (sqlite3_prepare_v2(database, [querySQL2 UTF8String], -1, &statement, NULL) == SQLITE_OK)
    {

        while (sqlite3_step(statement) == SQLITE_ROW)
        {
            Message *obj = [[Message alloc] init];

            NSString *msgBody=[[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 1)];
            obj.msgBody= msgBody;

            NSString *msgSub=[[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 2)];
            obj.msgSub= msgSub;

            NSString *msgSender=[[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 3)];
            obj.msgFrom= msgSender;

            NSString *msgTo=[[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 4)];
            obj.msgTo= msgTo;

            NSString *msgDate=[[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 5)];
            obj.msgDate= msgDate;

            [listOfItems addObject:obj];

            [self.tableView reloadData];
        }

        sqlite3_reset(statement);
        sqlite3_finalize(statement);
对于
选择行

NSString *queryInsert = [NSString stringWithFormat: @"insert into mail_snoozlist (msgBody,msgSubject, msgSender,msgTo,msgDate,snoozTime) values('%@','%@','%@','%@','%@','%@')",strBody,msgSub,msgFrom,msgTo,strMsgDate,stringFromDate];

    NSLog(@"queryInsert:%@",queryInsert);

    const char *sql = [queryInsert UTF8String];

    if(sqlite3_prepare_v2(database, sql, -1, &statement, NULL) == SQLITE_OK) {
        sqlite3_step(statement);
        sqlite3_reset(statement);

    } else {

        NSAssert1(0,@"error preparing statement",sqlite3_errmsg(database));
        return;
    }

    sqlite3_finalize(statement);
NSString *querySQL2 = [NSString stringWithFormat: @"Select * from mail_snoozlist WHERE snoozTime = '%@'",_snoozTime];

    NSLog(@"querySql:%@",querySQL2);

    if (sqlite3_prepare_v2(database, [querySQL2 UTF8String], -1, &statement, NULL) == SQLITE_OK)
    {

        while (sqlite3_step(statement) == SQLITE_ROW)
        {
            Message *obj = [[Message alloc] init];

            NSString *msgBody=[[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 1)];
            obj.msgBody= msgBody;

            NSString *msgSub=[[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 2)];
            obj.msgSub= msgSub;

            NSString *msgSender=[[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 3)];
            obj.msgFrom= msgSender;

            NSString *msgTo=[[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 4)];
            obj.msgTo= msgTo;

            NSString *msgDate=[[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 5)];
            obj.msgDate= msgDate;

            [listOfItems addObject:obj];

            [self.tableView reloadData];
        }

        sqlite3_reset(statement);
        sqlite3_finalize(statement);
请任何人帮我解决这个问题


谢谢

添加这两个方法,并在插入和选择之前在insert method中调用它们

 - (void) createEditableCopyOfDatabaseIfNeeded
{


    BOOL success;
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSError *error;
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:@"dbname.sqlite"];
    success = [fileManager fileExistsAtPath:writableDBPath];
    if (success) return;
    //{

    NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"dbname.sqlite"];

    success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
    // }
    if (!success)
    {
        NSAssert1(0, @"Failed to create writable database file with message '%@'.", [error localizedDescription]);
    }
}


- (void)initializeDatabase
 {



NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"dbname.sqlite"];
sqlite3_open([path UTF8String], &database);
}

您应该更改
NSAssert
语句以包含错误消息:

NSAssert1(0, @"error preparing statement: %s", sqlite3_errmsg(database));
一旦你这样做了,你应该得到一个有意义的回答,这将帮助你诊断问题

如果不查看
sqlite3\u errmsg
消息,就很难诊断问题。它可以简单到列名或表名中的输入错误,也可以复杂到无法找到表,因为创建数据库时找不到该表,所以创建了一个空白数据库(没有该表)。在看到错误消息之前很难说


顺便说一句,您不应该使用
stringWithFormat
构建SQL,因为您会受到SQL注入攻击,并且如果这些文本值中有任何一个带有撇号,您也会遇到问题。您应该使用
占位符而不是printf样式的格式化程序,然后使用
sqlite3\u bind\u text
调用将值绑定到这些列:

NSString *queryInsert = @"insert into mail_snoozlist (msgBody,msgSubject, msgSender,msgTo,msgDate,snoozTime) values(?, ?, ?, ?, ?, ?)";

if (sqlite3_prepare_v2(database, sql, -1, &statement, NULL) != SQLITE_OK) {
    NSAssert1(0,@"error preparing statement: %s",sqlite3_errmsg(database));
    return;
}

// for these 6 sqlite3_bind function calls, if any of these strings can be `nil`, then you'd
// want to call sqlite3_bind_null if that's the case, rather than sqlite3_bind_text

if (sqlite3_bind_text(statement, 1, [strBody UTF8String], -1, NULL) != SQLITE_OK) {
    NSAssert1(0,@"error binding 1: %s",sqlite3_errmsg(database));
    sqlite3_finalize(statement);
    return;
}

if (sqlite3_bind_text(statement, 2, [msgSub UTF8String], -1, NULL) != SQLITE_OK) {
    NSAssert1(0,@"error binding 2: %s",sqlite3_errmsg(database));
    sqlite3_finalize(statement);
    return;
}

if (sqlite3_bind_text(statement, 3, [msgFrom UTF8String], -1, NULL) != SQLITE_OK) {
    NSAssert1(0,@"error binding 3: %s",sqlite3_errmsg(database));
    sqlite3_finalize(statement);
    return;
}

if (sqlite3_bind_text(statement, 4, [msgTo UTF8String], -1, NULL) != SQLITE_OK) {
    NSAssert1(0,@"error binding 4: %s",sqlite3_errmsg(database));
    sqlite3_finalize(statement);
    return;
}

if (sqlite3_bind_text(statement, 5, [strMsgDate UTF8String], -1, NULL) != SQLITE_OK) {
    NSAssert1(0,@"error binding 5: %s",sqlite3_errmsg(database));
    sqlite3_finalize(statement);
    return;
}

if (sqlite3_bind_text(statement, 6, [stringFromDate UTF8String], -1, NULL) != SQLITE_OK) {
    NSAssert1(0,@"error binding 6: %s",sqlite3_errmsg(database));
    sqlite3_finalize(statement);
    return;
}

if (sqlite3_step(statement) != SQLITE_DONE) {
    NSAssert1(0,@"error stepping: %s",sqlite3_errmsg(database));
}

sqlite3_finalize(statement);

我用
insert
语句说明了这个问题,但是
select
语句也应该这样做。

对于调用,请使用这些行//[self-CreateEditableCopyOfDatabaseIfRequired];[自初始化数据库];谢谢你的回复。我在查询中做了一点更改,解决了这个问题:
NSString*queryInsert=[NSString stringWithFormat:@“插入邮件休眠列表(msgBody、msgSubject、msgSender、msgTo、msgDate、snoozTime)值(“%s”、“s”、“s”、“s”、“s”、“s”、“strobdy UTF8String”、“msgObj.msgSub UTF8String]、[msgObj.msgFrom UTF8String]、[msgObj.msgTo UTF8String],[stringFromDate UTF8String],[stringFromDate UTF8String]];
谢谢您的回复。我已经通过查询中的一点更改解决了这个问题:
NSString*queryInsert=[NSString stringWithFormat:@“插入邮件睡眠列表(msgBody,msgSubject,msgSender,msgTo,msgDate,snoozTime)值('%s','%s','%s','%s','%s','%s'),'%s'),[Strobdy UTString],[msgObj.msgSub UTF8String],[msgObj.msgFrom UTF8String],[msgObj.msgTo UTF8String],[strmssgdate UTF8String],[stringFromDate UTF8String]]
@Pankaj首先,你仍然应该将
%s
添加到你的
NSAssert1
行中,否则当你出错时,你将永远看不到
sqlite3\u errmsg
。其次,在你的SQL中将
%@
更改为
%s
只是巧合地起作用,实际上并不能解决任何问题,只会使代码变得不那么清晰。第三,如果您提议的更改试图插入一个
strobody
或一个
msgSubject
中碰巧有撇号,那么您的代码仍然会崩溃。不要使用
stringWithFormat
来构建SQL,而是使用
sqlite3\u bind\u text
。另外,一个不诚实的用户可能会进行SQL注入攻击,例如,我添加了这个代码e、 但现在我得到了错误:
由于未捕获的异常“nsinternalinconsistenceexception”而终止应用程序,原因是:“错误准备语句:库例程调用顺序错误”
。我没有得到任何错误绑定日志。@Pankaj现在您的断言报告了准确的SQLite错误消息:非常好。此错误,“库例程调用顺序不正确",表示您没有遵循。例如,如果您关闭了数据库而忽略了重新打开它,则可能会发生这种情况。我认为错误不在上面的代码中,而是在其他地方。请逐步检查代码,检查调用open、prepare、bind、Step、finalize和close的顺序。特别是在
sqlite3\o处放置断点/日志pen
sqlite3\u close
行。@Pankaj请参阅。