Как вы находите количество строк в базе данных sqlite с помощью Swift 4? - PullRequest
0 голосов
/ 28 февраля 2019

Я пытаюсь найти последний идентификатор в моей таблице в базе данных, чтобы я мог поместить его в другую таблицу.Как я могу найти этот идентификатор?

1 Ответ

0 голосов
/ 28 февраля 2019

Вам не нужно количество строк, а вы хотите, чтобы он был последним rowid.Обычно они одинаковы, но не всегда.Что если вы удалили строку?Вы действительно хотите rowid, который вы можете получить с помощью sqlite3_last_insert_rowid сразу после вставки строки.Это даст вам rowid для ранее вставленной строки.


Например, рассмотрим:

var db: OpaquePointer?
if sqlite3_open(fileURL.path, &db) != SQLITE_OK {
    print("error opening database")
}

if sqlite3_exec(db, "CREATE TABLE IF NOT EXISTS author (author_id INTEGER PRIMARY KEY, name TEXT NOT NULL)", nil, nil, nil) != SQLITE_OK {
    let errmsg = String(cString: sqlite3_errmsg(db)!)
    print("error creating table: \(errmsg)")
}

var statement: OpaquePointer?

if sqlite3_prepare_v2(db, "INSERT INTO author (name) VALUES (?)", -1, &statement, nil) != SQLITE_OK {
    let errmsg = String(cString: sqlite3_errmsg(db)!)
    print("error preparing insert: \(errmsg)")
}

if sqlite3_bind_text(statement, 1, "William Shakespeare", -1, SQLITE_TRANSIENT) != SQLITE_OK {
    let errmsg = String(cString: sqlite3_errmsg(db)!)
    print("failure binding: \(errmsg)")
}

if sqlite3_step(statement) != SQLITE_DONE {
    let errmsg = String(cString: sqlite3_errmsg(db)!)
    print("failure inserting author: \(errmsg)")
}

let authorId = sqlite3_last_insert_rowid(db)

if sqlite3_finalize(statement) != SQLITE_OK {
    let errmsg = String(cString: sqlite3_errmsg(db)!)
    print("error finalizing prepared statement: \(errmsg)")
}

Итак, если вы намеревались захватить rowid, точто вы можете ссылаться на него в других таблицах, sqlite3_last_insert_rowid будет захватывать то, что SQLite сгенерировал для вас.В приведенном выше примере я устанавливаю authorId константу для любого SQLite, назначенного для этой записи.

Вы, вероятно, знаете это, но ради будущих читателей мы должны вообще позволить SQLite генерировать уникальный rowid для нас:

  • используйте INTEGER PRIMARY KEY (возможно AUTOINCREMENT, если необходимо) в определении таблицы, как указано выше;и

  • на самом деле не задают значение для этого ключа при вставке, а позволяют SQLite заполнять его.

Внизу, мы позволяемSQLite присваивает нам rowid значений, и мы используем sqlite3_last_insert_rowid для захвата идентификатора предыдущей строки, которая была создана.


Например, теперь я могу использовать это authorId, когда хочуиспользуйте это в другой таблице:

let sql = """
    CREATE TABLE IF NOT EXISTS book (
        book_id INTEGER PRIMARY KEY,
        title TEXT NOT NULL,
        author_id INTEGER,
            FOREIGN KEY (author_id) REFERENCES author (author_id))
    """

if sqlite3_exec(db, sql, nil, nil, nil) != SQLITE_OK {
    let errmsg = String(cString: sqlite3_errmsg(db)!)
    print("error creating table: \(errmsg)")
}

if sqlite3_prepare_v2(db, "INSERT INTO book (title, author_id) VALUES (?, ?)", -1, &statement, nil) != SQLITE_OK {
    let errmsg = String(cString: sqlite3_errmsg(db)!)
    print("error preparing insert: \(errmsg)")
}

if sqlite3_bind_text(statement, 1, "Henry V", -1, SQLITE_TRANSIENT) != SQLITE_OK {
    let errmsg = String(cString: sqlite3_errmsg(db)!)
    print("failure binding book title: \(errmsg)")
}

if sqlite3_bind_int64(statement, 2, authorId) != SQLITE_OK {
    let errmsg = String(cString: sqlite3_errmsg(db)!)
    print("failure binding author id: \(errmsg)")
}

if sqlite3_step(statement) != SQLITE_DONE {
    let errmsg = String(cString: sqlite3_errmsg(db)!)
    print("failure inserting book: \(errmsg)")
}

if sqlite3_finalize(statement) != SQLITE_OK {
    let errmsg = String(cString: sqlite3_errmsg(db)!)
    print("error finalizing prepared statement: \(errmsg)")
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...