我正尝试创建注入查询SQLite的斯威夫特卡伦特3,但I'm功能具有逃逸字符的问题SQLite的SQLITE_MISUSE错误3
class SQLiteQueryManager {
static func insertNewStore(StoreId: Int64, Name: String, Address: String) -> Bool {
let vCommand = "INSERT INTO Store (Id, StoreId, Name, Address) VALUES (\(SQLiteConnectionManager.nextID("Store")),\(StoreId),'\(Name)','\(Address)')"
return SQLiteConnectionManager.insertDatabase(vCommand)
}
}
问题INS当I'm试图执行SQLiteConnectionManager.insertDatabase功能I'm发送到SQLite的字符串看起来是这样的:
INSERT INTO商店(ID,STOREID,姓名,地址)VALUES(1,1,\'蒂达 1 \ ','Dirección1')
SQLite拒绝查询。
我试过.replacingOccurrences(的:“\”,与:“”),但它不工作。
我在DB浏览器中的查询已经测试和工程
INSERT INTO商店(ID,STOREID,姓名,地址)VALUES(1,1, '蒂达 1', 'Dirección1')
如何删除\ ??
我SQLite的功能是这样的:
static func insertDatabase(_ pCommand: String) -> Bool
{
var vInsertStatement: OpaquePointer? = nil
let vDB: OpaquePointer = SQLiteConnectionManager.openDatabase()
var vReturn: Bool
if sqlite3_prepare_v2(vDB, pCommand.replacingOccurrences(of: "\\", with: ""), -1, &vInsertStatement, nil) == SQLITE_OK {
if sqlite3_step(vInsertStatement) == SQLITE_DONE {
print("insertDatabase() correct with statement \(pCommand)")
vReturn = true
} else {
print("insertDatabase() fail with statement \(pCommand)")
vReturn = false
}
} else {
print("insertDatabase() pCommand could not be prepared")
vReturn = false
}
sqlite3_finalize(vInsertStatement)
sqlite3_close(vDB)
return vReturn
}
Open函数返回OK,所以我的猜测是逃避char或类似的东西。
这是函数的打印输出:
insertDatabase()失败,并声明INSERT INTO商店(ID,STOREID, 姓名,地址)VALUES(1,1, '蒂达1',” Dirección1' )
更新1:
sqlite3_step(vInsertStatement)将返回SQLITE_MISUSE,但我找不到错误,DB是在包和执行open()表演工作和选择我正在做的工作,有什么可能是错的?
更新2:
我这是怎么开德DB返回OK:
private static func openDatabase() -> OpaquePointer {
var vDB: OpaquePointer? = nil
mDBURL = Bundle.main.url(forResource: "ARDB", withExtension: "db")
if let vDBURL = mDBURL{
if sqlite3_open(vDBURL.absoluteString, &vDB) == SQLITE_OK {
print("The database is open.")
} else {
print("Unable to open database in method openDatabase().")
}
return vDB!
} else {
return vDB!
}
}
然后我跑这来获取最后一个ID和工作原理:
static func nextID(_ pTableName: String!) -> Int
{
var vGetIdStatement: OpaquePointer? = nil
let vDB: OpaquePointer = SQLiteConnectionManager.openDatabase()
let vCommand = String(format: "SELECT Id FROM %@ ORDER BY Id DESC LIMIT 1", pTableName)
var vResult: Int32? = 0
if sqlite3_prepare_v2(vDB, vCommand, -1, &vGetIdStatement, nil) == SQLITE_OK {
if sqlite3_step(vGetIdStatement) == SQLITE_ROW {
vResult = sqlite3_column_int(vGetIdStatement, 0)
print("nextID() correct with statement \(vCommand)")
} else {
print("nextID() fail with statement \(vCommand)")
}
} else {
print("nextID() statement could not be prepared")
}
sqlite3_finalize(vGetIdStatement)
sqlite3_close(vDB)
var id: Int = 1
if (vResult != nil)
{
id = Int(vResult!) + 1
}
return id
}
我已经改变了我的插入功能,使用或不使用cString语句:
static func insertDatabase(_ pCommand: String) -> Bool
{
var vInsertStatement: OpaquePointer? = nil
let vDB: OpaquePointer = SQLiteConnectionManager.openDatabase()
var vReturn: Bool
if sqlite3_prepare_v2(vDB, pCommand.cString(using: .utf8), -1, &vInsertStatement, nil) == SQLITE_OK {
if sqlite3_step(vInsertStatement) == SQLITE_DONE {
print("insertDatabase() correct with statement \(pCommand)")
vReturn = true
} else {
print("insertDatabase() fail with statement \(pCommand) with error: \(sqlite3_step(vInsertStatement)) : \(sqlite3_errmsg(vDB))")
vReturn = false
}
} else {
print("insertDatabase() \(pCommand) could not be prepared with error: \(sqlite3_prepare_v2(vDB, pCommand.cString(using: .utf8), -1, &vInsertStatement, nil))")
vReturn = false
}
sqlite3_finalize(vInsertStatement)
sqlite3_close(vDB)
return vReturn
}
如果我在控制台打印sqlite3_errmsg(VDB)我得到这个没有帮助:
▿可选>▿一些:0x0000000105347e80 - pointerValue:4382293632
如果我打印sqlite3_step(vInsertStatement)返回21 SQLITE_MISUSE
任何帮助将不胜感激。
在此先感谢。
尝试使用[binding](https://sqlite.org/c3ref/bind_blob.html),而不是直接插入字符串。无论如何,出于安全原因,这是很好的做法。 –
我同意约翰蒙哥马利:你不应该逃避任何事情。 SQLite语句可以被赋值而不需要任何转义:这就是“语句绑定”。现在你也可以使用像https://github.com/groue/GRDB.swift这样的强大的Swift库:'try db.execute(“INSERT ... VALUES(?,...)”,arguments:[value, ...])# –
@GwendalRoué嗨sqlite3_step(vInsertStatement)正在返回SQLITE_MISUSE,但我找不到错误,数据库在捆绑和open()语句的工作和选择我在做的工作,什么可以是错的? –