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
}
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
シミュレーターで実行して、DB Browser for SQLite でできた SQLite のファイルを開いて確認してみます。
SQLite のファイルの場所は「SQLite ファイルの場所を確認する方法」でご確認ください。
DB Browser for SQLite については後ほど別の記事でご紹介します。
students テーブルに入っていた student_id = 1 のデータが削除されています。
以上、Swift で SQLite のテーブルにデータを削除する方法をご説明しました。