環境設定
| 項目 | 值 |
| 資料庫伺服器 | s_test |
| 登入帳號 | sa |
| 密碼 | 7890 |
| 資料庫名稱 | db_test |
建立測試資料表
CREATE TABLE tb_test (
id INT IDENTITY(1,1),
photo IMAGE,
CONSTRAINT pk_tb_test PRIMARY KEY(id)
)
使用 IMAGE 資料類型儲存二進位檔案 (最大 2GB)。
功能一:將本機檔案儲存至資料庫
Imports System.IO
Imports System.Data.SqlClient
Public Class ImageHandler
Shared Sub SaveImageToDatabase()
' 1. 讀取檔案為位元組陣列
Dim fs As New FileStream("c:\1.jpg", FileMode.Open, FileAccess.Read)
Dim imgData(fs.Length - 1) As Byte
fs.Read(imgData, 0, fs.Length)
fs.Close()
' 2. 建立資料庫連線與 DataAdapter
Dim tempConnection As New SqlConnection
Dim tempAdapter As SqlDataAdapter
Dim tempDataSet As New DataSet
tempConnection.ConnectionString = "server=s_test;uid=sa;pwd=7890;database=db_test"
tempConnection.Open()
' 使用 WHERE 1=0 只取結構不取資料
tempAdapter = New SqlDataAdapter("SELECT * FROM tb_test WHERE 1=0", tempConnection)
Dim cb As New SqlCommandBuilder(tempAdapter) ' 自動產生 INSERT/UPDATE/DELETE 命令
tempAdapter.Fill(tempDataSet)
' 3. 新增資料列並更新
Dim tempDataRow As DataRow = tempDataSet.Tables(0).NewRow()
tempDataRow("photo") = imgData
tempDataSet.Tables(0).Rows.Add(tempDataRow)
tempAdapter.Update(tempDataSet) ' 觸發 INSERT 命令
tempConnection.Close()
End Sub
End Class
功能二:從資料庫讀取檔案存至本機
Shared Sub LoadImageFromDatabase()
Dim tempConnection As New SqlConnection
Dim tempAdapter As SqlDataAdapter
Dim tempDataSet As New DataSet
tempConnection.ConnectionString = "server=s_test;uid=sa;pwd=7890;database=db_test"
tempConnection.Open()
tempAdapter = New SqlDataAdapter("SELECT * FROM tb_test", tempConnection)
tempAdapter.Fill(tempDataSet)
' 讀取第一筆資料的 photo 欄位
If tempDataSet.Tables(0).Rows.Count > 0 Then
Dim imgData As Byte() = CType(tempDataSet.Tables(0).Rows(0)("photo"), Byte())
' 寫入檔案
Dim fs As New FileStream("c:\2.jpg", FileMode.Create, FileAccess.Write)
fs.Write(imgData, 0, imgData.Length)
fs.Close()
End If
tempConnection.Close()
End Sub
核心架構解析
| 元件 | 角色 |
| SqlConnection | 管理資料庫連線 |
| SqlDataAdapter | 橋接 DataSet 與資料庫,負責 Fill/Update |
| SqlCommandBuilder | 根據 SelectCommand 自動產生 Insert/Update/DeleteCommand |
| DataSet | 離線資料容器,記憶體中資料表集合 |
| DataRow | 代表單一資料列,索引器存取欄位值 |
關鍵技術要點
- 離線架構優勢:DataSet 在記憶體操作,更新時才連線,減少連線佔用
- SqlCommandBuilder 自動命令產生:需 SelectCommand 為單一資料表且有主鍵,否則需手寫命令
- IMAGE/VARBINARY(MAX) 欄位對應:.NET 對應
Byte() 陣列
- 大檔案考量:超大檔案建議使用
SqlCommand.ExecuteNonQuery 搭配參數化查詢分塊寫入,避免記憶體壓力
- 資料流處理:
FileStream.Read/Write 需正確處理位元組長度與位移
常見問題與解決