SQLite Swift db.prepare Optional() в значениях инструкции

В документации SQLite Swift есть ссылка на получение оператора результаты напрямую. У меня подготовлено много SQL-запросов, и я не очень хочу их рефакторить. Я бы скорее использовал их, поскольку они используют db.prepare, как показано ниже.

Операторы с результатами могут повторяться.

let stmt = try db.prepare("SELECT id, email FROM users")
for row in stmt {
    print("id: \(row[0]), email: \(row[1])")
    // id: Optional(1), email: Optional("[email protected]")
}

Возвращаемые значения всегда имеют "Необязательный()" вокруг них. Есть ли способ, которым мы можем просто вернуть необработанные значения строки без этого?


person Mark80    schedule 08.11.2015    source источник


Ответы (3)


Разверните значения, используя ! после переменной, как сказал @stephencelis:

let stmt = try db.prepare("SELECT id, email FROM users")
for row in stmt {
    print("id: \(row[0]!), email: \(row[1]!)")
}
person Ahmad    schedule 16.11.2015
comment
если бы мое заявление было SELECT * от пользователей. Вы знаете, как получить имя столбца вместе со значением в цикле? - person Lokesh Chowdary; 09.06.2017

Вы можете использовать https://github.com/groue/GRDB.swift. Он позволяет вам извлекать необязательные или необязательные параметры по вашему желанию:

for row in Row.fetch(db, "SELECT id, email FROM users") {
    let id: Int64 = row.value(atIndex: 0)
    let email: String = row.value(atIndex: 1)
    print(id, email)
}
person Gwendal Roué    schedule 24.11.2015

Типобезопасный API позволяет объявлять выражения необязательных типов, которые при извлечении из оператора не упаковываются.

Из README:

let users = Table("users")
let id = Expression<Int64>("id")
let name = Expression<String?>("name")
let email = Expression<String>("email")

try db.run(users.create { t in
    t.column(id, primaryKey: true)
    t.column(name)
    t.column(email, unique: true)
})
// CREATE TABLE "users" (
//     "id" INTEGER PRIMARY KEY NOT NULL,
//     "name" TEXT,
//     "email" TEXT NOT NULL UNIQUE
// )

let insert = users.insert(name <- "Alice", email <- "[email protected]")
let rowid = try db.run(insert)
// INSERT INTO "users" ("name", "email") VALUES ('Alice', '[email protected]')

for user in db.prepare(users) {
    println("id: \(user[id]), name: \(user[name]), email: \(user[email])")
    // id: 1, name: Optional("Alice"), email: [email protected]
}

Обратите внимание, что и id, и email, которые не являются необязательными, возвращаются как таковые.

person stephencelis    schedule 09.11.2015
comment
Извините, это не отвечает на мой вопрос. Я действительно не хочу типобезопасности, я хочу иметь возможность напрямую подключать свой SQL. Меня устраивает, что все ответы выводятся в виде строк, что является значением по умолчанию для SQLite. - person Mark80; 11.11.2015
comment
@Mark80 Поскольку значения SQLite динамически возвращаются во время выполнения, у небезопасной версии нет возможности узнать, каким будет массив значений, кроме необязательных. Однако вы можете использовать многочисленные дополнительные методы развертывания Swift, чтобы решить эту проблему! - person stephencelis; 11.11.2015
comment
@stephencelis, что, если запрос является соединением? - person SPatel; 03.09.2020