[ Team LiB ] |
Recipe 9.11 Reading and Writing Binary Data with SQL ServerProblemYou need to read and write binary data from and to a SQL Server 2000 database. SolutionUse the techniques from the following example. The schema of table TBL0911 used in this solution is shown in Table 9-3.
The sample code contains nine event handlers:
The C# code is shown in Example 9-14. Example 9-14. File: BinaryDataForm.cs// Namespaces, variables, and constants using System; using System.Configuration; using System.Drawing; using System.Windows.Forms; using System.IO; using System.Data; using System.Data.SqlClient; private const String TABLENAME = "TBL0911"; private DataSet ds; private SqlDataAdapter da; private BindingManagerBase bm; private Byte[] image; // . . . private void BinaryDataForm_Load(object sender, System.EventArgs e) { // Create the DataSet. ds = new DataSet( ); // Define select and update commands for the DataAdapter. String selectCommand = "SELECT Id, Description FROM " + TABLENAME; String updateCommand = "UPDATE " + TABLENAME + " " + "SET Description = @Description " + "WHERE Id = @Id"; // Create the DataAdapter. da = new SqlDataAdapter(selectCommand, ConfigurationSettings.AppSettings["Sql_ConnectString"]); da.UpdateCommand = new SqlCommand(updateCommand, da.SelectCommand.Connection); da.UpdateCommand.CommandType = CommandType.Text; da.UpdateCommand.Parameters.Add("@Id", SqlDbType.Int, 0, "Id"); da.UpdateCommand.Parameters.Add("@Description", SqlDbType.NVarChar, 50, "Description"); // Fill the schema and the data from the table. da.FillSchema(ds, SchemaType.Source, TABLENAME); da.Fill(ds, TABLENAME); // Bind all of the controls to the DataSet. idTextBox.DataBindings.Add("Text", ds, TABLENAME + ".Id"); descriptionTextBox.DataBindings.Add("Text", ds, TABLENAME + ".Description"); // Get the binding manager base for the parent table. bm = BindingContext[ds, TABLENAME]; // Handler to update the correct image in response to // each record reposition bm.PositionChanged += new EventHandler(bm_PositionChanged); // Update the display for the first record. bm_PositionChanged(null, null); } private void bm_PositionChanged(Object sender, EventArgs e) { // Handler for the binding manager record change // Clear the image and picture box. image = null; imagePictureBox.Image = null; // Get the ID for the record from the binding manager. int Id = (int)ds.Tables[TABLENAME].Rows[bm.Position]["ID"]; // Create the connection. SqlConnection conn = new SqlConnection( ConfigurationSettings.AppSettings["Sql_ConnectString"]); // Create the command to retrieve the image from the database. String sqlText = "SELECT BlobData FROM " + TABLENAME + " WHERE Id = " + Id; SqlCommand cmd = new SqlCommand(sqlText, conn); // Retrieve the image to a stream. conn.Open( ); try { int bufferSize = 100; byte[] outbyte = new byte[bufferSize]; long retVal = 0; long startIndex = 0; SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.SequentialAccess); dr.Read( ); // Check to see if the field is DBNull. if (!dr.IsDBNull(0)) { // Create the memory stream to hold the output. MemoryStream ms = new MemoryStream( ); // Read the bytes into outbyte. retVal = dr.GetBytes(0, startIndex, outbyte, 0, bufferSize); // Keep reading while there are more bytes // beyond the buffer. while (retVal == bufferSize) { // Write the bytes to the memory stream. ms.Write(outbyte, 0, outbyte.Length); // Update the start index and // fill the buffer again. startIndex += bufferSize; retVal = dr.GetBytes(0, startIndex, outbyte, 0, bufferSize); } // Write the bytes remaining in the buffer. ms.Write(outbyte, 0, (int)retVal - 1); // Transfer the memory stream to the image. image = ms.ToArray( ); } } catch (System.InvalidCastException) { // Image is null or invalid in the database. Ignore. } finally { conn.Close( ); } if (image != null) { // Load the image into a stream. MemoryStream ms = new MemoryStream(image); try { // Set the PictureBox image to the value of the stream. imagePictureBox.Image = Image.FromStream(ms); } catch(Exception ex) { MessageBox.Show(ex.Message); } // Close the stream. ms.Close( ); } } private void selectImageButton_Click(object sender, System.EventArgs e) { // Create the file dialog to select image. OpenFileDialog ofd = new OpenFileDialog( ); ofd.InitialDirectory = System.IO.Path.GetTempPath( ); ofd.Filter = "Bitmap Files (*.bmp)|*.bmp|JPEG files (*.jpg)|*.jpg|" + "All files (*.*)|*.*"; ofd.FilterIndex = 2; if (ofd.ShowDialog( ) == DialogResult.OK) { // Read image into file stream, and from there into Byte array. FileStream fs = new FileStream(ofd.FileName, FileMode.Open, FileAccess.Read); image = new Byte[fs.Length]; fs.Read(image, 0, image.Length); try { // Set the PictureBox image from the stream. imagePictureBox.Image = Image.FromStream(fs); } catch (Exception ex) { MessageBox.Show(ex.Message); image = null; } fs.Close( ); } } private void clearImageButton_Click(object sender, System.EventArgs e) { // Clear the image and picture box. image = null; imagePictureBox.Image = null; } private void updateButton_Click(object sender, System.EventArgs e) { // Update the data and image to the database. // Get the ID for the record from the binding manager. int Id = (int)ds.Tables[TABLENAME].Rows[bm.Position]["ID"]; String sqlWrite = "UPDATE " + TABLENAME + " SET BlobData = @BlobData WHERE ID = " + Id; // Create the connection and command. SqlConnection conn = new SqlConnection( ConfigurationSettings.AppSettings["Sql_ConnectString"]); SqlCommand cmdWrite = new SqlCommand(sqlWrite, conn); // Create parameter for insert command. SqlParameter prm; if(image != null) { // Add a parameter for the image binary data. prm = new SqlParameter("@BlobData", SqlDbType.VarBinary, image.Length, ParameterDirection.Input, false, 0, 0, null, DataRowVersion.Current, image); } else { // Add a parameter for a null image. prm = new SqlParameter("@BlobData", SqlDbType.VarBinary, 0, ParameterDirection.Input, false, 0, 0, null, DataRowVersion.Current, System.DBNull.Value); } // Add the parameter to the command. cmdWrite.Parameters.Add(prm); // Execute the command to update the image in the database. conn.Open( ); cmdWrite.ExecuteNonQuery( ); conn.Close( ); // End the binding manager edit. bm.EndCurrentEdit( ); // Use the DataAdapter to update the table data. da.Update(ds.Tables[TABLENAME]); } private void moveFirstButton_Click(object sender, System.EventArgs e) { bm.Position = 0; } private void movePreviousButton_Click(object sender, System.EventArgs e) { bm.Position -= 1; } private void moveNextButton_Click(object sender, System.EventArgs e) { bm.Position += 1; } private void moveLastButton_Click(object sender, System.EventArgs e) { bm.Position = bm.Count - 1; } DiscussionYou can write a BLOB to a data source using several techniques:
You can read a BLOB from a data source using several techniques:
A BLOB can be quite large and may require a lot of system memory to be written to a data source as a single value. In addition to reading BLOBs in chunks, some data sources allow you to write a BLOB to the data source in chunks. For more information consult the MSDN Library and the documentation for your .NET data provider. |
[ Team LiB ] |