Excelシートに入力されたテキストと画像をSQLiteデータベースに登録する(3)
INSERT文でBLOBデータを登録する
SQLiteで BLOBをINSERT文で扱う方法を調べてみると、16進数文字列をx''で囲って記述するとよいことがわかりました。
以下のような感じ。
sqlite> CREATE TABLE table2 (id INTEGER, dat BLOB); sqlite> sqlite> INSERT INTO table2 (id, dat) VALUES (1, x'0003070b0f'); sqlite> sqlite> SELECT id, hex(dat) FROM table2; 1|0003070B0F sqlite>
なんや、こんな簡単に出来るんか。。。
ちょっと拍子抜け。
難しく考えすぎでした。
Byte() を16進文字列に変換する
VBScriptでは Byte() に対する操作はほとんど何も出来ません。
ネット上を少し検索すると、16進文字列をByte()に変換する方法が、以下のページにありました。
http://winscript.s41.xrea.com/wiki/index.php?%5B%5B%A5%C6%A5%AF%A5%CB%A5%C3%A5%AF%5D%5D
なにやら Microsoft.XMLDOM を使うと 16進文字列→Byte() に変換できる様子。なるほど。これを応用して逆の入出力をすれば、Byte()→16進文字列 の変換ができるのでは?
ということで作ったのがこの関数。
'------------------------------------------------------------------------------- 'バイト配列を16進文字列に変換する '------------------------------------------------------------------------------- Function ByteArray2HexText(byteArray) With CreateObject("Microsoft.XMLDOM").createElement("tmp") .DataType = "bin.hex" .NodeTypedValue = byteArray ByteArray2HexText = .Text End With End Function
これであっさりうまく行きました。引数に Byte() を渡すと16進文字列が返ってきます。
INSERT文を作ってSQLiteに流しこむ
あとは SQLite をShellExecで起動し標準入力に SQL を流しこんでやれば実行できそうです。
こんな感じです。
Option Explicit Dim objFSO :Set objFSO = WScript.CreateObject("Scripting.FileSystemObject") Dim objWshShell : Set objWshShell = WScript.CreateObject("WScript.Shell") 'データファイルのパス Dim tempFilePath : tempFilePath = objFSO.BuildPath(objFSO.GetParentFolderName(WScript.ScriptFullName), "temp.jpg") 'データファイルをバイナリ読みこみ Dim objStream : Set objStream = WScript.CreateObject("ADODB.Stream") objStream.Open : objStream.Type = 1 objStream.LoadFromFile tempFilePath objStream.position = 0 Dim objBin : objBin = objStream.Read objStream.Close 'sqlite3.exe を起動 Dim objWshExec : Set objWshExec = objWshShell.Exec("sqlite3.exe test.db") '標準入力を取得 Dim sqlStream : Set sqlStream = objWshExec.StdIn 'SQLを書き込む sqlStream.WriteLine "INSERT INTO table2 (id, dat) VALUES (2, x'" & ByteArray2HexText(objBin) & "');" 'テキストも書いてみる sqlStream.WriteLine "INSERT INTO table2 (id, dat) VALUES (3, 'てすと');" 'SELECTしてみる sqlStream.WriteLine "SELECT * FROM table2;" sqlStream.Close 'SELECT結果を表示 MsgBox objWshExec.StdOut.ReadAll '------------------------------------------------------------------------------- 'バイト配列を16進文字列に変換する '------------------------------------------------------------------------------- Function ByteArray2HexText(byteArray) With CreateObject("Microsoft.XMLDOM").createElement("tmp") .DataType = "bin.hex" .NodeTypedValue = byteArray ByteArray2HexText = .Text End With End Function
実際これでうまく行きました。
ただし、Linuxで見ると日本語が化けます。SJISで入ってしまっているようです。
ガーン。
Windowsだけで使うのなら問題ないですが、このDBはAndroidで使うDBなので、これではまずいです。UTF-8に変換する必要があります。
次はUTF-8に変換する方法を考えます。