SQLite插入Swift导致循环Swift 3.1

时间:2017-05-01 17:22:48

标签: swift sqlite

我正在尝试使用Swift 3.1将数组插入SQLite

当我使用“if”语句时,可以实现单个插入而不会出现问题。但是,我需要这个来插入一个数组,所以我需要使用“while”语句。但是,这会导致insert语句在循环中运行。

func insertDiveGear() {
    var statement: OpaquePointer? = nil

    let names = itemDataArray

    let update = "INSERT INTO DiveGearForDive (id, name) VALUES (?, ?);"

    while sqlite3_prepare_v2(self.dlDatabase.database, update, -1, &statement, nil) == SQLITE_OK {

        for (_ , name) in names.enumerated() {

            let diveNumber = Int32(diveNumber)

            sqlite3_bind_int(statement, 1, diveNumber)
            sqlite3_bind_text(statement, 2, name, -1, nil)

            if sqlite3_step(statement) == SQLITE_DONE {
                print("Successfully inserted row.")
            } else {
                print("Could not insert row.")
            }

        }

        sqlite3_finalize(statement)
    }
}

任何帮助都会很棒

1 个答案:

答案 0 :(得分:2)

您的代码无法退出while循环,因为sqlite3_prepare_v2不会失败。但是不需要while循环。你可以这样做:

func insertDiveGear() {
    var statement: OpaquePointer? = nil

    let names = itemDataArray

    let update = "INSERT INTO DiveGearForDive (id, name) VALUES (?, ?);"

    for (diveNumber, name) in names.enumerated() {
        if sqlite3_prepare_v2(dlDatabase.database, update, -1, &statement, nil) == SQLITE_OK {
            sqlite3_bind_int(statement, 1, Int32(diveNumber))
            sqlite3_bind_text(statement, 2, name, -1, SQLITE_TRANSIENT)

            if sqlite3_step(statement) == SQLITE_DONE {
                print("Successfully inserted row.")
            } else {
                print("Could not insert row.")
            }

            sqlite3_finalize(statement)
        }
    }
}

或者,更高效,只准备一次语句,然后循环绑定,步进,然后重置:

func insertDiveGear() {
    var statement: OpaquePointer? = nil

    let names = itemDataArray

    let update = "INSERT INTO DiveGearForDive (id, name) VALUES (?, ?);"

    guard sqlite3_prepare_v2(dlDatabase.database, update, -1, &statement, nil) == SQLITE_OK else {
        let errmsg = String(cString: sqlite3_errmsg(dlDatabase.database))
        print("failure preparing: \(errmsg)")
        return
    }

    for (diveNumber, name) in names.enumerated() {
        sqlite3_bind_int(statement, 1, Int32(diveNumber))
        sqlite3_bind_text(statement, 2, name, -1, SQLITE_TRANSIENT)

        if sqlite3_step(statement) == SQLITE_DONE {
            print("Successfully inserted row.")
        } else {
            print("Could not insert row.")
        }

        sqlite3_reset(statement)
    }

    sqlite3_finalize(statement)
}

我不知道该let diveNumber = Int32(diveNumber)行(diveNumber在哪里定义;使用相同名称?等),所以请根据需要调整,但主要问题是为什么循环没有退出,因为如果SQL格式正确,sqlite3_prepare_v2将始终返回SQLITE_OK

另请注意,我将SQLITE_TRANSIENT常量(请参阅Cannot invoke initializer for type 'sqlite3_destructor_type')与sqlite3_bind_text结合使用,以确保SQLite创建自己的字符串副本,这在处理时是谨慎的用Swift字符串。