[解決済み] Swift で SQLite データベースにアクセスする
質問
Swiftのコードで、アプリ内のSQLiteデータベースにアクセスする方法を探しています。
Objective C で SQLite Wrapper を使用し、ブリッジングヘッダーを使用できることを知っていますが、私はむしろ、このプロジェクトを完全に Swift で行うことができるようにしたいと思っています。これを行う方法はありますか、もしそうなら、誰かがクエリを送信し、行を取得する方法などを示す参照に私を指し示すことができますか?
どのように解決するのですか?
おそらく多くの SQLite ラッパーのうちの 1 つを使うべきですが、SQLite ライブラリーを自分で呼び出す方法を知りたかったら、そうするでしょう。
-
SQLite の C 呼び出しを処理するために Swift プロジェクトを構成します。Xcode 9 以降を使用している場合は、単に行うことができます。
import SQLite3
-
データベースを作成/オープンします。
let fileURL = try! FileManager.default .url(for: .applicationSupportDirectory, in: .userDomainMask, appropriateFor: nil, create: true) .appendingPathComponent("test.sqlite") // open database var db: OpaquePointer? guard sqlite3_open(fileURL.path, &db) == SQLITE_OK else { print("error opening database") sqlite3_close(db) db = nil return }
注意:データベースのオープンに失敗したときに閉じるのはおかしいと思うかもしれません。
sqlite3_open
ドキュメント は、メモリリークを避けるためにそうしなければならないことを明示しています。開くときにエラーが発生するかどうかに関わらず、関連するリソースは データベース接続 ハンドルに渡すことで解放する必要があります。
sqlite3_close()
に渡して解放する必要があります。 -
使用方法
sqlite3_exec
を使ってSQLを実行します(例:create table)。if sqlite3_exec(db, "create table if not exists test (id integer primary key autoincrement, name text)", nil, nil, nil) != SQLITE_OK { let errmsg = String(cString: sqlite3_errmsg(db)!) print("error creating table: \(errmsg)") }
-
使用方法
sqlite3_prepare_v2
でSQLを準備します。?
というプレースホルダーを用意して、そこに値をバインドします。var statement: OpaquePointer? if sqlite3_prepare_v2(db, "insert into test (name) values (?)", -1, &statement, nil) != SQLITE_OK { let errmsg = String(cString: sqlite3_errmsg(db)!) print("error preparing insert: \(errmsg)") } if sqlite3_bind_text(statement, 1, "foo", -1, SQLITE_TRANSIENT) != SQLITE_OK { let errmsg = String(cString: sqlite3_errmsg(db)!) print("failure binding foo: \(errmsg)") } if sqlite3_step(statement) != SQLITE_DONE { let errmsg = String(cString: sqlite3_errmsg(db)!) print("failure inserting foo: \(errmsg)") }
注意:これは
SQLITE_TRANSIENT
定数 を実装することができます。 を以下のように実装します。internal let SQLITE_STATIC = unsafeBitCast(0, to: sqlite3_destructor_type.self) internal let SQLITE_TRANSIENT = unsafeBitCast(-1, to: sqlite3_destructor_type.self)
-
SQLをリセットして別の値を挿入します。この例では、挿入する
NULL
という値を挿入します。if sqlite3_reset(statement) != SQLITE_OK { let errmsg = String(cString: sqlite3_errmsg(db)!) print("error resetting prepared statement: \(errmsg)") } if sqlite3_bind_null(statement, 1) != SQLITE_OK { let errmsg = String(cString: sqlite3_errmsg(db)!) print("failure binding null: \(errmsg)") } if sqlite3_step(statement) != SQLITE_DONE { let errmsg = String(cString: sqlite3_errmsg(db)!) print("failure inserting null: \(errmsg)") }
-
プリペアドステートメントをファイナライズして、そのプリペアドステートメントに関連するメモリを回復します。
if sqlite3_finalize(statement) != SQLITE_OK { let errmsg = String(cString: sqlite3_errmsg(db)!) print("error finalizing prepared statement: \(errmsg)") } statement = nil
-
テーブルから値を選択するための新しいステートメントを用意し、値を取得するループを実行します。
if sqlite3_prepare_v2(db, "select id, name from test", -1, &statement, nil) != SQLITE_OK { let errmsg = String(cString: sqlite3_errmsg(db)!) print("error preparing select: \(errmsg)") } while sqlite3_step(statement) == SQLITE_ROW { let id = sqlite3_column_int64(statement, 0) print("id = \(id); ", terminator: "") if let cString = sqlite3_column_text(statement, 1) { let name = String(cString: cString) print("name = \(name)") } else { print("name not found") } } if sqlite3_finalize(statement) != SQLITE_OK { let errmsg = String(cString: sqlite3_errmsg(db)!) print("error finalizing prepared statement: \(errmsg)") } statement = nil
-
データベースを閉じます。
if sqlite3_close(db) != SQLITE_OK { print("error closing database") } db = nil
Swift 2 およびそれ以前のバージョンの Xcode については この回答の以前のリビジョン .
関連
-
Python の sqlalchemy テーブル作成例 詳細
-
SQLite3 コマンドライン操作ガイド
-
SQLiteチュートリアル(II)。C/C++インターフェイスの紹介
-
[解決済み] SQLiteのINSERT/per-secondのパフォーマンスを向上させる
-
[解決済み] ATTACHで開いたSQLiteデータベースファイルのテーブルを一覧表示するにはどうすればよいですか?
-
[解決済み] SwiftからObjective-Cのコードを呼び出すにはどうしたらいいですか?
-
[解決済み] SQLiteでテーブルが存在するかどうかを確認するにはどうすればよいですか?
-
[解決済み] Swiftで#pragmaマーク?
-
[解決済み] Swift Betaのパフォーマンス:配列のソート
-
[解決済み] SQLiteデータベースで、一度に複数行を挿入することは可能ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
よく使われるsQliteステートメントとsQliteデベロッパーの使用・登録について
-
SQLite3における日付と時刻の関数のまとめ
-
SQLite3 用に ANSI から UTF8 への交換関数を提供する。
-
SQLiteデータベースの共通文とMACでのSQLite用可視化ツール「MeasSQLlite」の利用について
-
[解決済み] sqliteのテーブルに新しいカラムを挿入しますか?
-
[解決済み] SqLiteで上位5レコードを取得する方法は?
-
[解決済み】SQLiteの "Insert if not exists "ステートメントについて
-
[解決済み] SQLiteスクリプトの実行
-
[解決済み] SQLite - 値を特定の数だけ増加させる
-
[解決済み] 数百万レコードを扱うSQLiteの効率的なページング