teratail header banner
teratail header banner
質問するログイン新規登録

質問編集履歴

2

解決したので、解決方法を追記した。

2020/01/06 05:49

投稿

TAKASE_Hiroyuki
TAKASE_Hiroyuki

スコア21

title CHANGED
File without changes
body CHANGED
@@ -167,4 +167,98 @@
167
167
  #お願い
168
168
  画像データを、データベースに正しく格納するためには、どのような命令を書けばよいのでしょうか。また、格納されたデータを、プログラムで読むためには、どのような命令を書けばよいのか、についても、合わせて教えていただければ幸いです。
169
169
 
170
- どうか、よろしくお願いいたします。
170
+ どうか、よろしくお願いいたします。
171
+
172
+ #追記(解決方法)
173
+ 以下のような方法で本件は解決しましたので、本文にも追記しておきます。
174
+
175
+ まず、本文で「ここがわからない」と書いた部分については、次のようにすると画像データを保存できることが確認できました。
176
+
177
+ ```C#
178
+ // こうすればできます
179
+ comm.CommandText = "insert into mydata(name,face) values ('visual studio3',@face);";
180
+ ImageConverter converter = new ImageConverter();
181
+ byte[] fdata = (byte[])converter.ConvertTo(im2, typeof(byte[]));
182
+ var param = new SQLiteParameter("@face", System.Data.DbType.Binary);
183
+ param.Value = fdata;
184
+ comm.Parameters.Add(param);
185
+ comm.ExecuteNonQuery();
186
+ ```
187
+
188
+ つぎに、実際のプログラムでは、このような保存作業を、一度に 10000回程度実施する予定ですので、for 文を用いて、10000 回実施してみました。
189
+
190
+ ```C#
191
+ using (var conn = new SQLiteConnection("DataSource=data.db"))
192
+ {
193
+ conn.Open();
194
+ SQLiteCommand cmd = conn.CreateCommand();
195
+ ImageConverter converter = new ImageConverter();
196
+ byte[] fdata;
197
+ SQLiteParameter param;
198
+
199
+ for (int i=0; i < 10000; i++)
200
+ {
201
+ /*
202
+ cmd.CommandText = "insert into mydata(name) values (@ID)";
203
+ cmd.Parameters.Add(new SQLiteParameter("@ID", "visual studio4"));
204
+ cmd.ExecuteNonQuery();
205
+ */
206
+
207
+ cmd.CommandText = "insert into mydata(name,face) values ('visual studio5',@face);";
208
+ fdata = (byte[])converter.ConvertTo(im2, typeof(byte[]));
209
+ param = new SQLiteParameter("@face", System.Data.DbType.Binary);
210
+ param.Value = fdata;
211
+ cmd.Parameters.Add(param);
212
+ cmd.ExecuteNonQuery();
213
+
214
+ }
215
+
216
+ conn.Close();
217
+ }
218
+ ```
219
+
220
+ ところが、100000回、作業を行うのに5分から7分程度必要で、とても実用に堪えないことがわかりました。このことについては、あちこちのページで「トランザクション処理が原因で、非常に速度が遅くなる」と書いてありましたので、実際に作業の前後にトランザクションに関する命令を追加しました。
221
+
222
+ ```C#
223
+ var ts = conn.BeginTransaction();
224
+ <途中の処理>
225
+ ts.Commit();
226
+ ```
227
+
228
+ この2行を追加したプログラムは、次のとおりです。
229
+
230
+ ```C#
231
+ using (var conn = new SQLiteConnection("DataSource=data.db"))
232
+ {
233
+ conn.Open();
234
+ var ts = conn.BeginTransaction();
235
+
236
+ SQLiteCommand cmd = conn.CreateCommand();
237
+ ImageConverter converter = new ImageConverter();
238
+ byte[] fdata;
239
+ SQLiteParameter param;
240
+
241
+ for (int i=0; i < 10000; i++)
242
+ {
243
+ /*
244
+ cmd.CommandText = "insert into mydata(name) values (@ID)";
245
+ cmd.Parameters.Add(new SQLiteParameter("@ID", "visual studio4"));
246
+ cmd.ExecuteNonQuery();
247
+ */
248
+
249
+ cmd.CommandText = "insert into mydata(name,face) values ('visual studio5',@face);";
250
+ fdata = (byte[])converter.ConvertTo(im2, typeof(byte[]));
251
+ param = new SQLiteParameter("@face", System.Data.DbType.Binary);
252
+ param.Value = fdata;
253
+ cmd.Parameters.Add(param);
254
+ cmd.ExecuteNonQuery();
255
+
256
+ }
257
+
258
+ ts.Commit();
259
+ conn.Close();
260
+ }
261
+ ```
262
+
263
+ 今度は、作業は数秒で終了してしまいました。
264
+ 以上、報告です。

1

「ありまえす」⇒「ありえます」

2020/01/06 05:49

投稿

TAKASE_Hiroyuki
TAKASE_Hiroyuki

スコア21

title CHANGED
File without changes
body CHANGED
@@ -120,7 +120,7 @@
120
120
 
121
121
  概略を説明すると、まず、データベースに接続します(ファイルが無ければ、新しく作ります)。次に、data.png を読み込み、pic.Image に格納し、画面にも表示させます。また、pic.Image の一部を切り取り、im1 と im2 に保存し、それぞれ画面に表示させます。
122
122
 
123
- 次にデータベースにレコードを登録します。mydata テーブルのうち、name については、 TEXT NOT NULL ですので、必ず登録しなければなりませんが、face BLOB については、登録しない場合もありえす。
123
+ 次にデータベースにレコードを登録します。mydata テーブルのうち、name については、 TEXT NOT NULL ですので、必ず登録しなければなりませんが、face BLOB については、登録しない場合もありえす。
124
124
 
125
125
  レコードとして、「visual studio1」という name をもつデータと、「visual studio2」という name をもつデータの合計2つのデータが登録できたことは、[DB Browser for SQLite](https://sqlitebrowser.org/) を用いて、確認できました。
126
126