Если ваша вставка не удалась, вы должны напечатать сообщение об ошибке sqlite3_errmsg
, которое точно скажет вам, что пошло не так.
FWIW, ваш код сработал для меня, так что это Возможно, что-то не входит в ваш вопрос, например, как вы открыли базу данных и / или как была определена таблица. Возможные проблемы включают в себя:
- вставка в базу данных только для чтения (например, открытая база данных в пакете, доступном только для чтения, явно открытая с помощью
sqlite3_open_v2
в режиме только для чтения и т. Д. c .); - ваш оператор связывания завершился неудачно (вам действительно тоже следует проверить его на успех);
- с уникальным ключом в этом столбце и уже имеющим это значение где-то; или
- с другими необходимыми (
NOT NULL
) столбцами, которые не были предоставлены.
Независимо от того, регистрация сообщения об ошибке устранит любую неопределенность.
Например
func insert() {
var insertStatement: OpaquePointer?
guard sqlite3_prepare_v2(mySQLDB, insertStatementString, -1, &insertStatement, nil) == SQLITE_OK else {
printError(with: "INSERT statement not prepared")
return
}
defer { sqlite3_finalize(insertStatement) }
let date = "14071999"
guard sqlite3_bind_text(insertStatement, 1, date.cString(using: .utf8), -1, SQLITE_TRANSIENT) == SQLITE_OK else {
printError(with: "Bind for INSERT failed")
return
}
guard sqlite3_step(insertStatement) == SQLITE_DONE else {
printError(with: "Could not insert a row")
return
}
print("Successfully inserted row")
}
func printError(with message: String) {
let errmsg = sqlite3_errmsg(mySQLDB).flatMap { String(cString: $0) } ?? "Unknown error"
print(message, errmsg)
}
Где
internal let SQLITE_TRANSIENT = unsafeBitCast(-1, to: sqlite3_destructor_type.self)
Хотя я структурировал это с помощью операторов guard
, даже если вы остаетесь с вашим шаблоном if
, убедитесь, что вы только sqlite3_finalize
, если оператор подготовки завершился успешно , Нет смысла завершать финализацию, если подготовка не удалась.
Также целесообразно использовать SQLITE_TRANSIENT
для связанных параметров.