Swift - SQLite でデータを削除 (DELETE)

ここでは、Swift で SQLite のテーブルのデータを削除する方法をご説明します。

Swift - SQLite でデータを取得 (SELECT)」のコードに、SQLite でデータを削除するコードを追加します。

students テーブルのデータを削除する関数を定義する

ここまでで、次のような Student 構造体のデータを保持する SQLite の students テーブルにデータを挿入・更新・取得をしてきました。

struct Student {
    var StudentID: Int
    var StudentNumber: String
    var FirstName: String
    var LastName: String
    var Age: Int?
    
    init(studentID: Int, studentNumber: String, firstName: String, lastName: String, age: Int?) {
        self.StudentID = studentID
        self.StudentNumber = studentNumber
        self.FirstName = firstName
        self.LastName = lastName
        self.Age = age
    }
}
CREATE TABLE IF NOT EXISTS students (
    student_id INTEGER NOT NULL PRIMARY KEY,
    student_number TEXT NOT NULL,
    first_name TEXT NULL,
    last_name TEXT NULL,
    age INTEGER NULL
);

今回は、studentID を受け取り、students テーブルからその student_id を持つデータを削除する deleteStudent 関数を作ります。

指定された studentID は students テーブルに存在している前提ですすめます。


DBService.swift ファイルを開き以下のコードを追加してください。

func deleteStudent(studentID: Int) -> Bool {
    let deleteSql = "DELETE FROM students WHERE student_id = ?;";
    var deleteStmt: OpaquePointer? = nil
    
    if sqlite3_prepare_v2(db, (deleteSql as NSString).utf8String, -1, &deleteStmt, nil) != SQLITE_OK {
        print("db error: \(getDBErrorMessage(db))")
        return false
    }
    
    sqlite3_bind_int(deleteStmt, 1,Int32(studentID))
    
    if sqlite3_step(deleteStmt) != SQLITE_DONE {
        print("db error: \(getDBErrorMessage(db))")
        sqlite3_finalize(deleteStmt)
        return false
    }

    sqlite3_finalize(deleteStmt)
    return true
}

Swift - SQLite でデータを削除 (DELETE) 1

deleteStudent 関数のコードを順を追ってご説明します。

まず、2 行目で、SQLite の DELETE 文のスクリプトを deleteSql に定義しています。


SQLite で SQL 文を実行するには、その前にステートメントを準備用の関数をつかって、バイトコードプログラムにコンパイルする必要があります。

ここでは、sqlite3_prepare_v2() 関数を使って SQL 文をコンパイルしています。

int sqlite3_prepare_v2(
  sqlite3 *db,            /* Database handle */
  const char *zSql,       /* SQL statement, UTF-8 encoded */
  int nByte,              /* Maximum length of zSql in bytes. */
  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
  const char **pzTail     /* OUT: Pointer to unused portion of zSql */
);

3 行目で、sqlite3_prepare_v2() 関数に渡すステートメントハンドル用の OpaquePointer? 型の変数の deleteStmt を定義しています。

5 行目で、sqlite3_prepare_v2() 関数に、データベースを開いた時に取得した db ハンドル、deleteSql を UTF-8 に変換した文字列、上で定義した &deleteStmt などを渡して実行しています。


sqlite3_prepare_v2() 関数 は成功したら SQLITE_OK を返し、失敗するとエラーコードを返します。

失敗した時には getDBErrorMessage() 関数を使ってエラーコードをプリントし、false を返しています。


10 行目では、上で準備したステートメントに、値をバインドしています。

sqlite3_bind_int() を使って、deleteSql 文のひとつめの ? に studentID を Int32 に変換してバインドしています。


12 ~ 16 行目では、sqlite3_step() 関数を使って、コンパイルした SQL文を評価して実行しています。

sqlite3_step() 関数は成功すると SQLITE_DONE を返します。

失敗した時は getDBErrorMessage() 関数を使ってエラーコードをプリントしています。

return する前に、sqlite3_finalize() 関数で、prepare したステートメントオブジェクトを destroy しています。

指定した student_id を持つレコードが存在しなくてもエラーにはなりません。


18 ~ 19 行目で、sqlite3_finalize() 関数で、prepare したステートメントオブジェクトを destroy してから true を返しています。


students テーブルのデータを削除する

それでは、作った deleteStudent() 関数を使って、データを削除してみます。

ViewController.swift の viewDidLoad() のコードを次のように変更してください。

//var student1 = Student(studentID: 1, studentNumber: "S000001", firstName: "Yuta", lastName: "Tanaka", age: 16)
//
//if DBService.shared.insertStudent(student: student1) {
//    print("Insert success")
//} else {
//    print("Insert Failed")
//}

//student1.LastName = "Yamada"
//student1.Age = 17
//
//if DBService.shared.updateStudent(student: student1) {
//    print("Update success")
//} else {
//    print("Update Failed")
//}

//let (success, errorMessage, student) = DBService.shared.getStudent(studentId: 2)
//if(success){
//    if let student = student {
//        print(student)
//    } else {
//        print("Student not found")
//    }
//} else {
//    print(errorMessage ?? "Error")
//}

if DBService.shared.deleteStudent(studentID: 1) {
    print("Delete success")
} else {
    print("Delete Failed")
}

29 行目で、先ほど作った関数 DBService.shared.deleteStudent() に studentID: 1 を渡してデータを削除しています。


これを実行して、データの削除が成功すると、デバッガーのアウトプットコンソールに次のように表示されます。

Opened connection to database
Delete success

Swift - SQLite でデータを削除 (DELETE) 2


シミュレーターで実行して、DB Browser for SQLite でできた SQLite のファイルを開いて確認してみます。

SQLite のファイルの場所は「SQLite ファイルの場所を確認する方法」でご確認ください。

DB Browser for SQLite については後ほど別の記事でご紹介します。


students テーブルに入っていた student_id = 1 のデータが削除されています。

Swift - SQLite でデータを削除 (DELETE) 3

Swift - SQLite でデータを削除 (DELETE) 4


以上、Swift で SQLite のテーブルにデータを削除する方法をご説明しました。

© 2024 iOS 開発入門