Как я могу передать BLOB на VARBINARY (MAX) на INSERT - PullRequest
3 голосов
/ 05 декабря 2011

Я нашел много информации о том, как выбрать большой двоичный объект в качестве потока с помощью CommandBehavior.SequentialAccess.

Я также хотел бы передать потоковый большой двоичный объект на вставку (чтобы избежать кэширования большого двоичного объекта какмассив байтов в памяти), и я не могу найти никаких примеров.Я нашел некоторую документацию, в которой упоминается синтаксис .WRITE (expression,@Offset, @Length) в операторе UPDATE T-SQL, который совместим с VARBINARY(MAX).Итак, я думаю о написании класса, который может взять Stream и поместить его в базу данных, используя последовательные операторы UPDATE (.WRITE).Это правильный способ сделать это, или есть лучший способ?

Ссылки на UPDATE.WRITE:

http://msdn.microsoft.com/en-us/library/ms178158(SQL.100).aspx

http://msdn.microsoft.com/en-us/library/ms177523(v=SQL.100).aspx

Ссылки на выбор BLOB-объектов с помощью CommandBehavior.SequentialAccess:

http://msdn.microsoft.com/en-us/library/87z0hy49.aspx

Эффективный для памяти способ чтения BLOB-данных в C # / SQL 2005

Получение двоичных данных с использованием SqlDataReader

Как сделать потоки из больших двоичных объектов доступными в простых старых объектах C # при использовании SqlDataReader?

Потоковая передача VARBINARY данных из SQL Server в C #

ВотPOC с использованием синтаксиса .Write:

DDL:

create database BlobTest
go
use blobtest
go

create table Blob
(
    Id bigint not null primary key identity(1,1),
    Data varbinary(max) not null default(0x)
)

C #:

using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main()
        {
            string pathToBigFile = "C:\\bigfile.big";
            int optimumBufferSizeForSql = 8040; //See /5378615/kak-sozdat-stsenarii-insert-dlya-tablitsy-s-polem-varbinary-max

            long newBlobId = InitialiseNewBlobInSqlServer();

            using (Stream stream = new FileStream(  pathToBigFile, 
                                                    FileMode.Open, 
                                                    FileAccess.Read, 
                                                    FileShare.ReadWrite))
            {
                byte[] buffer = new byte[optimumBufferSizeForSql];

                while(true)
                {
                    int numberBytesRead = stream.Read(buffer, 0, optimumBufferSizeForSql);

                    if (numberBytesRead == 0)
                    {
                        //Done
                        break;
                    }

                    WriteBufferToSqlServer(
                        numberBytesRead == optimumBufferSizeForSql ? buffer : buffer.Take(numberBytesRead).ToArray(),
                        newBlobId);
                }
            }
        }

        static long InitialiseNewBlobInSqlServer()
        {
            using (SqlConnection conn = new SqlConnection("Data Source=localhost; Initial Catalog=BlobTest; Integrated Security=SSPI;"))
            using (SqlCommand command = new SqlCommand())
            {
                command.Connection = conn;
                command.CommandType = CommandType.Text;
                command.CommandText = "Insert into blob (Data) values (0x); select convert(bigint,Scope_identity());";

                conn.Open();
                return (long) command.ExecuteScalar();
            }
        }

        static void WriteBufferToSqlServer(byte[] data, long blobId)
        {
            using (SqlConnection conn = new SqlConnection("Data Source=localhost; Initial Catalog=BlobTest; Integrated Security=SSPI;"))
            using (SqlCommand command = new SqlCommand())
            {
                command.Connection = conn;
                command.CommandType = CommandType.Text;
                command.Parameters.AddWithValue("@id", blobId);
                command.Parameters.AddWithValue("@data", data);
                command.CommandText = "Update Blob set Data.Write(@data, null, null) where Id = @id;";

                conn.Open();
                command.ExecuteNonQuery();
            }
        }
    }
}

1 Ответ

1 голос
/ 05 декабря 2011

Вы должны использовать RBS интерфейс SQL Server для работы с BLOB-объектами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...