簡體   English   中英

將圖像存儲在數據庫中並檢索

[英]Store image in database and retrieve it

我在數據庫中插入圖像的代碼如下:

MemoryStream ms =new MemoryStream();
byte[] PhotoByte=null;
PhotoByte=ms.ToArray();
pictureBox1.Image.Save(ms, ImageFormat.Jpeg);
PhotoByte =ms.ToArray();
Str = "insert into Experimmm Values('" + PhotoByte + "','" + textBox1.Text + "')";
Conn.Open();
cmd.Connection = Conn;
cmd.CommandText = Str;
cmd.ExecuteNonQuery();
Conn.Close();

一切順利。 我可以在ma數據庫表中看到二進制數據,例如<Binary Data> 。檢索數據的代碼是:

Str ="select * from Experimmm where id = '" +textBox2.Text + "'";
Conn.Open();
cmd.Connection = Conn;
cmd.CommandText = Str;
dr = cmd.ExecuteReader();
if (dr.Read())
{ label1.Text = dr.GetValue(1).ToString();
byte[] PhotoByte = (byte[])dr.GetValue(0);
MemoryStream mem = new MemoryStream(PhotoByte, 0, PhotoByte.Length);
//but an error takes place on next line "Parameter is not valid."             
pictureBox2.Image = Image.FromStream(mem);
} Conn.Close();

我正在使用Visual Studio 10,C#,SQL Server 2005

您的代碼有幾個問題。 我將逐行處理:

MemoryStream ms =new MemoryStream();
byte[] PhotoByte=null;
PhotoByte=ms.ToArray();
pictureBox1.Image.Save(ms, ImageFormat.Jpeg);
PhotoByte =ms.ToArray();

雖然這不是問題,但您在這里不需要進行任何分配。 上面的代碼可以這樣更清晰地編寫:

MemoryStream ms =new MemoryStream();
pictureBox1.Image.Save(ms, ImageFormat.Jpeg);
byte[] PhotoByte =ms.ToArray();

接下來,以下代碼不使用參數。 總是,總是,總是參數化您的SQL查詢,而不是動態地構建SQL。 不,認真,總是。 是的,即使那樣。 (另外, Str變量是什么?某種重用的實例變量?不要這樣做。)

Str = "insert into Experimmm Values('" + PhotoByte + "','" + textBox1.Text + "')";
Conn.Open();
cmd.Connection = Conn;
cmd.CommandText = Str;
cmd.ExecuteNonQuery();
Conn.Close();

相反,應該是這樣的:

Conn.Open();
using(SqlCommand cmd = connection.CreateCommand())
{
    cmd.CommandText = "insert into Experimmm (column list) values(@data, @name)";

    cmd.Parameters.Add("@data", SqlDbType.VarBinary).Value = PhotoByte;
    cmd.Parameters.Add("@name", SqlDbType.VarChar, yourlength).Value = textBox1.Text;

    cmd.ExecuteNonQuery();
}
Conn.Close();

接下來,我們將繼續您的檢索。 再次使用Str變量,不要執行此類操作。 另外,您還需要參數化此查詢。

byte[] data;
string name;

Conn.Open();
using(SqlCommand cmd = Conn.CreateCommand())
{    
    cmd.CommandText = "select column_list from Experimmm where id = @id";

    cmd.Parameters.Add("@id", SqlDbType.VarChar, field_length).Value = textBox2.Text;

    using(SqlDataReader dr = cmd.ExecuteReader())
    {
        if (dr.Read())
        {
            data = (byte[])dr.GetValue(0); 
            name = (string)dr.GetValue(1);
        }
    }
}
Conn.Close();

label1.Text = name;
pictureBox2.Image = Image.FromStream(new MemoryStream(data));

當然可以將圖像存儲在db中。 但是,不建議這樣做。 最好將它們存儲在文件系統中。

您的代碼有點混亂。 以下是一個更好的示例。

MemoryStream ms =new MemoryStream(); 
byte[] PhotoByte=null; 
pictureBox1.Image.Save(ms, ImageFormat.Jpeg); 
PhotoByte =ms.ToArray(); 
// I'm not sure whether you are able to create an sql by simply concating the string
Str = "insert into Experimmm Values('@PhotoBytes','@MyTextValue')"; 
// You have to parametrize your query
cmd.Parameters.AddWithValue("PhotoBytes", PhotoByte);
// This also helps you to avoid syntactical corruption in case of ' and sql injection
cmd.Parameters.AddWithValue("MyTextValue", textBox1.Text );
Conn.Open(); 
cmd.Connection = Conn; 
cmd.CommandText = Str; 
cmd.ExecuteNonQuery(); 
Conn.Close(); 

檢索時,可以在某些處理程序中使用二進制編寫器

namespace TestNS
{
   public class MyHttpHandler : IHttpHandler
   {
      // Override the ProcessRequest method.
      public void ProcessRequest(HttpContext context)
      {
         // Your preparations, i.e. querystring or something
         var conn = new SqlConnection("Your connectionstring");
         var command = new SqlCommand("Your sql for retrieval of the bytes", conn);
         conn.Open();
         var data = (Byte[])command.ExecuteScalar();
         conn.Close();
         context.Response.BinaryWrite(data);      }

      public Boolean IsReusable
      {
         get { return false; }
      }
   }
}
OleDbConnection con = new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\KUTTY\Real_Project\Royalty_Pro\DbRoyalty_Access\Buzz_Loyalty.mdb");
DataSet ds = new DataSet();
con.Open();
OleDbCommand cmd = new OleDbCommand("select pic from test_table where id_image='123'",con);
OleDbDataAdapter da=new OleDbDataAdapter(cmd);
da.Fill(ds,"test_table");
//con.Close();

//ds = new DataSet();
//da.Fill(ds, "test_table");
FileStream FS1 = new FileStream("image.jpg", FileMode.Create);
if (ds.Tables["test_table"].Rows.Count > 0)
{
    byte[] blob = (byte[])ds.Tables["test_table"].Rows[0]["pic"];
    FS1.Write(blob, 0, blob.Length);
    FS1.Close();
    FS1 = null;

    byte[] imageData = (byte[])cmd.ExecuteScalar();
    MemoryStream ms = new MemoryStream(imageData, 0, imageData.Length);
    pictureBox2.Image = Image.FromStream(ms);



    pictureBox2.Image = Image.FromFile("image.jpg");
    pictureBox2.SizeMode = PictureBoxSizeMode.StretchImage;
    pictureBox2.Refresh();

    pictureBox2.Image = Image.FromStream(new MemoryStream(blob));  
    pictureBox2.Image = Image.FromFile("image.jpg");
    pictureBox2.SizeMode = PictureBoxSizeMode.StretchImage;
    pictureBox2.Refresh();
}

您應該使用參數化查詢,而不是連接SQL字符串。

除了修復明顯的SQL Injection漏洞之外,這還使您能夠將映像正確插入數據庫中。

有關如何插入SQL Server映像/二進制字段的問題和答案有很多,您應該看看它們。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM