sqlite iphone лучшая практика для чтения данных - PullRequest
2 голосов
/ 26 сентября 2011

Я пытаюсь создать приложение, которое читает из базы данных SQLite3.Я планирую предварительно загружать данные во время разработки, поэтому приложению не нужно ничего изменять в базе данных, только читать из нее, делать запросы и т. Д.

Каков наилучший метод для чтения данных исключительно?Должен ли я открыть базу данных, прочитать данные и закрыть ее с каждым запросом?Приложение будет делать много маленьких запросов и несколько больших.Лучше иметь базу данных открытой на время работы приложения или открывать / закрывать ее при каждом извлечении?

Ответы [ 5 ]

1 голос
/ 26 сентября 2011

Чтение:

1.Для запросов важно повторно использовать скомпилированные операторы.
2. Убедитесь, что вы используете параметры, чтобы вы могли повторно использовать эти скомпилированные запросы

Когда вы вызываете sqlite3_prepare_v2, он компилирует оператор идает вам ссылку на утверждение обратно.Найдите способ сохранить это и использовать снова.Смотрите код ниже для * заявления.Вы передаете & заявление в подготовку.

Кроме того, обратите внимание на использование?для параметров.Если вы собираетесь повторно использовать оператор, важно вызвать sqlite3_reset () снова для оператора, повторно связать входные данные из программы (параметры) и выполнить его снова.

sqlite3_stmt    *statement;
NSString *querySQL = @"update contacts set name=?,address=?,phone=? where id=?";
NSLog(@"query: %@", querySQL);
const char *query_stmt = [querySQL UTF8String];

// preparing a query compiles the query so it can be re-used.
// find a way to save off the *statement so you can re-use it.
sqlite3_prepare_v2(_contactDb, query_stmt, -1, &statement, NULL);  

// use sqlite3_bind_xxx functions to bind in order values to the params   
sqlite3_bind_text(statement, 1, [[contact name] UTF8String], -1, SQLITE_STATIC);
sqlite3_bind_text(statement, 2, [[contact address] UTF8String], -1, SQLITE_STATIC);
sqlite3_bind_text(statement, 3, [[contact phone] UTF8String], -1, SQLITE_STATIC);
sqlite3_bind_int64(statement, 4, [[contact id] longLongValue]);

Всегдапроверьте коды возврата!и зарегистрируйте или обработайте ошибки.

    rc = sqlite3_step(stmt);
    switch (rc)
    {
        case SQLITE_ROW:
            // ...
            break;

        case SQLITE_OK:
        case SQLITE_DONE:
            break;

        default:
            // ....
            }

            return NO;
    }

если вы получили ошибку, войдите в систему или получите сообщение об ошибке, чтобы предоставить дополнительную информацию:

- (NSString*)errorMessage
{
    return [NSString stringWithCString:sqlite3_errmsg(_sqlite3) encoding:NSUTF8StringEncoding];    
}
0 голосов
/ 22 июня 2015

По вашему вопросу вы хотите прочитать данные из базы данных. Ниже приведены ответы на ваши вопросы.

  1. Нет необходимости открывать БД каждый раз, когда вы запускаете запрос. Только один раз. Лучше, если вы создадите синглтон-класс и откроете в нем db впервые, когда он будет инициирован.
  2. Используйте следующий метод кода, который будет работать для всех запросов на выборку с условным выбором, сгруппировать и т. Д.
  3. I) он принимает имена столбцов вывода / результата в качестве входного массива ii) TableName iii) где условие iv) предложение OrderBy v) group By предложение

- (NSMutableArray *)runSelecteQueryForColumns: (NSArray *)p_columns ontableName: (NSString *)p_tableName withWhereClause: (NSString *)p_whereClause withOrderByClause: (NSString *)p_orederByCalause withGroupByClause: (NSString *)p_groupByClause
{


    NSMutableArray *l_resultArray = [[NSMutableArray alloc] init];

    if(!self.m_database)
    {
        if(![self openDatabase])
        {
            sqlite3_close(self.m_database);
            //NSLog(@"error in select : DB creating : %@",p_whereClause);
            return nil;

        }
    }

    NSMutableString *l_simpleQuery =[[NSMutableString alloc] initWithString:@"Select"] ;

    if(p_columns)
    {

        for(int l_row = 0 ; l_row < [p_columns count] ; l_row++)
        {
            if(l_row != [p_columns count]-1)
            {
                [l_simpleQuery appendString:[NSString stringWithFormat:@" %@,", [p_columns objectAtIndex:l_row]]];
            }
            else
            {
                [l_simpleQuery appendString:[NSString stringWithFormat:@" %@", [p_columns objectAtIndex:l_row]]];
            }
        }
    }
    else
    {
        [l_simpleQuery appendString:@" *"];
    }

    [l_simpleQuery appendString:[NSString stringWithFormat:@" From %@",p_tableName]];

    if(p_whereClause)
    {
        [l_simpleQuery appendString:[NSString stringWithFormat:@" %@",p_whereClause]];
    }
    if(p_groupByCaluase)
    {
        [l_simpleQuery appendString:[NSString stringWithFormat:@" %@",p_groupByCaluase]];
    }

    if(p_orederByCalause)
    {
        [l_simpleQuery appendString:[NSString stringWithFormat:@" %@",p_orederByCalause]];
    }


    //NSLog(@"Select Query: - %@",l_simpleQuery);

    const char *l_query_stmt = [l_simpleQuery UTF8String];

    sqlite3_stmt *l_statement = nil;

    int i = sqlite3_prepare_v2(self.m_database,
                               l_query_stmt, -1, &l_statement, NULL);

    if (i == SQLITE_OK)
    {

        while(sqlite3_step(l_statement) == SQLITE_ROW)
        {

            [l_resultArray addObject:[self createDictionary:l_statement]];

        }

        sqlite3_finalize(l_statement);


    }
    else
    {
        sqlite3_finalize(l_statement);
        //sqlite3_close(l_database);
        DDLogError(@"%@ - error in SQL :%@",THIS_FILE,l_simpleQuery);
        return nil;
    }
    //NSLog(@"RESULT %@",l_resultArray);
    return l_resultArray;

}
0 голосов
/ 26 сентября 2011

Когда вы открываете базу данных, используя sqlite_open_v2 и флаг SQLITE_OPEN_READONLY, SQLite открывает сам файл в режиме только для чтения, поэтому даже если ваше приложение из-за ошибки повреждает принадлежность памятидля SQLite база данных останется нетронутой.

Имея это в виду, я буду держать базу данных открытой, пока приложение не закроется.(Возможно, вы захотите закрыть его, если получите уведомление о нехватке памяти и снова откроете его по требованию, но открывать и закрывать его для каждого запроса будет бесполезно.)

0 голосов
/ 26 сентября 2011

Если вы не копируете базу данных в каталог Documents, вы работаете с базой данных из каталога ресурсов, и эта папка доступна только для чтения.

0 голосов
/ 26 сентября 2011

Используйте sqlite_open_v2 с флагом SQLITE_OPEN_READONLY.Например, я использую следующий метод, чтобы открыть базу данных только для чтения.

  // Open for reading only.
- (int) openDatabaseAtPath:(NSString *) path
{
    if (database != nil)
    {
        sqlite3_close(self.database);
        [self setDatabase:nil];
    }

    int errorCode = SQLITE_OK;
    errorCode = sqlite3_open_v2([path UTF8String],
                                 &database,
                                 SQLITE_OPEN_READONLY,
                                 NULL);

    return errorCode;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...