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

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

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

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

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

Q&A

解決済

2回答

1279閲覧

SQLiteに複数のTEXTデータを正しく保存したい

Ka_ya_

総合スコア31

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

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

0グッド

1クリップ

投稿2020/06/09 04:45

編集2020/06/09 07:41

質問失礼します。

下記サイトを参考にコードを記載してSQLiteへデータ保存をしたのですが、
現状のコードではTEXTが下記の様に違う値で保存されてしまいます。

・テキストフィールドに入力した文字→eventTextカラムに保存される文字列
「a」→「2」
「あ」→「202」
「あいう」→「20200101」
「あいうえお」→「20200101」

どうやらeventTextの後に処理を記載しているselectDayの文字列「20200101」が、
入力した文字数に対応する長さでeventTextカラムに保存されてしまっているようです。
(dateカラムにはselectDayが常に正しく保存されています)

どうすればそれぞれのTEXTを正しく保存出来るのか、
どなたかご教授いただけますと嬉しいです。

よろしくお願いいたします。

・参考サイト
https://www.simplifiedios.net/swift-sqlite-tutorial/

・保存が失敗するコード

Swift

1import UIKit 2import SQLite3 3 4class ViewController: UIViewController { 5 6 var db: OpaquePointer? 7 var eventList = [Event]() 8 9 //ボタンを設定する 10 var button :UIButton = { 11 let btn = UIButton() 12 btn.setTitle("入力", for: .normal) 13 btn.backgroundColor = UIColor.gray 14 btn.tintColor = .white 15 btn.translatesAutoresizingMaskIntoConstraints = false 16 btn.addTarget(self, action: #selector(ViewController.tap(_:)), for: .touchUpInside) 17 return btn 18 }() 19 20 21 override func viewDidLoad() { 22 super.viewDidLoad() 23 //ボタンを表示する 24 view.addSubview(button) 25 //オートレイアウト 26 button.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true 27 button.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true 28 button.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.3).isActive = true 29 button.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.1).isActive = true 30 31 //データベースのパス 32 let fileURL = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false) 33 .appendingPathComponent("TestDatabase.sqlite") 34 35 //データベースを開く 36 if sqlite3_open(fileURL.path, &db) != SQLITE_OK { 37 print("error opening database") 38 } 39 40 //テーブルの作成 41 if sqlite3_exec(db, "CREATE TABLE IF NOT EXISTS TestData (eventText TEXT, date TEXT)", nil, nil, nil) != SQLITE_OK { 42 let errmsg = String(cString: sqlite3_errmsg(db)!) 43 print("error creating table: (errmsg)") 44 } 45 46 } 47 ///ボタン押下時の挙動 48 @objc func tap(_ sender: UIButton) { 49 //アラートで入力画面を表示 50 let alertController = UIAlertController(title:nil, message:"入力して下さい", preferredStyle: UIAlertController.Style.alert) 51 alertController.addTextField() 52 53 let okButton = UIAlertAction(title: "OK", style: UIAlertAction.Style.default) { (ok) in 54 //テキストフィールドの文字をSQLに保存する 55 if let textField = alertController.textFields?.first { 56 ///保存するテキストフィールドのテキスト 57 let eventText :String = textField.text ?? "" 58 ///保存する日付 59 let selectDay :String = "20200101" 60 61 var stmt: OpaquePointer? 62 ///保存用SQL文の作成 63 let queryString = "INSERT INTO TestData (eventText, date) VALUES (?,?)" 64 65 //ここでsqlを送信する 66 if sqlite3_prepare(self.db, queryString, -1, &stmt, nil) != SQLITE_OK{ 67 let errmsg = String(cString: sqlite3_errmsg(self.db)!) 68 print("error preparing insert: (errmsg)") 69 return 70 } 71 //一つ目の?に値を設定する 72 if sqlite3_bind_text(stmt, 1, eventText, -1, nil) != SQLITE_OK{ 73 let errmsg = String(cString: sqlite3_errmsg(self.db)!) 74 print("failure binding name: (errmsg)") 75 return 76 } 77 78 //二つ目の?に値を設定する 79 if sqlite3_bind_text(stmt, 2, selectDay, -1, nil) != SQLITE_OK{ 80 let errmsg = String(cString: sqlite3_errmsg(self.db)!) 81 print("failure binding name: (errmsg)") 82 return 83 } 84 85 //実行時エラーの処理 86 if sqlite3_step(stmt) != SQLITE_DONE { 87 let errmsg = String(cString: sqlite3_errmsg(self.db)!) 88 print("failure inserting hero: (errmsg)") 89 return 90 } 91 92 self.readValues() 93 94 print("Herro saved successfully") 95 96 } 97 } 98 alertController.addAction(okButton) 99 let cancelButton = UIAlertAction(title: "cancel", style: UIAlertAction.Style.cancel, handler:nil) 100 alertController.addAction(cancelButton) 101 //アラートを表示する 102 present(alertController, animated:true, completion: nil) 103 } 104 ///SQLから値を取得する 105 func readValues(){ 106 //配列を空にする 107 eventList.removeAll() 108 ///取得用SQLの作成 109 let queryString = "SELECT * FROM TestData" 110 111 var stmt:OpaquePointer? 112 //SQLを実行する 113 if sqlite3_prepare(db, queryString, -1, &stmt, nil) != SQLITE_OK{ 114 let errmsg = String(cString: sqlite3_errmsg(db)!) 115 print("error preparing insert: (errmsg)") 116 return 117 } 118 //実行したSQLから値を取り出す 119 while(sqlite3_step(stmt) == SQLITE_ROW){ 120 let eventText = String(cString: sqlite3_column_text(stmt, 0)) 121 let date = String(cString: sqlite3_column_text(stmt, 1)) 122 123 let event = Event(date: date,eventString: eventText) 124 eventList.append(event) 125 } 126//eventStringが正しく保存されていない 127 for event in eventList { 128 print(event.eventString) 129 print(event.date) 130 } 131 } 132} 133 134 135class Event { 136 137 var date:String = String() 138 var eventString:String = String() 139 140 init(date:String, eventString:String) { 141 self.date = date 142 self.eventString = eventString 143 } 144 145} 146

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

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

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

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

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

YT0014

2020/06/09 05:17

dateに保存しようとしているselectDayですが、宣言も代入もされていませんので、元のソースからの転記漏れかどうか、ご確認ください。
Ka_ya_

2020/06/09 05:24

質問をご確認いただき、ありがとうございます。 すみません、selectDayに関してはコードの抜粋漏れだった為、 修正いたしました。 selectDayの数列TEXTは正しく保存出来ているのですが、 eventTextでテキストフィールドから取得するTEXTだけが文字化けしてしまう状態です。 お手数ですが、ご確認よろしくお願いいたします。
YT0014

2020/06/09 06:41

修正、確認いたしました。 状況確認のため、文字化け時の入出力データをお願いします。 また、同名テーブルを使っているようですが、別データベースに格納されているのでしょうか?同一データベースだと、下のコードでのcreate table の DEFAULT current_timestamp が影響している可能性があります。 テーブル名を、一時的に変更して、結果をご確認ください。
Ka_ya_

2020/06/09 07:35

たびたび申し訳ありません。 ご確認いただき、ありがとうございます。 データベースとテーブルに関して、修正いたしました。 現状の挙動に関しても質問内容に反映させていただき、 再現可能な状態のコードに記載し直しました。 データ保存時の記載方法が間違っているのかとは思うのですが、 TEXTカラムが複数ある参考サイトなどを見つける事が出来ず、 解決方法を見つけられずにいます。 お手数をお掛けして申し訳ありませんが、 ご確認よろしくお願いいたします。
YT0014

2020/06/09 08:29

原因の切り分けの為、insert時の eventText に値を設定した直後と、select時の、eventText と date の(Eventに設定する前の)値を確認してください。 print()でも、デバッガでも、良いので。 また、可能であれば、sqliteのテーブルデータを編集ツールなので確認してみてください。
Ka_ya_

2020/06/09 09:54

ご確認いただきありがとうございます。 printで確認した結果、 insert時のeventText→「あ」 select時(Eventに設定する前の)eventText→「202」 date→「20200101」 となっていました。 sqliteのテーブルデータに関しては調べ方が分からなかった為、 編集ツールに関して調べてみようと思います。 たびたび申し訳ありません。 ご確認よろしくお願いします。
guest

回答2

0

自己解決

sqlite3_bind_textの引数記載を間違えていたようで、
修正したところ無事に保存出来るようになりました。

投稿2020/06/10 02:35

Ka_ya_

総合スコア31

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

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

0

swift

1 let eventText = String(cString: sqlite3_column_text(stmt, 0)) 2 let date = String(cString: sqlite3_column_text(stmt, 1))

この部分ですが、最後のパラメータは合っていますか?
0はidで、1、2とinsertと対になるようにすべきでは?

投稿2020/06/09 06:28

t_obara

総合スコア5488

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

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

Ka_ya_

2020/06/09 07:39

ご回答ありがとうございます。 最後のパラメーターに関して、 1.2にすると2でnilエラーが発生してしまい、 ?に値を設定する際の数値を0.1にするとrangeのエラーになってしまう為、 どちらかに揃える事が出来ませんでした。 調べても引数に関して良く分からずに手探りで試している為、 正しい記載方法が分からずにいます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問