Ich bin eine Funktion zu erstellen versuchen, die Abfragen zu SQLite in Swift 3, aber Ich habe Probleme mit den entweichenden ZeichenSQLite SQLITE_MISUSE Fehler in Swift 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)
}
}
Das Problem spritzt ins, dass, wenn ich bin versuchen SQLiteConnectionManager.insertDatabase auszuführen Funktion, um die Zeichenfolge, die ich bin zu SQLite Senden sieht wie folgt aus:
INSERT INTO Store (Id, StoreID, Name, Adresse) VALUES (1,1, \ 'Tienda 1 \ ', \' Dirección 1 \ ')
Und SQLite lehnt die Abfrage ab.
Ich habe versucht.replacingOccurrences (of: "\", mit: ""), aber es funktioniert nicht.
Ich habe im DB-Browser die Abfrage getestet und funktioniert
INSERT INTO Store (Id, StoreID, Name, Adresse) VALUES (1,1, 'Tienda 1', 'Dirección 1')
Wie kann ich das entfernen? diese
Meine SQLite-Funktion ist:
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
}
Die Open-Funktion Rückkehr ok so meine Vermutung das entweichende char oder so ähnlich ist.
Es handelt sich hierbei die Druckausgabe der Funktion:
insertDatabase() nicht mit Anweisung INSERT INTO Store (Id, StoreID, Name, Adresse) VALUES (1,1, 'Tienda 1',‘ Dirección 1')
UPDATE 1:
sqlite3_step (vInsertStatement) SQLITE_MISUSE zurückkehrt, aber ich kann den Fehler nicht finden, ist die DB in dem Bündel und der open() s Tattement Arbeit und eine Auswahl, die ich mache, funktioniert, was kann falsch sein?
UPDATE 2:
Dies ist, wie ich öffne de DB und kehrt 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!
}
}
Dann laufe ich dies die letzte Id zu erhalten und arbeitet:
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
}
Ich habe meine Einfügefunktion zu diesem mit oder ohne cString-Anweisung geändert:
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
}
Wenn ich die sqlite3_errmsg (VDB) in der Konsole aus erhalte ich diese, die nicht hilft:
▿ Optional> ▿ einige: 0x0000000105347e80 - pointer: 4382293632
Wenn ich print sqlite3_step (vInsertStatement) gibt 21 zurück SQLITE_MISUSE
Jede Hilfe wird geschätzt.
Vielen Dank im Voraus.
Verwenden Sie [binding] (https://sqlite.org/c3ref/bind_blob.html), anstatt die Strings direkt zu interpolieren. Aus Sicherheitsgründen ist es eine gute Übung. –
Ich stimme John Montgomery zu: Sie sollen nichts entgehen. SQLite-Anweisungen können mit Werten gespeist werden, ohne dass ein Entweichen erforderlich ist: das sind "Anweisungsbindungen". Jetzt können Sie auch eine robuste Swift-Bibliothek wie https://github.com/groue/GRDB.swift verwenden: 'try db.execute (" INSERT ... VALUES (?, ...) ", Argumente: [value, ...]) ' –
@ GwendalRoué Hallo sqlite3_step (vInsertStatement) gibt SQLITE_MISUSE zurück, aber ich kann den Fehler nicht finden, die DB ist im Bündel und die open() Anweisung funktioniert und eine Auswahl, die ich mache funktioniert, was kann falsch liegen? –