Swift - SQLite でデータを挿入 (INSERT)

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

Swift で SQLite のテーブルを作成する」のコードに、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
);


まずは、Student オブジェクトを受け取り、students テーブルにデータを挿入する insertStudent 関数を作ります。

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

func insertStudent(student: Student) -> Bool {
    let insertSql = """
                    INSERT INTO students
                        (student_id, student_number, first_name, last_name, age)
                        VALUES
                        (?, ?, ?, ?, ?);
                    """;
    var insertStmt: OpaquePointer? = nil
    
    if sqlite3_prepare_v2(db, (insertSql as NSString).utf8String, -1, &insertStmt, nil) != SQLITE_OK {
        print("db error: \(getDBErrorMessage(db))")
        return false
    }
    
    sqlite3_bind_int(insertStmt, 1,Int32(student.StudentID))
    sqlite3_bind_text(insertStmt, 2, (student.StudentNumber as NSString).utf8String, -1, nil)
    sqlite3_bind_text(insertStmt, 3, (student.FirstName as NSString).utf8String, -1, nil)
    sqlite3_bind_text(insertStmt, 4, (student.LastName as NSString).utf8String, -1, nil)
    
    if student.Age == nil {
        sqlite3_bind_null(insertStmt, 5)
    } else {
        sqlite3_bind_int(insertStmt, 5, Int32(student.Age!))
    }
    
    if sqlite3_step(insertStmt) != SQLITE_DONE {
        print("db error: \(getDBErrorMessage(db))")
        sqlite3_finalize(insertStmt)
        return false
    }
    sqlite3_finalize(insertStmt)
    return true
}

Swift - SQLite でデータを挿入 (INSERT) 1

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

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


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 */
);

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

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


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

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


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

文字列をバインドするには sqlite3_bind_text()、整数をバインドするには sqlite3_bind_int() のようにデータ型によって違う関数を使います。

15 行目では sqlite3_bind_int() を使って、insertSql 文のひとつめの ? に student.StudentID を Int32 に変換してバインドしています。

16 行目では sqlite3_bind_text() を使って、insertSql 文の二つ目の ? に student.StudentNumber を UTF-8 に変換してバインドしています。

同様に 17、18 行目では sqlite3_bind_text() を使って、三つ目と四つ目の ? に student.FirstName と student.LastName をバインドしています。

20 ~ 24 行目では、五つ目の ? に student.Age が null の時は sqlite3_bind_null() を使って null をバインドして、null 出ない時は sqlite3_bind_int() を使って student.Age をバインドしています。


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

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

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

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


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


students テーブルにデータを挿入する

それでは、作った insertStudent() 関数を使って、データを挿入してみます。

ViewController.swift の viewDidLoad() に以下のコードを追加してください。

let 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")
}

1 行目で student1 という Student 型のオブジェクトを生成しています。

3 ~ 7 行目では、先ほど作った関数 DBService.shared.insertStudent() に student1 を渡してデータを挿入しています。


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

Opened connection to database
Insert success

Swift - SQLite でデータを挿入 (INSERT) 2


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

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

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


students テーブルができていて、データが一行挿入されています。

Swift - SQLite でデータを挿入 (INSERT) 3

Swift - SQLite でデータを挿入 (INSERT) 4


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

次は Swift で SQLite のデータを更新します。

次の記事 「Swift - SQLite でデータを更新 (UPDATE)」

© 2024 iOS 開発入門