Как вы находите количество строк в базе данных sqlite с помощью Swift 4?

-4

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

  • 0
    Возможная копия Get Rows Count из базы данных sqlite в iPhone ios
  • 0
    Это вопрос sql или swift? Если вы уже храните данные в базе данных, я думаю, у вас работает Swift?
Теги:

1 ответ

2

Вы не хотите количество строк, но вы хотите, чтобы его последний 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)")
}
  • 1
    Вы на самом деле не нужно AUTOINCREMENT : sqlite.org/autoinc.html
  • 0
    Хорошее уточнение. Обновленный ответ.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню