简体   繁体   中英

Why Sql Server Image In Binary Causes Issue in string Query but works in Parameterized Query

I am saving Image in a table in VarBinary and its working.but the problem is if i save image using string query when i retrieve it it says parameter not valid although Image binary is save in database and i can see it. but if i use parametrized query and retrieve image it is displayed correctly:

Here is my parametrized query code:

     try
                    {
                        byte[] byteImg = ImageToByteArray(pictureBox1.Image);
                        connection = con.getConnection();
                        if (connection != null)
                        {
                            query = @"INSERT INTO [tblImages]
                               ([Image])
                         VALUES
                               (@image)";
                            connection.Open();
                            cmd = new SqlCommand(query, connection);
                            cmd.Parameters.AddWithValue("@image", byteImg);
                            cmd.ExecuteNonQuery();
                            MessageBox.Show("Saved");
                            connection.Close();
                            pictureBox1.Image = null;
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                    }

Database Row View Using Parameterized:

在此处输入图片说明

Here is my string query code:

 try
                {
                     byte[] byteImg = ImageToByteArray(pictureBox1.Image);
                    connection = con.getConnection();
                    if (connection != null)
                    {
                        query = @"INSERT INTO [tblImages]
                           ([Image])
                     VALUES
                           (Convert(varbinary(MAX),'" + byteImg + "'))";
                        connection.Open();
                        cmd = new SqlCommand(query, connection);
                        cmd.ExecuteNonQuery();
                        MessageBox.Show("Saved");
                        connection.Close();
                        pictureBox1.Image = null;
                    }
                }
                catch
                {

                }

Byte Conversion Method:

public byte[] ImageToByteArray(Image img)       
        {
            System.IO.MemoryStream ms = new System.IO.MemoryStream();
            img.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
            return ms.ToArray();
        }

Database Row View:

在此处输入图片说明

Why is this happening why using Parametrized query binary is different in row and using string query it different, its very weird.

Any help will be appreciated.

You can actually just do:

INSERT INTO [tblImages]  ([Image])
VALUES 0x5379......

To build the binary string use code like this (buffer is your byte array)

_sbScript.Append("0x");

for (int i = 0; i < buffer.Length; i++)
{
    _sbScript.Append(buffer[i].ToString("X2",System.Globalization.CultureInfo.InvariantCulture));
}

In the hex in the second data snapshot ( 0x53797374... ) all the bytes spell out the type name ("System.Byte[]" maybe? I stopped translating...).

0x53 - 'S'
0x79 - 'y'
0x73 - 's'
0x74 - 't'
0x65 - 'e'
0x6D - 'm'

When you build the string using CONVERT(VARBINARY(MAX), '" + array + "')" the arrays ToString method is being called, which is not well defined on System.Array and returns the name of the type. Then your Sql looks like INSERT INTO ... (CONVERT(VARBINARY(MAX), 'System.Byte[]') and that will be inserted into the database in error.

Choosing the parameterized option would definately be the safer way to go (with respect to both Security, and potential bugs), but if you want to execute it as a SQL string, you will want to build a string of the actual bytes, as demonstrated in ErikEJ's answer.

You have a different INSERT statement in the string query code.

The parametrized query code is:

query = @"INSERT INTO [tblImages]
                 ([Image])
          VALUES (@image)";

Whilst the string query code is:

query = @"INSERT INTO [tblImages]
                 ([Image])
          VALUES (Convert(varbinary(MAX),'" + byteImg + "'))";

Removing the CONVERT should woudl make the two statements insert in the same way.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM