Почему метод SQLite sqlite3_step не работает - PullRequest
1 голос
/ 12 июля 2020

У меня есть проект iOS SQLite. Я создал класс DBHelper, инициализирующий доступ к базе данных, как описано в этом руководстве , и написал в DBHelper такие функции, как createTable() и insert(), которые работают правильно, и еще одну read(), которая должен вернуть массив с данными. Начало этой забавы c выглядит так:

func read() -> [DataModel]{
    let queryStatementString: String = "SELECT * FROM objects;"
    var queryStatement: OpaquePointer? = nil
    var psns: [DataModel] = []
    
    if sqlite3_prepare_v2(db, queryStatementString, -1, &queryStatement, nil) != SQLITE_OK {
        let errmsg = String(cString: sqlite3_errmsg(db)!)
        print("error preparing select: \(errmsg)")
    }
    print("\(sqlite3_step(queryStatement)) and \(SQLITE_ROW)")
    while sqlite3_step(queryStatement) == SQLITE_ROW {
    //and here I try to declare variables like let name = String(describing: 
    // String(cString: sqlite3_column_text(queryStatement, 1)))
    // and then create a DataModel with these variables 

Дело в том, что последняя строка while sqlite3_step(queryStatement) == SQLITE_ROW недоступна, и весь код после этой строки не компилируется.

print в предыдущей строке выдает в консоли «101 и 100», и я думаю, это причина того, почему while l oop не работает должным образом. Где мне найти причину этой ошибки?

1 Ответ

1 голос
/ 12 июля 2020

Если ваш оператор print печатает 101, то есть SQLITE_DONE, для результата sqlite3_step, это просто означает, что в таблице нет данных.

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

Например, определив путь к моему конкретному экземпляру этого приложения на этом симуляторе, затем я перешел в командную строку, перешел в этот каталог, открыл sqlite3 и подтвердил, что строки, которые я вставил в свой код, появились в таблице:

enter image description here

Or, in TablePlus:

введите описание изображения здесь

Очевидно, я использую person, как в этом руководстве, но использую любое имя таблицы, которое вы использовали при создании таблицы и вставке данных. И, разумеется, ваш путь для команды cd будет другим, поэтому выведите свой путь в функции openDatabase и используйте его для диагностики c.

В вашем примере кода вы используете следующий шаблон кода:

print("\(sqlite3_step(queryStatement)) and \(SQLITE_ROW)")
while sqlite3_step(queryStatement) == SQLITE_ROW {
    ...
}

Если бы в вашей таблице была одна запись, sqlite3_step в операторе print извлек бы ее, а sqlite3_step в операторе while затем перейдет к следующей записи, и, поскольку вы сейчас находитесь в конце таблицы, вы выйдете из l oop. В итоге вы пропускаете первую строку в своих результатах с помощью этого дополнительного вызова sqlite3_step в операторе print.

Удалите этот оператор print. Или, если вы хотите его распечатать, убедитесь, что вы не вводите посторонние звонки sqlite3_step. Например, вы можете сделать:

var rc = sqlite3_step(statement)

while rc == SQLITE_ROW {
    print("row", rc)

    ...
    rc = sqlite3_step(statement)
}

print("done", rc)

if rc != SQLITE_DONE {
    // print the error
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...