Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/116.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在iOS应用程序中删除SQLite中的记录_Ios_Sqlite - Fatal编程技术网

如何在iOS应用程序中删除SQLite中的记录

如何在iOS应用程序中删除SQLite中的记录,ios,sqlite,Ios,Sqlite,我正在尝试删除应用程序中的记录,但无法成功删除 下面是代码片段 if(trackingHistory != nil){ for (NSString *trkNum in trackingHistory) { if(trkNum == NULL){ continue; } if (sqlite3_open(dbpath, &database) == SQLITE_OK) {

我正在尝试删除应用程序中的记录,但无法成功删除

下面是代码片段

if(trackingHistory != nil){
    for (NSString *trkNum in trackingHistory) {
        if(trkNum == NULL){
            continue;
        }
        if (sqlite3_open(dbpath, &database) == SQLITE_OK)
        {
            NSString *querySQL = [NSString stringWithFormat: @"delete from TRACK_IT where TRACKING_NUMBER=\"%@\"",trkNum];
            const char *query_stmt = [querySQL UTF8String];
            sqlite3_prepare_v2(database, query_stmt,-1, &statement, NULL);
            if (sqlite3_step(statement) == SQLITE_DONE)
            {
                NSLog(@"deleted record");
                //return YES;
            } else {
                NSLog(@"Failed to delete record");
                // return NO;
            }
            sqlite3_reset(statement);
        }
    }
}

请告诉我可能有什么问题?

您的查询字符串似乎使用了双引号而不是单引号:

NSString *querySQL = [NSString
    stringWithFormat: @"delete from TRACK_IT where TRACKING_NUMBER=\"%@\"",trkNum];
//                                                                  ^   ^
//                                                                  |   |
//                                                              Here and Here
用单引号替换应修复此语法错误:

NSString *querySQL = [NSString
    stringWithFormat: @"delete from TRACK_IT where TRACKING_NUMBER='%@'",trkNum];

但是,除非您自己的程序内置了
trkNum
,否则不要使用这种删除记录的方法:如果数据来自用户,则您打开应用程序时会受到SQL注入攻击

您的查询字符串似乎使用双引号而不是单引号:

NSString *querySQL = [NSString
    stringWithFormat: @"delete from TRACK_IT where TRACKING_NUMBER=\"%@\"",trkNum];
//                                                                  ^   ^
//                                                                  |   |
//                                                              Here and Here
用单引号替换应修复此语法错误:

NSString *querySQL = [NSString
    stringWithFormat: @"delete from TRACK_IT where TRACKING_NUMBER='%@'",trkNum];
但是,除非
trkNum
内置在您自己的程序中,否则不要使用这种删除记录的方法:如果数据来自用户,则您打开应用程序会受到SQL注入攻击

从数据库中删除

-(iAction)删除:(ui按钮*)发件人{

}从数据库中删除

-(iAction)删除:(ui按钮*)发件人{


}ios swift中的简单删除操作

import UIKit
import SQLite3

let kCell = "Cell"

class ViewController: UIViewController {

    @IBOutlet weak var tfHeroName: UITextField!
    @IBOutlet weak var tfPowerRanking: UITextField!
    @IBOutlet weak var btnSave: UIButton!

    var db: OpaquePointer?
    private let refreshControl = UIRefreshControl()

    @IBOutlet weak var tableView: UITableView!

    var heroList = [Hero]()


    override func viewDidLoad() {
        super.viewDidLoad()

        //SetupPullTorefresh

        // Add Refresh Control to Table View
        if #available(iOS 10.0, *) {
            tableView.refreshControl = refreshControl
        } else {
            tableView.addSubview(refreshControl)
        }

        // Configure Refresh Control
        refreshControl.addTarget(self, action: #selector(refreshListData(_:)), for: .valueChanged)
        refreshControl.tintColor = #colorLiteral(red: 0.8078431487, green: 0.02745098062, blue: 0.3333333433, alpha: 1)
        refreshControl.attributedTitle = NSAttributedString(string: "Loading...")

        //database file address
        let fileURL = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
            .appendingPathComponent("HeroesDatabase.sqlite")

        //opening database
        if sqlite3_open(fileURL.path, &db) != SQLITE_OK {
            print("error opening database")
        }

        //creating table
        if sqlite3_exec(db, "CREATE TABLE IF NOT EXISTS Heroes (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, powerrank INTEGER)", nil, nil, nil) != SQLITE_OK {
            let errmsg = String(cString: sqlite3_errmsg(db)!)
            print("error creating table: \(errmsg)")
        }

        readValues()

    }

    @IBAction func tapOnBtnSave(_ sender: Any) {
        let name = tfHeroName.text?.trimmingCharacters(in: .whitespacesAndNewlines)
        let poweRanking = tfPowerRanking.text?.trimmingCharacters(in: .whitespacesAndNewlines)

        if name!.isEmpty {
            tfHeroName.layer.borderColor = #colorLiteral(red: 0.8058760762, green: 0.2736578584, blue: 0.1300437152, alpha: 1)
        }

        if poweRanking!.isEmpty {
            tfPowerRanking.layer.borderColor = #colorLiteral(red: 0.8058760762, green: 0.2736578584, blue: 0.1300437152, alpha: 1)
        }

        //creating a statement
        var stmt: OpaquePointer?

        //the insert query
        let queryString = "INSERT INTO Heroes (name, powerrank) VALUES (?,?)"

        //preparing the query
        if sqlite3_prepare(db, queryString, -1, &stmt, nil)  != SQLITE_OK {

            let errmsg = String(cString: sqlite3_errmsg(db)!)
            print("error preparing insert: \(errmsg)")
            return

        }

        //binding the parameters

        if sqlite3_bind_text(stmt, 1, name, -1, nil) != SQLITE_OK{
            let errmsg = String(cString: sqlite3_errmsg(db)!)
            print("failure binding name: \(errmsg)")
            return
        }

        if sqlite3_bind_int(stmt, 2, (poweRanking! as NSString).intValue) != SQLITE_OK {
            let errmsg = String(cString: sqlite3_errmsg(db))
            print("failure binding name: \(errmsg)")
        }

        //executing the query to insert values
        if sqlite3_step(stmt) != SQLITE_DONE {
            let errmsg = String(cString: sqlite3_errmsg(db)!)
            print("failure binding name: \(errmsg)")

        }

        //emptying the textfields
        tfHeroName.text = ""
        tfPowerRanking.text = ""


    }

    //MARK: Read Operation
    func readValues(){
        heroList.removeAll()

        let queryString = "SELECT * FROM Heroes"

        var stmt:OpaquePointer?

        if sqlite3_prepare(db, queryString, -1, &stmt, nil) != SQLITE_OK{
            let errmsg = String(cString: sqlite3_errmsg(db)!)
            print("error preparing insert: \(errmsg)")
            return
        }

        while(sqlite3_step(stmt) == SQLITE_ROW){
            let id = sqlite3_column_int(stmt, 0)
            let name = String(cString: sqlite3_column_text(stmt, 1))
            let powerrank = sqlite3_column_int(stmt, 2)

            heroList.append(Hero(id: Int(id), name: String(describing: name), powerRanking: Int(powerrank)))
        }

        self.tableView.reloadData()
        self.refreshControl.endRefreshing()
    }

    //MARK: Delete Operation
    func deleteItemFromList(itemId: Int32){

        let deleteStatementStirng = "DELETE FROM Heroes WHERE id = ?;"
        var deleteStatement: OpaquePointer? = nil

        if sqlite3_prepare(db, deleteStatementStirng, -1, &deleteStatement, nil) == SQLITE_OK {

            sqlite3_bind_int(deleteStatement, 1, itemId)

            if sqlite3_step(deleteStatement) == SQLITE_DONE {
                print("Successfully deleted row.")
            } else {
                print("Could not delete row.")
            }
        } else {
            print("DELETE statement could not be prepared")
        }

        sqlite3_finalize(deleteStatement)
        print("delete")
    }


    @objc private func refreshListData(_ sender: Any) {
        readValues()
    }

}

extension ViewController : UITableViewDelegate, UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return heroList.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell(style: UITableViewCell.CellStyle.default, reuseIdentifier: "cell")
        let hero: Hero
        hero = heroList[indexPath.row]
        cell.textLabel?.text = hero.name
        return cell
    }

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {

        if editingStyle == UITableViewCell.EditingStyle.delete {
            heroList.remove(at: indexPath.row)
            deleteItemFromList(itemId: Int32(heroList[indexPath.row].powerRanking))
            tableView.deleteRows(at: [indexPath], with: UITableView.RowAnimation.automatic)
            tableView.reloadData()
        }

    }

    func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        return true
    }

}


class Hero {

    var id: Int
    var name: String?
    var powerRanking: Int

    init(id: Int, name: String?, powerRanking: Int){
        self.id = id
        self.name = name
        self.powerRanking = powerRanking
    }
}

ios swift中的简单删除操作

import UIKit
import SQLite3

let kCell = "Cell"

class ViewController: UIViewController {

    @IBOutlet weak var tfHeroName: UITextField!
    @IBOutlet weak var tfPowerRanking: UITextField!
    @IBOutlet weak var btnSave: UIButton!

    var db: OpaquePointer?
    private let refreshControl = UIRefreshControl()

    @IBOutlet weak var tableView: UITableView!

    var heroList = [Hero]()


    override func viewDidLoad() {
        super.viewDidLoad()

        //SetupPullTorefresh

        // Add Refresh Control to Table View
        if #available(iOS 10.0, *) {
            tableView.refreshControl = refreshControl
        } else {
            tableView.addSubview(refreshControl)
        }

        // Configure Refresh Control
        refreshControl.addTarget(self, action: #selector(refreshListData(_:)), for: .valueChanged)
        refreshControl.tintColor = #colorLiteral(red: 0.8078431487, green: 0.02745098062, blue: 0.3333333433, alpha: 1)
        refreshControl.attributedTitle = NSAttributedString(string: "Loading...")

        //database file address
        let fileURL = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
            .appendingPathComponent("HeroesDatabase.sqlite")

        //opening database
        if sqlite3_open(fileURL.path, &db) != SQLITE_OK {
            print("error opening database")
        }

        //creating table
        if sqlite3_exec(db, "CREATE TABLE IF NOT EXISTS Heroes (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, powerrank INTEGER)", nil, nil, nil) != SQLITE_OK {
            let errmsg = String(cString: sqlite3_errmsg(db)!)
            print("error creating table: \(errmsg)")
        }

        readValues()

    }

    @IBAction func tapOnBtnSave(_ sender: Any) {
        let name = tfHeroName.text?.trimmingCharacters(in: .whitespacesAndNewlines)
        let poweRanking = tfPowerRanking.text?.trimmingCharacters(in: .whitespacesAndNewlines)

        if name!.isEmpty {
            tfHeroName.layer.borderColor = #colorLiteral(red: 0.8058760762, green: 0.2736578584, blue: 0.1300437152, alpha: 1)
        }

        if poweRanking!.isEmpty {
            tfPowerRanking.layer.borderColor = #colorLiteral(red: 0.8058760762, green: 0.2736578584, blue: 0.1300437152, alpha: 1)
        }

        //creating a statement
        var stmt: OpaquePointer?

        //the insert query
        let queryString = "INSERT INTO Heroes (name, powerrank) VALUES (?,?)"

        //preparing the query
        if sqlite3_prepare(db, queryString, -1, &stmt, nil)  != SQLITE_OK {

            let errmsg = String(cString: sqlite3_errmsg(db)!)
            print("error preparing insert: \(errmsg)")
            return

        }

        //binding the parameters

        if sqlite3_bind_text(stmt, 1, name, -1, nil) != SQLITE_OK{
            let errmsg = String(cString: sqlite3_errmsg(db)!)
            print("failure binding name: \(errmsg)")
            return
        }

        if sqlite3_bind_int(stmt, 2, (poweRanking! as NSString).intValue) != SQLITE_OK {
            let errmsg = String(cString: sqlite3_errmsg(db))
            print("failure binding name: \(errmsg)")
        }

        //executing the query to insert values
        if sqlite3_step(stmt) != SQLITE_DONE {
            let errmsg = String(cString: sqlite3_errmsg(db)!)
            print("failure binding name: \(errmsg)")

        }

        //emptying the textfields
        tfHeroName.text = ""
        tfPowerRanking.text = ""


    }

    //MARK: Read Operation
    func readValues(){
        heroList.removeAll()

        let queryString = "SELECT * FROM Heroes"

        var stmt:OpaquePointer?

        if sqlite3_prepare(db, queryString, -1, &stmt, nil) != SQLITE_OK{
            let errmsg = String(cString: sqlite3_errmsg(db)!)
            print("error preparing insert: \(errmsg)")
            return
        }

        while(sqlite3_step(stmt) == SQLITE_ROW){
            let id = sqlite3_column_int(stmt, 0)
            let name = String(cString: sqlite3_column_text(stmt, 1))
            let powerrank = sqlite3_column_int(stmt, 2)

            heroList.append(Hero(id: Int(id), name: String(describing: name), powerRanking: Int(powerrank)))
        }

        self.tableView.reloadData()
        self.refreshControl.endRefreshing()
    }

    //MARK: Delete Operation
    func deleteItemFromList(itemId: Int32){

        let deleteStatementStirng = "DELETE FROM Heroes WHERE id = ?;"
        var deleteStatement: OpaquePointer? = nil

        if sqlite3_prepare(db, deleteStatementStirng, -1, &deleteStatement, nil) == SQLITE_OK {

            sqlite3_bind_int(deleteStatement, 1, itemId)

            if sqlite3_step(deleteStatement) == SQLITE_DONE {
                print("Successfully deleted row.")
            } else {
                print("Could not delete row.")
            }
        } else {
            print("DELETE statement could not be prepared")
        }

        sqlite3_finalize(deleteStatement)
        print("delete")
    }


    @objc private func refreshListData(_ sender: Any) {
        readValues()
    }

}

extension ViewController : UITableViewDelegate, UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return heroList.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell(style: UITableViewCell.CellStyle.default, reuseIdentifier: "cell")
        let hero: Hero
        hero = heroList[indexPath.row]
        cell.textLabel?.text = hero.name
        return cell
    }

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {

        if editingStyle == UITableViewCell.EditingStyle.delete {
            heroList.remove(at: indexPath.row)
            deleteItemFromList(itemId: Int32(heroList[indexPath.row].powerRanking))
            tableView.deleteRows(at: [indexPath], with: UITableView.RowAnimation.automatic)
            tableView.reloadData()
        }

    }

    func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        return true
    }

}


class Hero {

    var id: Int
    var name: String?
    var powerRanking: Int

    init(id: Int, name: String?, powerRanking: Int){
        self.id = id
        self.name = name
        self.powerRanking = powerRanking
    }
}

我们不是读心术的人。请告诉我们运行此代码时会发生什么?数据库打开了吗?调用
sqlite3\u prepare\u v2
是否成功(您需要检查结果)?
sqlite3\u步骤
返回什么?当其中任何一个失败时,使用
sqlite3\u errmsg
获取错误。断点,跳过etcAlso,为什么在循环中打开数据库?在循环外打开一次(循环后关闭)。此外,在循环之前,您应该只准备一次语句。是否需要提交语句?调试时的条件-->if(sqlite3_步骤(语句)==SQLITE_完成)始终为true。但是,在试图获取删除的记录时,我总是能够将其取回!我们不是读心术的人。请告诉我们运行此代码时会发生什么?数据库打开了吗?调用
sqlite3\u prepare\u v2
是否成功(您需要检查结果)?
sqlite3\u步骤
返回什么?当其中任何一个失败时,使用
sqlite3\u errmsg
获取错误。断点,跳过etcAlso,为什么在循环中打开数据库?在循环外打开一次(循环后关闭)。此外,在循环之前,您应该只准备一次语句。是否需要提交语句?调试时的条件-->if(sqlite3_步骤(语句)==SQLITE_完成)始终为true。但是,在试图获取删除的记录时,我总是能够将其取回!解释使用字符串格式时正确使用
sqlite3\u bind\u xxx
可能有助于澄清您的最后一点。解释使用字符串格式时正确使用
sqlite3\u bind\u xxx
可能有助于澄清您的最后一点。