iOS Swift 插入 sqlite FMDB
Posted
技术标签:
【中文标题】iOS Swift 插入 sqlite FMDB【英文标题】:iOS Swift insert into sqlite FMDB 【发布时间】:2016-04-02 18:40:09 【问题描述】:这是我的问题:我有这个葡萄酒应用程序,它以漂亮的表格视图向用户显示我的数据库内容。使用 FMDB executeQuery 函数,我可以很容易地从中获取数据,但是每当我尝试向 SQLite 表添加内容时,它就会失败。
这是我使用的代码。
do
try sharedInstance.database!.executeUpdate("INSERT INTO wine VALUES (?, ?, ?)", values: [id, name, wineType])
catch
print("error \(error)")
我尝试将所有内容放在一个字符串中,然后将其作为第一个参数发送,并将 nil 作为第二个参数,但同样失败。此语法来自Data Sanitisation section in the FMDB README from github
我发现了一些类似的案例,但答案都是 Objective-C。请注意,我对 ios 完全陌生,对 Objective-C 一无所知,这是我的第一个 Swift 应用程序。
我做错了什么?
【问题讨论】:
您可以为 SQLite 使用 Swift 包装器。现在有好的,比如github.com/groue/GRDB.swift 【参考方案1】:语法是正确的,可能你想检查一下:
你事先打电话给sharedInstance.database!.open()
您的表格仅包含 3 列
如果您在项目中包含FMDatabaseAdditionsVariadic.swift
和FMDatabaseVariadic.swift
,您可以像这样调用executeUpdate
:
do
try sharedInstance.database!.executeUpdate("INSERT INTO wine VALUES (?, ?, ?)", id, name, wineType)
catch
print("error \(error)")
【讨论】:
【参考方案2】:注意 :- 在这里,我将使用 FMDB 快速向您发送在数据库中插入记录的代码。
import UIKit
class FMDBDatabaseSignUpVC: UIViewController
@IBOutlet weak var txtFirstNameOutlet: UITextField!
@IBOutlet weak var txtLastNameOutlet: UITextField!
@IBOutlet weak var txtEMailIDOutlet: UITextField!
@IBOutlet weak var txtPasswordOutlet: UITextField!
var databasePath = NSString()
override func viewDidLoad()
super.viewDidLoad()
let filemgr = NSFileManager.defaultManager()
let dirPaths =
NSSearchPathForDirectoriesInDomains(.DocumentDirectory,
.UserDomainMask, true).first as String!
databasePath = (dirPaths as NSString).stringByAppendingPathComponent("swiftDemo.db")
if !filemgr.fileExistsAtPath(databasePath as String)
let contactDB = FMDatabase (path: databasePath as String)
if contactDB == nil
print(contactDB.lastErrorMessage())
// Do any additional setup after loading the view.
@IBAction func btnSaveAction(sender: UIButton)
let contactDB = FMDatabase (path: databasePath as String)
if contactDB.open()
let InsertQry = "insert into userInfo (userFirstName, userLastName,userEmailID,userPassword) values ('\(txtFirstNameOutlet.text!)','\(txtLastNameOutlet.text!)','\(txtEMailIDOutlet.text!)','\(txtPasswordOutlet.text!)')"
let result = contactDB.executeUpdate(InsertQry, withArgumentsInArray: nil)
if !result
print(contactDB.lastErrorMessage())
else
print("Success")
txtFirstNameOutlet.text=""
txtLastNameOutlet.text=""
txtEMailIDOutlet.text=""
txtPasswordOutlet.text=""
【讨论】:
【参考方案3】:在某些情况下executeUpdate
会失败,所以首先尝试使用executeQuery
或executeStatments
来解决问题。
如果它不起作用,我认为打开数据库后执行sql语句的正确方法是:
executeUpdate("INSERT INTO wine VALUES ('\(id)', '\(name)', '\(wineType)')")
语句执行成功后关闭数据库。您在数据库中的 id 类型是什么?它是自动递增的吗?
您在控制台中遇到什么错误?尝试使用断点,看看发生了什么。
更新 之前的代码不适合在生产环境中使用,因为它会受到 SQL 注入 Reference 的影响,我认为在 iOS 上使用 FMDB,之前的代码可以使用。
【讨论】:
不要通过连接形成字符串。如果 wineType 等于 "); DROP TABLE wine;" 怎么办? 减一,因为答案推荐不安全代码,受 SQL 注入影响。检查***.com/questions/332365/… @Gwendal,您最好修改答案而不是投反对票。我们需要高质量的答案,为什么不通过编辑答案来提供帮助?! @Jeyhey,我已经用你的参考更新了答案。谢谢 除了 SQL 注入问题(取决于应用程序和上下文,可能会或可能不会对您产生影响)之外,还有在使用时包含撇号(单引号)的问题方法。我不得不想象,葡萄酒名称中包含撇号的情况并不少见。在这些情况下,这会中断。【参考方案4】:这应该可行:
do
try sharedInstance.database!.executeUpdate("INSERT INTO wine(id, name, wineType) VALUES (?, ?, ?)", values: [id, name, wineType])
catch
print("error \(error)")
【讨论】:
以上是关于iOS Swift 插入 sqlite FMDB的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 swift 在 iOS coredata sqlite 中启用 DELETE MODE
如何在 IOS Swift 中使用 SQLite 使用 FMDB 处理多个线程