iPhone, sqlite3, как передать значения в оператор выбора? - PullRequest
0 голосов
/ 01 октября 2010

Это код, который я использую для выбора некоторых записей из моей базы данных. Я связываю две даты в моем sql, однако, когда я добираюсь до sqlite3_step, я получаю SQLITE_DONE, где я должен получать SQLITE_ROW. Похоже, он обрабатывает привязки, а не запрашивает данные.

Что я делаю не так?

NSString *startDateRangeString = @"2000-05-01";
NSString *endDateRangeString = @"2011-05-01";

sqlite3 *database;
int result = sqlite3_open("mydb.db", &database);
if(result != SQLITE_OK)
{
    NSLog(@"Could not open db.");
}

const char *sql = "select pid from tmp where due >= '%@' and due < '%@' order by due, pid;";
sqlite3_stmt *statementTMP;

int error_code = sqlite3_prepare_v2(database, sql, -1, &statementTMP, NULL);
if(error_code == SQLITE_OK) {

    sqlite3_bind_text(statementTMP, 1, [startDateRangeString UTF8String], -1, SQLITE_TRANSIENT);
    sqlite3_bind_text(statementTMP, 2, [endDateRangeString UTF8String], -1, SQLITE_TRANSIENT);

    int step_error_code = sqlite3_step(statementTMP);

    while(sqlite3_step(statementTMP) == SQLITE_ROW) // I get 101 aka SQLITE_DONE
    {
        NSLog(@"Found!!");
    }
}
sqlite3_finalize(statementTMP);
sqlite3_close(database);

Ответы [ 4 ]

3 голосов
/ 01 октября 2010

Я думаю, что ваш SQL плох.Вместо% @ вы должны использовать?для позиционных параметров.

Я настоятельно рекомендую использовать оболочку, чтобы упростить жизнь.FMDB отлично подходит на http://github.com/ccgus/fmdb.

1 голос
/ 01 октября 2010
    char *statementTMP = "select pid from tmp where due >= '?1' and due < '?2' order by due, pid";
....
    sqlite3_bind_text(statementTMP, 1, [startDateRangeString UTF8String], -1, SQLITE_TRANSIENT);
    sqlite3_bind_text(statementTMP, 2, [endDateRangeString UTF8String], -1, SQLITE_TRANSIENT);
0 голосов
/ 01 октября 2010

Если я правильно прочитал .. Вы не выполняете утверждение .. вы просто готовите .. вы должны сделать оба ..

эта часть просто подготовить запрос

if (sqlite3_prepare_v2(database, sql, -1, &stmt, NULL) != SQLITE_OK) 
{
            NSLog(@"SQL Warning: failed to prepare statement 
with message '%s'.", sqlite3_errmsg(database));
}

Эта часть фактически выполняет запрос

if(sqlite3_exec(database, sql, nil, &stmt, &errmsg) == SQLITE_OK)
{
        NSLog(@"it means that you query executed correctly"); 
        if(sqlite3_step(stmt) == SQLITE_ROW)
        {
             NSLog(@"Found!!");
        }
}else 
{
        NSLog(@"SQL Warning: '%s'.", sqlite3_errmsg(database));
}

=)

0 голосов
/ 01 октября 2010

Это по замыслу.

sqlite3_step возвращает SQLITE_ROW для каждой строки в наборе результатов и SQLITE_DONE, чтобы указать, что строк больше нет. Таким образом, если результирующий набор содержит N строк, то N вызовов будут возвращать SQLITE_ROW, а (N + 1) -й возвращает SQLITE_DONE. Пустой набор результатов не является чем-то особенным, он следует той же логике с N = 0 (поэтому самый первый вызов возвращает SQLITE_DONE). Это позволяет клиентскому коду обрабатывать все наборы результатов равномерно.

Надеюсь, это поможет.

Дай мне знать, если тебе понадобится помощь.

PK

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