【问题标题】:How to pass byte[] from C# as string to SQL Server stored procedure and convert into varbinary(MAX)如何将 C# 中的 byte[] 作为字符串传递给 SQL Server 存储过程并转换为 varbinary(MAX)
【发布时间】:2016-05-26 22:43:36
【问题描述】:

在这个项目中,有一个封装了 ADO.NET 的类,用于常见的数据访问,如 ExecuteDataReaderExecuteScalar 等。

当使用这些方法调用存储过程时,它允许您传递一个Dictionary<string, string> 的参数(字符串键、字符串值),然后将它们作为SqlParameter 添加到SqlCommand 对象中。

有一种情况是我们必须在数据库中保存一个文档。文档是byte[],数据库中对应的列是varbinary(MAX)

我们已经四处寻找解决方案,但所有可用的都是使用 SqlDbType.Varbinary 的示例,在这种情况下这不是一个选项。

我们最近的尝试是尝试将byte[] 转换为二进制字符串,将其作为nvarchar(max) 传递到存储过程中,然后在将其保存到Document 表时使用CONVERT(varbinary(max), @theFileBinaryString),但是,这保存损坏的文件。

C#

byte[] pDocumentBytes = ...;
string documentAsBinary = "0x" + BitConverter.ToString(pDocumentBytes).Replace("-", ""); 

SQL

@DocumentContentAsBinary nvarchar(max) -- This is "documentAsBinary" from C# above

DECLARE @DocumentContentVarbinary varbinary(max);
SET @DocumentContentVarbinary = CONVERT(varbinary(max), @DocumentContentAsBinary);

【问题讨论】:

    标签: c# sql-server stored-procedures varbinary


    【解决方案1】:

    假设你有这个 SP:

    DECLARE
    @Value1 ...
    @Value2 ...
    ...
    @File VARBINARY(MAX)
    
    INSERT INTO [YourTable] (Column1, Column2, ..., File) VALUES (@Value1, @Value2, ..., @File)
    

    使用此语法将文件转换为字节数组,并直接将字节数组作为 varbinary 数据插入:

    using System.Data.SqlClient;
    using System.IO;
    
    byte[] data;
    
    using (FileStream fs = new FileStream(document, FileMode.Open)
    {
        BinaryReader fileReader = new BinaryReader(document);
        data = fileReader.ReadBytes((int)document.Length);
        document.Close(); // don't forget to close file stream
    }
    
    using (var connection = new SqlConnection("YourConnectionStringHere"))
    {
        connection.Open();
        using (var command = new SqlCommand("YourSPHere", connection)
        {
            command.CommandType = CommandType.StoredProcedure;
    
            // insert parameters here
    
            // add file parameter at the end of collection parameters
            command.Parameters.AddWithValue("@File", SqlDbType.VarBinary).Value = data;
            command.ExecuteNonQuery();
        }
        connection.Close();
    }
    

    参考:http://www.codeproject.com/Questions/309795/How-to-insert-byte-array-into-SQL-table

    我希望这个解决方案有用。

    【讨论】:

    • 感谢您的回复。我们调用的 SP 接受一个用户定义的表参数,它只接受文档内容为 nvarchar(max)。我们需要找到正确的方法将它作为 nvarchar(max) 传递给 SP,以便它可以在 SP 内转换为 varbinary(max)。
    【解决方案2】:

    VARBINARY(MAX)byte[] 之间没有正确映射的SqlDbType。但实际上这没关系,因为参数化基础设施只是为您处理这个,下面的代码就可以工作了:

    var binary = new bytes[1];
    var command = new SqlCommand("INSERT INTO [MyTable]([BinaryColumn]) VALUES (@binary)");
    command.Parameters.AddWithValue("@binary", binary);
    command.ExecuteNonQuery();
    

    更多详情请看这里: What SqlDbType maps to varBinary(max)?

    【讨论】:

    • 感谢您的回复。不幸的是,这在这种情况下不起作用,因为我们必须将文档内容作为 nvarchar(max) 传递,然后在 SP 中进行转换。
    • 但是为什么呢?转换为 NVARCHAR 然后再转换回来根本没有意义。存储过程的参数完全错误,需要更改。
    【解决方案3】:

    更新您的查询以使用参数并将字节数组作为参数直接传递给表

    例如 SQL:

    insert into table values (@data);
    

    C#

    SqlComman com = new SqlCommand("insert into table values (@data);",Database Connection);
    com.Paramaters.Add(new SqlParameter("@Data" Byte array));
    com.executeNonQuery();
    

    【讨论】:

    • 感谢您的回复。不幸的是,我们无法完全控制 SqlCommand 对象,必须将文件作为 nvarchar(max) 传递。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-24
    • 2017-09-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多