sqlite连续插入语句在200左右停止运行

时间:2016-07-12 09:13:53

标签: ios objective-c sqlite

所以我有一个应用程序,我将数据输入到sqlite数据库,它从文本文件中获取该数据拖入文档目录。 内容如下:

file1.pdf, A1, A3, folderName1, 
file2.pdf, A4, A75, folderName2, 

我用10个文本字符串测试了它。它工作和插入正常,所以我决定创建一个更多的测试。 (357)这不是它将使用的最大值,而是现在足够大的样本。

我跑了这个,在240左右,插入查询更改为错误准备。然后以下以错误开头:无法打开数据库。 - 我为sqlite3_open创建的错误消息!= SQLITE_OK。

2016-07-12 09:49:10.289 AppName[897:491157] /       /
2016-07-12 09:49:10.290 AppName[897:491157] INSERT INTO Files (fileName, folder, refNum, endrefNum) SELECT 'file1.pdf', 'Statement', 'S460', 'S460' WHERE NOT EXISTS(SELECT fileName FROM Files WHERE fileName = 'file1.pdf')

2016-07-12 09:49:10.317 AppName[897:491157] /       /
2016-07-12 09:49:10.317 AppName[897:491157] INSERT INTO Files (fileName, folder, refNum, endrefNum) SELECT 'file2.pdf', 'Important', 'S461', 'S461' WHERE NOT EXISTS(SELECT fileName FROM Files WHERE fileName = 'file2.pdf')

2016-07-12 09:49:10.341 AppName[897:491157] /       /
2016-07-12 09:49:10.342 AppName[897:491157] INSERT INTO Files (fileName, folder, refNum, endrefNum) SELECT 'file3.pdf', 'Important', 'S462', 'S463' WHERE NOT EXISTS(SELECT fileName FROM Files WHERE fileName = 'file3.pdf')
2016-07-12 09:49:10.343 AppName[897:491157] Error running insert: INSERT INTO Files (fileName, folder, refNum, endrefNum) SELECT 'file3.pdf', 'Important', 'S462', 'S463' WHERE NOT EXISTS(SELECT fileName FROM Files WHERE fileName = 'file3.pdf')

2016-07-12 09:49:10.343 AppName[897:491157] /       /
2016-07-12 09:49:10.344 AppName[897:491157] Error: cannot open database
2016-07-12 09:49:10.344 AppName[897:491157] INSERT INTO Files (fileName, folder, refNum, endrefNum) SELECT 'file4.pdf', 'Important', 'S464', 'S464' WHERE NOT EXISTS(SELECT fileName FROM Files WHERE fileName = 'file4.pdf')
2016-07-12 09:49:10.344 AppName[897:491157] Error preparing INSERT INTO Files (fileName, folder, refNum, endrefNum) SELECT 'file4.pdf', 'Important', 'S464', 'S464' WHERE NOT EXISTS(SELECT fileName FROM Files WHERE fileName = 'file4.pdf')

上面是我的输出片段,显示我的INSERT语句和出现的错误消息。正如你所看到的,前两个正常进入。然后第3个文件遇到运行INSERT语句的问题。然后从那时起,其余的文件无法打开数据库,我认为这是为什么它无法准备语句。

我尝试了什么

我认为这样做的原因是因为某条线     扔掉了。 - 我剪切了文本文件的下半部分并将其粘贴到顶部。第一批很好,所以这不是原因。

我注意到在sqlite for android上有一个名为transaction的命令,用于多个插入查询。我是否需要做类似于iOS的事情?

-(void) addFileName:(NSString *)fileName
                        fileType:(NSString *)fileType
                        refNumber:(NSString *)bates
                           fileLocation:(NSString *)location
                 endrefNumber:(NSString *)endBates
{
    long long fileID;
    NSLog(@"/       /");
    [self openDB];

    // Names Table
    NSString *insertSQL = [NSString stringWithFormat:@"INSERT INTO Files (fileName, folder, refNum, endrefNum) SELECT '%@', '%@', '%@', '%@' WHERE NOT EXISTS(SELECT fileName FROM Files WHERE fileName = '%@')", fileName, fileType, bates, endBates, fileName];
    NSLog(@"%@",insertSQL);
    const char* query1 = [insertSQL UTF8String];
    sqlite3_stmt * query1_stmt = NULL;
    if (sqlite3_prepare_v2(database, query1, -1, &query1_stmt, NULL) != SQLITE_OK){
        NSLog(@"Error preparing %@", insertSQL);
        [self closeDB];
        return;
    }

    if (sqlite3_step(query1_stmt) != SQLITE_DONE) {
        NSLog(@"Error running insert: %s", query1);
        [self closeDB];
        return;
    }
    // row id
    fileID = sqlite3_last_insert_rowid(database);

    // phones table
    insertSQL = [NSString stringWithFormat:@"INSERT INTO Location (FileID, Location) VALUES (%lld, '%@')", fileID, location];
    const char* query2 = [insertSQL UTF8String];
    sqlite3_stmt * query2_stmt = NULL;
    if (sqlite3_prepare_v2(database, query2, -1, &query2_stmt, NULL) != SQLITE_OK){
        NSLog(@"Error preparing %@", insertSQL);
        [self closeDB];
        return;
    }

    if (sqlite3_step(query2_stmt) != SQLITE_DONE) {
        NSLog(@"Error running insert: %s", query2);
        [self closeDB];
        return;
    }

    [self closeDB];
}

打开数据库

-(void) openDB
{
    if ( (sqlite3_open([[self dbDocPath] UTF8String], &database)) != SQLITE_OK )
        NSLog(@"Error: cannot open database");
}

关闭数据库

-(void) closeDB
{
    sqlite3_close(database);
}

更新

所以我做了这样,数据库打开一次,插入所有数据,然后一旦完成就关闭。这似乎是数据库的打开和关闭是导致问题的原因。对我来说似乎有点奇怪,如果有人能解释为什么这会有所帮助。

1 个答案:

答案 0 :(得分:0)

  

所以我做了这个,以便数据库打开一次,插入所有的   数据,然后一旦完成就关闭。这似乎是开放和   关闭数据库是导致问题的原因。似乎仍然有点   对我来说很奇怪,如果有人能解释为什么这会有所帮助。

我认为问题是:

  1. 您不检查数据库是否已打开或已关闭。
  2. 您不检查打开数据库是否失败。
  3. 少量警卫代码应解决:

    -(BOOL) openDB
    {
        BOOL opened = YES;
        if (database == NULL) {
            if ( (sqlite3_open([[self dbDocPath] UTF8String], &database)) != SQLITE_OK ) {
                // Use sqlite3_errmsg() to tell us why it didn't open!
                NSLog(@"Error: cannot open database");
                opened = NO;
            }
        }
        return opened;
    }
    
    -(void) closeDB
    {
        if (database != NULL) {
            sqlite3_close(database);
            database = NULL;
        }
    }
    

    (我希望database是一个实例变量而不是全局?)。

    你还需要检查它是否打开OK:

    if (![self openDB])
        return;
    

    也来自@CL:

      

    您忘记了sqlite3_finalize()