質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
SQLite

SQLiteはリレーショナルデータベース管理システムの1つで、サーバーではなくライブラリとして使用されている。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

2回答

3689閲覧

【Swift】sqliteでSQLでUPDATEしても反映されない

freemann

総合スコア264

SQLite

SQLiteはリレーショナルデータベース管理システムの1つで、サーバーではなくライブラリとして使用されている。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2020/11/12 13:49

編集2020/11/14 08:20

Firefoxのブックマークのデータベース、places.sqliteの中のテーブル、moz_placesのurl列のデータを書き換えたいが、SQLを実行してエラーも出ないが反映もされない。

環境
Xcode 12.1
macOS Catalina 10.15.7

Swift

1let CONST_UPDATE = "UPDATE moz_places SET url = ? WHERE id = ?" 2 3 func updateData() -> Bool { 4 //SQL実行のエラー 5 var blError = false 6 //表示用のエラーコード 7 var errorCode = "" 8 let op = NSOpenPanel() 9 op.canChooseFiles = true 10 op.canChooseDirectories = false 11 op.allowsMultipleSelection = false 12 op.allowedFileTypes = ["sqlite"] 13 14 op.directoryURL = self.openURL 15 16 if op.runModal() == NSApplication.ModalResponse.OK { 17 //DBに接続 18 var db: OpaquePointer? = nil 19 var ret = sqlite3_open_v2(self.localBackupFile!.absoluteString, &db, SQLITE_OPEN_URI | SQLITE_OPEN_SHAREDCACHE | SQLITE_OPEN_NOMUTEX | SQLITE_OPEN_READWRITE, nil) 20 21 if ret == SQLITE_OK { 22 print("DB was opened.") 23 } else { 24 print("DB couldn't be opened.") 25 return false 26 } 27 28 print("(db.debugDescription)") 29 30 //ファイルの削除処理 31 for i in 0 ..< self.myList.count { 32 blError = false 33 if self.blReplaceURL == true { 34 //BEGIN TRANSACTION 35 var beginTransStatement: OpaquePointer? = nil 36 37 38 ret = sqlite3_prepare_v2(db, self.CONST_BEGIN_TRANSACTION, -1, &beginTransStatement, nil) 39 if ret == SQLITE_OK { 40 41 ret = sqlite3_step(beginTransStatement) 42 if ret == SQLITE_DONE { 43 print("BEGIN TRANSACTION for URL") 44 var updateStatement: OpaquePointer? = nil 45 46 ret = sqlite3_prepare_v2(db, self.CONST_UPDATE, -1, &updateStatement, nil) 47 if ret == SQLITE_OK { 48 //if sqlite3_bind_text(updateStatement, 1, (self.myList[i].Url as NSString).utf8String, -1, nil) != SQLITE_OK { 49 if sqlite3_bind_text(updateStatement, 1, self.myList[i].Url.cString(using: String.Encoding.utf8), -9, nil) != SQLITE_OK { 50 51 print("ERROR p1: %s", sqlite3_errmsg(db)) 52 } 53 if sqlite3_bind_int(updateStatement, 2, Int32(self.myList[i].id)) != SQLITE_OK { 54 print("ERROR p2: %s", sqlite3_errmsg(db)) 55 } 56 ret = sqlite3_step(updateStatement) 57 if ret == SQLITE_DONE { 58 print("DID UPDATE") 59 var endTransStatement: OpaquePointer? = nil 60 ret = sqlite3_prepare_v2(db, self.CONST_END_TRANSACTION, -1, &endTransStatement, nil) 61 if ret == SQLITE_OK { 62 ret = sqlite3_step(endTransStatement) 63 if ret == SQLITE_DONE { 64 print("END TRANSACTION") 65 } else { 66 print("RAISED ERROR") 67 blError = true 68 errorCode = "9-" + String(ret) 69 } 70 } else { 71 print("RAISED ERROR") 72 blError = true 73 errorCode = "8-" + String(ret) 74 } 75 sqlite3_finalize(endTransStatement) 76 } else { 77 print("RAISED ERROR") 78 blError = true 79 errorCode = "7-" + String(ret) 80 } 81 } else { 82 print("RAISED ERROR") 83 blError = true 84 errorCode = "6-" + String(ret) 85 } 86 sqlite3_finalize(updateStatement) 87 88 if blError == true { 89 var rollbackStatement: OpaquePointer? = nil 90 if sqlite3_prepare_v2(db, self.CONST_ROLLBACK, -1, &rollbackStatement, nil) == SQLITE_OK { 91 if sqlite3_step(rollbackStatement) == SQLITE_DONE { 92 print("DID ROLLBACK") 93 } else { 94 print("FAULT ROLLBACK") 95 } 96 } else { 97 print("FAULT ROLLBACK") 98 } 99 sqlite3_finalize(rollbackStatement) 100 } 101 } else { 102 errorCode = "2-" + String(ret) 103 } 104 } else { 105 errorCode = "1-" + String(ret) 106 } 107 sqlite3_finalize(beginTransStatement) 108 } 109 } 110 //sqlite3_finalize(queryStatement) 111 sqlite3_close(db) 112 print("Finished!") 113 114 //let panel = NSAlert() 115 116 let manager = FileManager.default 117 118 do { 119 try manager.removeItem(at: op.url!) 120 try manager.copyItem(at: self.localBackupFile!, to: op.url!) 121 } catch { 122 print("(error)") 123 return false 124 } 125 126 } 127 return blError 128 } 129

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

MasakiHori

2020/11/12 14:25

コンソールに何が表示されるか書いてください
freemann

2020/11/14 08:27

DB was opened. Optional(0x0000000101a162d0) BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION BEGIN TRANSACTION for URL DID UPDATE END TRANSACTION Finished!
freemann

2020/11/14 08:28

ログデータが長すぎて投稿出来ないようだったので、途中同じデータですので、削除して、短くして投稿しました。 よろしくお願いします。
MasakiHori

2020/11/14 15:32

ちょっと気になったんですけど、self.CONST_END_TRANSACTION これの中身どうなってます?
freemann

2020/11/15 05:27 編集

ありがとうございます。 let CONST_END_TRANSACTION = "END TRANSACTION" となっております。
guest

回答2

0

これは回答ではありません


すみません。何度かコードを読もうと思ったのですが、ごちゃごちゃし過ぎで僕には細かいところが分りませんでした。

大筋は読めたのですが、そこにsqlite3の使用法の誤りがありました。
回答とは直接関係ないのでそのまま放置しようかとも思ったのですが、気になって仕方がないのでその部分の説明だけさせていただきます。

質問者様のコードは大きくとらえると

swift

1for i in data { 2 beginTransactioin() 3 s = sqlite3_prepare_v2(...) 4 r = sqlite3_bind_XXX(...) 5 r = sqlite3_step(s) 6 r = sqlite3_finalize(s) 7 endTransaction() 8}

のようになっていますが、このやり方ではトランザクションの意味が全くなく、またsqlite3_bind_XXXを使う意味もほぼありません。
通常は

swift

1beginTransactioin() 2s = sqlite3_prepare_v2(...) 3for i in data { 4 r = sqlite3_bind_XXX(...) 5 r = sqlite3_step(s) 6 if r != SQLITE_DONE { 7 sqlite3_finalize(s) 8 rollbackTransaction() 9 return YYY // exit from function 10 } 11 r = sqlite3_reset(s) // パラメータをリセット 12} 13r = sqlite3_finalize(s) 14endTransaction()

のようにします。

SQLiteにはautotransaction機構があるので、トランザクションブロック内のSQLステートメントがただ1つの場合は明示的にトランザクションを使用する必要がありません。
トランザクションはそのブロック内で実行されたSQLステートメントをすべてデータベース(ファイル)に反映するかあるいはすべて破棄するかという時に使用します。
ですので通常はループの外側でその開始と終了を行います。
途中のSQLステートメントで問題が発生した場合は即座にロールバックして以降の処理を停止します。

続いてsqlite3_prepare_v2ですが、これは文字列のSQLステートメントをSQLite内部で使用するsqlite3_stmtにコンパイルを行っています。この処理は一般的に時間のかかる処理です。
ですのでsqlite3_bind_XXXでパラメータをバインドしながら次々にデータを処理する場合は、sqlite3_stmtを破棄せずに使いまわします。
つまりsqlite3_prepare_v2はループの開始前に実行し、ループの終了後にsqlite3_finalizeを行うようにします。

投稿2020/11/16 09:12

MasakiHori

総合スコア3384

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

freemann

2020/11/17 12:37

回答でなくてもありがとうございます。 ネットで検索しながら書いたコードなので、よくわかってないからですかね。 ちょっと見直してみます。
guest

0

自己解決

MasakiHori様のヒントを元に解決しました。

Swift

1 var updateStatement2: OpaquePointer? = nil 2 ret = sqlite3_prepare_v2(db, self.CONST_UPDATE, -1, &updateStatement2, nil) 3 4 //ファイルの削除処理 5 for i in 0 ..< self.myList.count { 6 blError = false 7 if self.blReplaceURL == true { 8 9 let URL = self.myList[i].Url.cString(using: String.Encoding.utf8) 10 if sqlite3_bind_text(updateStatement2, 1, URL, -1, nil) != SQLITE_OK { 11 print("ERROR p1: %s", sqlite3_errmsg(db)) 12 } 13 if sqlite3_bind_int(updateStatement2, 2, Int32(self.myList[i].id)) != SQLITE_OK { 14 print("ERROR p2: %s", sqlite3_errmsg(db)) 15 } 16 ret = sqlite3_step(updateStatement2) 17 let affectedRowsCount = sqlite3_changes(updateStatement2) 18 print("affected: (affectedRowsCount)") 19 if ret == SQLITE_DONE { 20 sqlite3_reset(updateStatement2) 21 print("DID UPDATE") 22 } else { 23 print("RAISED ERROR") 24 blError = true 25 errorCode = "7-" + String(ret) 26 } 27 } 28 29 } 30 sqlite3_finalize(updateStatement2) 31 sqlite3_close(db) 32

投稿2020/11/23 11:16

freemann

総合スコア264

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

MasakiHori

2020/11/24 10:49

おめでとうございます。 コードもかなりすっきりしてとてもいいです。 1点だけ。 sqlite3_reset()はsqlite3_step()が成功しても失敗しても行う必要があるのでif文の前か後に移動したほうがいいです。
freemann

2020/11/24 11:15

MasakiHori様、ありがとうございます。 再度の指摘助かります。 また質問した時はよろしくお願いします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問