質問編集履歴
3
コードの追記
test
CHANGED
File without changes
|
test
CHANGED
@@ -318,4 +318,28 @@
|
|
318
318
|
|
319
319
|
|
320
320
|
|
321
|
+
class Event {
|
322
|
+
|
323
|
+
|
324
|
+
|
325
|
+
var date:String = String()
|
326
|
+
|
327
|
+
var eventString:String = String()
|
328
|
+
|
329
|
+
|
330
|
+
|
331
|
+
init(date:String, eventString:String) {
|
332
|
+
|
333
|
+
self.date = date
|
334
|
+
|
335
|
+
self.eventString = eventString
|
336
|
+
|
337
|
+
}
|
338
|
+
|
339
|
+
|
340
|
+
|
341
|
+
}
|
342
|
+
|
343
|
+
|
344
|
+
|
321
345
|
```
|
2
コードと質問の内容修正
test
CHANGED
@@ -1 +1 @@
|
|
1
|
-
SQLiteに保存
|
1
|
+
SQLiteに複数のTEXTデータを正しく保存したい
|
test
CHANGED
@@ -4,21 +4,31 @@
|
|
4
4
|
|
5
5
|
下記サイトを参考にコードを記載してSQLiteへデータ保存をしたのですが、
|
6
6
|
|
7
|
-
|
7
|
+
現状のコードではTEXTが下記の様に違う値で保存されてしまいます。
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
|
12
|
-
|
9
|
+
|
10
|
+
|
13
|
-
|
11
|
+
・テキストフィールドに入力した文字→eventTextカラムに保存される文字列
|
12
|
+
|
14
|
-
|
13
|
+
「a」→「2」
|
14
|
+
|
15
|
+
「あ」→「202」
|
16
|
+
|
17
|
+
「あいう」→「20200101」
|
18
|
+
|
19
|
+
「あいうえお」→「20200101」
|
20
|
+
|
21
|
+
|
22
|
+
|
23
|
+
どうやらeventTextの後に処理を記載しているselectDayの文字列「20200101」が、
|
24
|
+
|
15
|
-
入力した
|
25
|
+
入力した文字数に対応する長さでeventTextカラムに保存されてしまっているようです。
|
16
|
-
|
17
|
-
|
18
|
-
|
26
|
+
|
19
|
-
|
27
|
+
(dateカラムにはselectDayが常に正しく保存されています)
|
20
|
-
|
28
|
+
|
29
|
+
|
30
|
+
|
21
|
-
どうすればTEXTを
|
31
|
+
どうすればそれぞれのTEXTを正しく保存出来るのか、
|
22
32
|
|
23
33
|
どなたかご教授いただけますと嬉しいです。
|
24
34
|
|
@@ -34,37 +44,79 @@
|
|
34
44
|
|
35
45
|
|
36
46
|
|
37
|
-
・失敗
|
47
|
+
・保存が失敗するコード
|
38
48
|
|
39
49
|
|
40
50
|
|
41
51
|
```Swift
|
42
52
|
|
53
|
+
import UIKit
|
54
|
+
|
43
55
|
import SQLite3
|
44
56
|
|
45
57
|
|
46
58
|
|
47
59
|
class ViewController: UIViewController {
|
48
60
|
|
49
|
-
|
61
|
+
|
50
62
|
|
51
63
|
var db: OpaquePointer?
|
52
64
|
|
53
|
-
///イベントリスト
|
54
|
-
|
55
65
|
var eventList = [Event]()
|
56
66
|
|
57
67
|
|
58
68
|
|
69
|
+
//ボタンを設定する
|
70
|
+
|
71
|
+
var button :UIButton = {
|
72
|
+
|
73
|
+
let btn = UIButton()
|
74
|
+
|
75
|
+
btn.setTitle("入力", for: .normal)
|
76
|
+
|
77
|
+
btn.backgroundColor = UIColor.gray
|
78
|
+
|
79
|
+
btn.tintColor = .white
|
80
|
+
|
81
|
+
btn.translatesAutoresizingMaskIntoConstraints = false
|
82
|
+
|
83
|
+
btn.addTarget(self, action: #selector(ViewController.tap(_:)), for: .touchUpInside)
|
84
|
+
|
85
|
+
return btn
|
86
|
+
|
87
|
+
}()
|
88
|
+
|
89
|
+
|
90
|
+
|
91
|
+
|
92
|
+
|
59
93
|
override func viewDidLoad() {
|
60
94
|
|
61
95
|
super.viewDidLoad()
|
62
96
|
|
97
|
+
//ボタンを表示する
|
98
|
+
|
99
|
+
view.addSubview(button)
|
100
|
+
|
101
|
+
//オートレイアウト
|
102
|
+
|
103
|
+
button.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
|
104
|
+
|
105
|
+
button.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
|
106
|
+
|
107
|
+
button.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.3).isActive = true
|
108
|
+
|
109
|
+
button.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.1).isActive = true
|
110
|
+
|
111
|
+
|
112
|
+
|
63
113
|
//データベースのパス
|
64
114
|
|
65
115
|
let fileURL = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
|
66
116
|
|
67
|
-
.appendingPathComponent("
|
117
|
+
.appendingPathComponent("TestDatabase.sqlite")
|
118
|
+
|
119
|
+
|
68
120
|
|
69
121
|
//データベースを開く
|
70
122
|
|
@@ -74,9 +126,11 @@
|
|
74
126
|
|
75
127
|
}
|
76
128
|
|
129
|
+
|
130
|
+
|
77
131
|
//テーブルの作成
|
78
132
|
|
79
|
-
if sqlite3_exec(db, "CREATE TABLE IF NOT EXISTS
|
133
|
+
if sqlite3_exec(db, "CREATE TABLE IF NOT EXISTS TestData (eventText TEXT, date TEXT)", nil, nil, nil) != SQLITE_OK {
|
80
134
|
|
81
135
|
let errmsg = String(cString: sqlite3_errmsg(db)!)
|
82
136
|
|
@@ -86,41 +140,45 @@
|
|
86
140
|
|
87
141
|
|
88
142
|
|
143
|
+
}
|
144
|
+
|
89
|
-
///
|
145
|
+
///ボタン押下時の挙動
|
90
|
-
|
146
|
+
|
91
|
-
func
|
147
|
+
@objc func tap(_ sender: UIButton) {
|
92
|
-
|
148
|
+
|
93
|
-
//
|
149
|
+
//アラートで入力画面を表示
|
94
150
|
|
95
151
|
let alertController = UIAlertController(title:nil, message:"入力して下さい", preferredStyle: UIAlertController.Style.alert)
|
96
152
|
|
97
153
|
alertController.addTextField()
|
98
154
|
|
99
|
-
|
155
|
+
|
100
156
|
|
101
157
|
let okButton = UIAlertAction(title: "OK", style: UIAlertAction.Style.default) { (ok) in
|
102
158
|
|
159
|
+
//テキストフィールドの文字をSQLに保存する
|
160
|
+
|
103
161
|
if let textField = alertController.textFields?.first {
|
104
162
|
|
105
|
-
|
106
|
-
|
107
|
-
|
163
|
+
///保存するテキストフィールドのテキスト
|
108
164
|
|
109
165
|
let eventText :String = textField.text ?? ""
|
110
166
|
|
111
|
-
|
167
|
+
///保存する日付
|
112
|
-
|
168
|
+
|
113
|
-
|
169
|
+
let selectDay :String = "20200101"
|
114
|
-
|
115
|
-
|
170
|
+
|
171
|
+
|
116
172
|
|
117
173
|
var stmt: OpaquePointer?
|
118
174
|
|
119
|
-
///保存用
|
175
|
+
///保存用SQL文の作成
|
120
|
-
|
176
|
+
|
121
|
-
let queryString = "INSERT INTO
|
177
|
+
let queryString = "INSERT INTO TestData (eventText, date) VALUES (?,?)"
|
122
|
-
|
178
|
+
|
179
|
+
|
180
|
+
|
123
|
-
//sqlを送信する
|
181
|
+
//ここでsqlを送信する
|
124
182
|
|
125
183
|
if sqlite3_prepare(self.db, queryString, -1, &stmt, nil) != SQLITE_OK{
|
126
184
|
|
@@ -132,7 +190,7 @@
|
|
132
190
|
|
133
191
|
}
|
134
192
|
|
135
|
-
//
|
193
|
+
//一つ目の?に値を設定する
|
136
194
|
|
137
195
|
if sqlite3_bind_text(stmt, 1, eventText, -1, nil) != SQLITE_OK{
|
138
196
|
|
@@ -144,7 +202,9 @@
|
|
144
202
|
|
145
203
|
}
|
146
204
|
|
205
|
+
|
206
|
+
|
147
|
-
//
|
207
|
+
//二つ目の?に値を設定する
|
148
208
|
|
149
209
|
if sqlite3_bind_text(stmt, 2, selectDay, -1, nil) != SQLITE_OK{
|
150
210
|
|
@@ -156,7 +216,9 @@
|
|
156
216
|
|
157
217
|
}
|
158
218
|
|
219
|
+
|
220
|
+
|
159
|
-
//エラー
|
221
|
+
//実行時エラーの処理
|
160
222
|
|
161
223
|
if sqlite3_step(stmt) != SQLITE_DONE {
|
162
224
|
|
@@ -168,11 +230,15 @@
|
|
168
230
|
|
169
231
|
}
|
170
232
|
|
171
|
-
|
233
|
+
|
172
234
|
|
173
235
|
self.readValues()
|
174
236
|
|
237
|
+
|
238
|
+
|
175
|
-
print("saved successfully")
|
239
|
+
print("Herro saved successfully")
|
240
|
+
|
241
|
+
|
176
242
|
|
177
243
|
}
|
178
244
|
|
@@ -180,8 +246,6 @@
|
|
180
246
|
|
181
247
|
alertController.addAction(okButton)
|
182
248
|
|
183
|
-
///キャンセルを押下した際の処理
|
184
|
-
|
185
249
|
let cancelButton = UIAlertAction(title: "cancel", style: UIAlertAction.Style.cancel, handler:nil)
|
186
250
|
|
187
251
|
alertController.addAction(cancelButton)
|
@@ -192,21 +256,19 @@
|
|
192
256
|
|
193
257
|
}
|
194
258
|
|
195
|
-
|
196
|
-
|
197
|
-
///
|
259
|
+
///SQLから値を取得する
|
198
260
|
|
199
261
|
func readValues(){
|
200
262
|
|
201
|
-
//配列を
|
263
|
+
//配列を空にする
|
202
264
|
|
203
265
|
eventList.removeAll()
|
204
266
|
|
205
|
-
///
|
267
|
+
///取得用SQLの作成
|
206
|
-
|
268
|
+
|
207
|
-
let queryString = "SELECT * FROM
|
269
|
+
let queryString = "SELECT * FROM TestData"
|
208
|
-
|
209
|
-
|
270
|
+
|
271
|
+
|
210
272
|
|
211
273
|
var stmt:OpaquePointer?
|
212
274
|
|
@@ -226,25 +288,19 @@
|
|
226
288
|
|
227
289
|
while(sqlite3_step(stmt) == SQLITE_ROW){
|
228
290
|
|
229
|
-
///予定(取得したstmtの0番目のカラムということ??)
|
230
|
-
|
231
291
|
let eventText = String(cString: sqlite3_column_text(stmt, 0))
|
232
292
|
|
233
|
-
///日付(取得したstmtの1番目のカラムということ??)
|
234
|
-
|
235
293
|
let date = String(cString: sqlite3_column_text(stmt, 1))
|
236
294
|
|
237
|
-
|
295
|
+
|
238
296
|
|
239
297
|
let event = Event(date: date,eventString: eventText)
|
240
298
|
|
241
|
-
//配列に追加
|
242
|
-
|
243
299
|
eventList.append(event)
|
244
300
|
|
245
301
|
}
|
246
302
|
|
247
|
-
//
|
303
|
+
//eventStringが正しく保存されていない
|
248
304
|
|
249
305
|
for event in eventList {
|
250
306
|
|
@@ -254,262 +310,12 @@
|
|
254
310
|
|
255
311
|
}
|
256
312
|
|
313
|
+
}
|
314
|
+
|
257
315
|
}
|
258
316
|
|
317
|
+
|
318
|
+
|
319
|
+
|
320
|
+
|
259
321
|
```
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
・保存が成功したコード
|
264
|
-
|
265
|
-
(上記と同様の記載で保存するカラムを両方「?」を使用するTEXTに変更すると、正しく保存されなくなってしまう)
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
```Swift
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
import UIKit
|
274
|
-
|
275
|
-
import SQLite3
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
class ViewController: UIViewController {
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
var db: OpaquePointer?
|
284
|
-
|
285
|
-
var eventList = [Event]()
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
//ボタンを設定する
|
290
|
-
|
291
|
-
var button :UIButton = {
|
292
|
-
|
293
|
-
let btn = UIButton()
|
294
|
-
|
295
|
-
btn.setTitle("入力", for: .normal)
|
296
|
-
|
297
|
-
btn.backgroundColor = UIColor.gray
|
298
|
-
|
299
|
-
btn.tintColor = .white
|
300
|
-
|
301
|
-
btn.translatesAutoresizingMaskIntoConstraints = false
|
302
|
-
|
303
|
-
btn.addTarget(self, action: #selector(ViewController.tap(_:)), for: .touchUpInside)
|
304
|
-
|
305
|
-
return btn
|
306
|
-
|
307
|
-
}()
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
override func viewDidLoad() {
|
314
|
-
|
315
|
-
super.viewDidLoad()
|
316
|
-
|
317
|
-
//ボタンを表示する
|
318
|
-
|
319
|
-
view.addSubview(button)
|
320
|
-
|
321
|
-
//オートレイアウト
|
322
|
-
|
323
|
-
button.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
|
324
|
-
|
325
|
-
button.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
|
326
|
-
|
327
|
-
button.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.3).isActive = true
|
328
|
-
|
329
|
-
button.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.1).isActive = true
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
//データベースのパス
|
334
|
-
|
335
|
-
let fileURL = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
|
336
|
-
|
337
|
-
.appendingPathComponent("EventsDatabase.sqlite")
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
//データベースを開く
|
342
|
-
|
343
|
-
if sqlite3_open(fileURL.path, &db) != SQLITE_OK {
|
344
|
-
|
345
|
-
print("error opening database")
|
346
|
-
|
347
|
-
}
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
//テーブルの作成
|
352
|
-
|
353
|
-
if sqlite3_exec(db, "CREATE TABLE IF NOT EXISTS Events (eventText TEXT, date TEXT DEFAULT current_timestamp)", nil, nil, nil) != SQLITE_OK {
|
354
|
-
|
355
|
-
let errmsg = String(cString: sqlite3_errmsg(db)!)
|
356
|
-
|
357
|
-
print("error creating table: (errmsg)")
|
358
|
-
|
359
|
-
}
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
}
|
364
|
-
|
365
|
-
///ボタン押下時の挙動
|
366
|
-
|
367
|
-
@objc func tap(_ sender: UIButton) {
|
368
|
-
|
369
|
-
//アラートで入力画面を表示
|
370
|
-
|
371
|
-
let alertController = UIAlertController(title:nil, message:"入力して下さい", preferredStyle: UIAlertController.Style.alert)
|
372
|
-
|
373
|
-
alertController.addTextField()
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
let okButton = UIAlertAction(title: "OK", style: UIAlertAction.Style.default) { (ok) in
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
if let textField = alertController.textFields?.first {
|
382
|
-
|
383
|
-
//テキストフィールドの文字をSQLに保存する
|
384
|
-
|
385
|
-
let eventText :String = textField.text ?? ""
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
var stmt: OpaquePointer?
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
let queryString = "INSERT INTO Events (eventText) VALUES (?)"
|
394
|
-
|
395
|
-
//ここでsqlを送信する
|
396
|
-
|
397
|
-
if sqlite3_prepare(self.db, queryString, -1, &stmt, nil) != SQLITE_OK{
|
398
|
-
|
399
|
-
let errmsg = String(cString: sqlite3_errmsg(self.db)!)
|
400
|
-
|
401
|
-
print("error preparing insert: (errmsg)")
|
402
|
-
|
403
|
-
return
|
404
|
-
|
405
|
-
}
|
406
|
-
|
407
|
-
//?に値を設定する
|
408
|
-
|
409
|
-
if sqlite3_bind_text(stmt, 1, eventText, -1, nil) != SQLITE_OK{
|
410
|
-
|
411
|
-
let errmsg = String(cString: sqlite3_errmsg(self.db)!)
|
412
|
-
|
413
|
-
print("failure binding name: (errmsg)")
|
414
|
-
|
415
|
-
return
|
416
|
-
|
417
|
-
}
|
418
|
-
|
419
|
-
//ここで実行してる
|
420
|
-
|
421
|
-
if sqlite3_step(stmt) != SQLITE_DONE {
|
422
|
-
|
423
|
-
let errmsg = String(cString: sqlite3_errmsg(self.db)!)
|
424
|
-
|
425
|
-
print("failure inserting hero: (errmsg)")
|
426
|
-
|
427
|
-
return
|
428
|
-
|
429
|
-
}
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
self.readValues()
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
print("Herro saved successfully")
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
}
|
442
|
-
|
443
|
-
}
|
444
|
-
|
445
|
-
alertController.addAction(okButton)
|
446
|
-
|
447
|
-
let cancelButton = UIAlertAction(title: "cancel", style: UIAlertAction.Style.cancel, handler:nil)
|
448
|
-
|
449
|
-
alertController.addAction(cancelButton)
|
450
|
-
|
451
|
-
//アラートを表示する
|
452
|
-
|
453
|
-
present(alertController, animated:true, completion: nil)
|
454
|
-
|
455
|
-
}
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
func readValues(){
|
460
|
-
|
461
|
-
eventList.removeAll()
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
let queryString = "SELECT * FROM Events"
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
var stmt:OpaquePointer?
|
470
|
-
|
471
|
-
//SQLを実行する
|
472
|
-
|
473
|
-
if sqlite3_prepare(db, queryString, -1, &stmt, nil) != SQLITE_OK{
|
474
|
-
|
475
|
-
let errmsg = String(cString: sqlite3_errmsg(db)!)
|
476
|
-
|
477
|
-
print("error preparing insert: (errmsg)")
|
478
|
-
|
479
|
-
return
|
480
|
-
|
481
|
-
}
|
482
|
-
|
483
|
-
//実行したSQLから値を取り出す
|
484
|
-
|
485
|
-
while(sqlite3_step(stmt) == SQLITE_ROW){
|
486
|
-
|
487
|
-
let eventText = String(cString: sqlite3_column_text(stmt, 0))
|
488
|
-
|
489
|
-
let date = String(cString: sqlite3_column_text(stmt, 1))
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
let event = Event(date: date,eventString: eventText)
|
494
|
-
|
495
|
-
eventList.append(event)
|
496
|
-
|
497
|
-
}
|
498
|
-
|
499
|
-
//どちらも文字化けせずに表示される
|
500
|
-
|
501
|
-
for event in eventList {
|
502
|
-
|
503
|
-
print(event.eventString)
|
504
|
-
|
505
|
-
print(event.date)
|
506
|
-
|
507
|
-
}
|
508
|
-
|
509
|
-
}
|
510
|
-
|
511
|
-
}
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
```
|
1
コードの抜粋漏れの修正
test
CHANGED
File without changes
|
test
CHANGED
@@ -108,6 +108,10 @@
|
|
108
108
|
|
109
109
|
let eventText :String = textField.text ?? ""
|
110
110
|
|
111
|
+
///入力する値の設定
|
112
|
+
|
113
|
+
let selectDay = "20200101"
|
114
|
+
|
111
115
|
///値を取得してくるコンテナ的なもの???
|
112
116
|
|
113
117
|
var stmt: OpaquePointer?
|