Reading SQL Varbinary Blob from Database

后端 未结 3 1228
情书的邮戳
情书的邮戳 2021-01-01 18:12

I am working on saving files to sql blob to a varbinary(max) column, and have got the save side of things working now (I believe).

What I can\'t figure out is how to

3条回答
  •  轮回少年
    2021-01-01 18:45

    With the .NET SQL Server provider, you can use a little-known but cool class called SqlBytes. It's been designed specifically to map varbinary fields, but there are not many examples on how to use it.

    Here is how you can save to the database with it (you can use a stored procedure or direct SQL like I demonstrate here, we just presume the MyBlobColumn is a varbinary one).

    string inputPath = "YourInputFile";
    using (var conn = new SqlConnection(YourConnectionString))
    {
        conn.Open();
        using (var cmd = conn.CreateCommand())
        {
            // note we define a '@blob' parameter in the SQL text
            cmd.CommandText = "INSERT INTO MyTable (Id, MyBlobColumn) VALUES (1, @blob)";
            using (var inputStream = File.OpenRead(inputPath))
            {
                // open the file and map it to an SqlBytes instance
                // that we use as the parameter value.
                var bytes = new SqlBytes(inputStream);
                cmd.Parameters.AddWithValue("blob", bytes);
    
                // undercovers, the reader will suck the inputStream out through the SqlBytes parameter
                cmd.ExecuteNonQuery();
            }
        }
    }
    

    To read the file out into a stream from the database, here is how you can do it.

    string outputPath = "YourOutputFile";
    using (var conn = new SqlConnection(YourConnectionString))
    {
        conn.Open();
        using (var cmd = conn.CreateCommand())
        {
            // this is a regular direct SQL command, but you can use a stored procedure as well
            cmd.CommandText = "SELECT MyBlobColumn FROM MyTable WHERE Id = 1";
    
            // note the usage of SequentialAccess to lower memory consumption (read the docs for more)
            using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess))
            {
                if (reader.Read())
                {
                    // again, we map the result to an SqlBytes instance
                    var bytes = reader.GetSqlBytes(0); // column ordinal, here 1st column -> 0
    
                    // I use a file stream, but that could be any stream (asp.net, memory, etc.)
                    using (var file = File.OpenWrite(outputPath))
                    {
                        bytes.Stream.CopyTo(file);
                    }
                }
            }
        }
    }
    

    With these techniques, we never allocated any byte[] nor MemoryStream instances, just used in and out SQL or File Streams.

提交回复
热议问题