首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server 圖片/二進位資料儲存與讀取完整實作(ASP.NET 範例)

     編輯:關於SqlServer

資料表設計

CREATE TABLE ImageStore (
    ID          INT IDENTITY(1,1) PRIMARY KEY,
    ImgTitle    NVARCHAR(50)   NOT NULL,  -- 使用者可讀標題
    ImgType     VARCHAR(50)    NOT NULL,  -- MIME 類型,如 image/jpeg
    ImgData     VARBINARY(MAX) NOT NULL   -- 實際二進位內容 (SQL 2005+ 建議用 VARBINARY(MAX))
);
SQL 2000 請用 `IMAGE` 類型;SQL 2005+ 強烈建議改用 `VARBINARY(MAX)`,支援所有字串函數且無 2GB 限制問題。

上傳與儲存(ASP.NET C# 後端)

protected void btnUpload_Click(object sender, EventArgs e)
{
    if (!FileUpload1.HasFile) return;

    // 1. 讀取檔案流
    Stream fs = FileUpload1.PostedFile.InputStream;
    int len = FileUpload1.PostedFile.ContentLength;
    string mime = FileUpload1.PostedFile.ContentType;
    string title = txtTitle.Text;

    byte[] buffer = new byte[len];
    fs.Read(buffer, 0, len);

    // 2. 參數化寫入 (防 SQL 注入、處理大物件)
    string connStr = ConfigurationManager.ConnectionStrings["MyDB"].ConnectionString;
    using (SqlConnection conn = new SqlConnection(connStr))
    using (SqlCommand cmd = new SqlCommand(
        "INSERT INTO ImageStore (ImgTitle, ImgType, ImgData) VALUES (@Title, @Type, @Data)", conn))
    {
        cmd.Parameters.Add("@Title", SqlDbType.NVarChar, 50).Value = title;
        cmd.Parameters.Add("@Type", SqlDbType.VarChar, 50).Value = mime;
        cmd.Parameters.Add("@Data", SqlDbType.VarBinary, -1).Value = buffer; // -1 = MAX

        conn.Open();
        cmd.ExecuteNonQuery();
    }
}

讀取並輸出至瀏覽器(通用處理器 .ashx 或頁面 Page_Load)

public void ProcessRequest(HttpContext context)
{
    string id = context.Request.QueryString["id"];
    if (string.IsNullOrEmpty(id)) return;

    string connStr = ConfigurationManager.ConnectionStrings["MyDB"].ConnectionString;
    using (SqlConnection conn = new SqlConnection(connStr))
    using (SqlCommand cmd = new SqlCommand(
        "SELECT ImgData, ImgType FROM ImageStore WHERE ID = @ID", conn))
    {
        cmd.Parameters.Add("@ID", SqlDbType.Int).Value = int.Parse(id);
        conn.Open();
        using (SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.SequentialAccess))
        {
            if (dr.Read())
            {
                context.Response.ContentType = dr.GetString(1); // ImgType
                // 使用 GetBytes 避免大物件一次載入記憶體
                long offset = 0;
                byte[] chunk = new byte[8192];
                long bytesRead;
                while ((bytesRead = dr.GetBytes(0, offset, chunk, 0, chunk.Length)) > 0)
                {
                    context.Response.OutputStream.Write(chunk, 0, (int)bytesRead);
                    offset += bytesRead;
                }
            }
        }
    }
}

前端呼叫

<img src="GetImage.ashx?id=123" alt="動態圖片" />

效能與架構建議

  • 檔案系統 vs 資料庫:小檔(<1MB)、需交易一致性、備份簡化 → 資料庫;大檔、高並發靜態存取 → 檔案系統 + 資料庫存路徑(FileTable/FILESTREAM 2008+ 兩全其美)。
  • 串流讀寫:大物件務必使用 `CommandBehavior.SequentialAccess` + `GetBytes`/`GetChars` 分塊處理,避免 LOH 壓力與 OOM。
  • 索引策略:二進位欄位不建索引;僅對 `ImgTitle`、`ImgType` 等查詢欄位建立索引。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved