简体   繁体   English

为什么二进制中的Sql Server映像在字符串查询中导致问题,但在参数化查询中起作用

[英]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. 我正在将图像保存在VarBinary及其工作表中。但是问题是,如果我在检索图像时使用字符串查询保存图像,则表示参数无效,尽管图像二进制文件已保存在数据库中并且可以看到它。 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. 为什么会发生这种情况,为什么使用Parametriczed查询二进制文件在行中不同,而使用字符串查询它在行中却不同,这很奇怪。

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...). 在第二个数据快照的十六进制( 0x53797374... )中,所有字节均拼出了类型名称(“ System.Byte []”可能是?我停止翻译了...)。

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. 当您使用CONVERT(VARBINARY(MAX), '" + array + "')"构建字符串时CONVERT(VARBINARY(MAX), '" + array + "')"将调用数组ToString方法,该方法在System.Array上定义不正确,并返回类型的名称。看起来像INSERT INTO ... (CONVERT(VARBINARY(MAX), 'System.Byte[]') ,并且将其错误地插入数据库。

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. 选择参数化选项绝对是最安全的方法(就安全性和潜在错误而言),但是如果您想将其作为SQL字符串执行,则需要构建一个实际字节的字符串,如所示在ErikEJ的回答中。

You have a different INSERT statement in the string query code. 字符串查询代码中有另一个INSERT语句。

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. 删除CONVERT应该会使两个语句以相同的方式插入。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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