SQL Server BLOB データの扱い (.NET)

#概要

SQL Server での BLOB データの使い方ですが、画像ファイルを BLOB フィールドに格納する方法と読みだす方法を示します。

まず、データの格納ですが、画像ファイルを読み込んで Image 型データに格納し、それを BLOB フィールドに挿入することにより行います。

BLOB データの読み出しですが、SELECT 文を実行して SQLDataReader オブジェクトを取得します。そして、その Read() メソッドを実行して、バイト型配列に格納します。さらにバイト型配列をベースにしたストリーム (MemoryStream) から Image オブジェクトを作成します。


#BLOB データの格納サンプル

次のメソッドは、他のフィールドとともに Image 型の画像データをテーブルに格納します。

```VisualBasic
''' <summary>
''' データを挿入する。
''' </summary>
''' <param name="title">タイトル</param>
''' <param name="creator">作者</param>
''' <param name="fileOrig">オリジナルのファイルパス</param>
''' <param name="img">画像データ</param>
''' <param name="mark">マーク</param>
''' <param name="info">情報</param>
''' <returns></returns>
Public Function Insert(ByVal title As String, ByVal creator As String, ByVal fileOrig As String, ByVal img As Image, ByVal mark As String, ByVal info As String) As Integer
    Dim command As New SqlCommand()
    command.Connection = Me.Connection
    command.CommandText = "INSERT INTO [PICTURES] ([Title], [Creator], [Original], [ImageData], [Mark], [Info]) " &
        "VALUES(@Title, @Creator, @Original, @ImageData, @Mark, @Info)"
    ' Parameter を準備
    Dim pTitle As New SqlParameter("@Title", SqlDbType.NVarChar, 100)
    pTitle.Value = title
    Dim pCreator As New SqlParameter("@Creator", SqlDbType.NVarChar, 50)
    pCreator.Value = creator
    Dim pOriginal As New SqlParameter("@Original", SqlDbType.NVarChar, 300)
    pOriginal.Value = fileOrig
    Dim pImageData As New SqlParameter("@ImageData", SqlDbType.Image)
    pImageData.Value = ConvertBytes(img)
    Dim pMark As New SqlParameter("@Mark", SqlDbType.Char, 10)
    pMark.Value = mark
    Dim pInfo As New SqlParameter("@Info", SqlDbType.NVarChar, 100)
    pInfo.Value = info
    ' SqlCommand に Parameter を割り当てる。
    command.Parameters.Add(pTitle)
    command.Parameters.Add(pCreator)
    command.Parameters.Add(pOriginal)
    command.Parameters.Add(pImageData)
    command.Parameters.Add(pMark)
    command.Parameters.Add(pInfo)

    ' SqlCommand を実行する。
    Me.Sql = command.CommandText.Replace("'", "''")
    Return command.ExecuteNonQuery()
End Function
```

#BLOB データの読み出しサンプル

次のメソッドは、主キーで指定した画像データを SELECT 文で取り出し、バイト列に格納します。

```VisualBasic
''' <summary>
''' Id で指定した画像データを得る。
''' </summary>
''' <param name="id"></param>
''' <returns></returns>
Public Function GetData(ByVal id As Integer) As Byte()
    Dim command As New SqlCommand()
    command.Connection = Me.Connection
    command.CommandText = $"SELECT [ImageData] FROM dbo.PICTURES WHERE Id = {id}"
    Dim buffer(MAXLENGTH) As Byte
    Dim reader = command.ExecuteReader()
    Try
        reader.Read()
        If reader.HasRows Then
            reader.GetBytes(0, 0, buffer, 0, MAXLENGTH)
        End If
    Finally
        reader.Close()
    End Try
    Return buffer
End Function
```

次のメソッドは、前のソースで示されるメソッド GetData を呼び出して、画像のバイト列を取得し、それを元に Image オブジェクトに変換してピクチャボックスに表示します。

```VisualBasic
'''<summary>
''' PICTURES テーブルの指定された Id の画像データをピクチャボックスに表示する。
''' </summary>
''' <param name="id"></param>
Private Sub ShowImageData(ByVal id As Integer)
    Dim data As Byte() = pics.GetData(id)
    Dim ms As New IO.MemoryStream(data)
    PictureBox1.Image = Image.FromStream(ms)
End Sub
```

-