Хранить BLOB-объекты в SQL Server, не считывая BLOB-объекты в память - PullRequest
4 голосов
/ 22 июля 2011

Я пытаюсь выполнить чтение из потока непосредственно в поле / запись в SQL Server.

Нетрудно сохранить файл на SQL Server, в сети есть множество примеров;
но я не могу найти ни одного примера, чтобы сначала не считал весь файл в память .

например:

byte[] data = BinaryReader.ReadBytes((int)filestream.Length);
cmd.Parameters.Add("@Data", SqlDbType.Image, data.Length).Value = data;

или что-то подобное.

Я мог бы использовать собственные команды SQL Server, но тогда мне пришлось бы поиграться с правами для SQL Server на чтение с другого компьютера / папки, и вместо этого я хотел бы сохранить все это на бизнес-уровне .NET.

Ответы [ 3 ]

1 голос
/ 22 июля 2011

Единственный способ, которым вы сможете это сделать, - это циклическое чтение фрагментов из вашего потока и выдача обновления базовой таблицы, используя UPDATE .WRITE или FILESTREAM.

Это не должно требовать больше разрешений, чем обычное обновление / вставка.

1 голос
/ 25 июля 2011

Я использовал эти ресурсы:

http://lennilobel.wordpress.com/2011/01/23/sql-server-2008-filestream-part-3-of-3-using-the-opensqlfilestream-api-2/ <- более или менее точный код dotnet для копирования. </p>

http://blogs.msdn.com/b/sqlserverstorageengine/archive/2008/03/03/filestream-configuration-and-setup-changes-in-sql-server-2008-february-ctp.aspx <- настройка файлового потока в sqlserver, упоминает об ошибке и ссылается на решение </p>

http://blogs.msdn.com/b/sqlserverstorageengine/archive/2008/06/09/enabling-filestream-post-sql2008-setup-a-known-issue-in-sql-config-manager.aspx <- решение проблемы, скрипт для запуска </p>

http://sqlsrvengine.codeplex.com/wikipage?title=FileStreamEnable&referringTitle=Home&ProjectName=sqlsrvengine <- скрипт </p>

(http://www.mssqltips.com/tip.asp?tip=1489 // Слишком стар, имеет неправильные имена)

, чтобы помочь мне.
Я обменялся функциональностью, чтобы передать данные прямо в веб-браузер(или чтение в ОЗУ) для сохранения его в файл с этим кодом:

    private static void CopyFile(string sourcePath, byte[] transToken, string targetPath, Guid uid)
    {
        //  Should we use a buffer here?  I mean - does this firehose use memory according to the file size?  If so - use a buffer and copy piece by piece.
        SafeFileHandle handle = NativeSqlClient.GetSqlFilestreamHandle(sourcePath, NativeSqlClient.DesiredAccess.Read, transToken);
        using (var fileSource = new FileStream(handle, FileAccess.Read))
        {
            using (var fileDest = new FileStream(Path.Combine(targetPath, uid.ToString()), FileMode.CreateNew, FileAccess.Write))
            {
                fileSource.CopyTo(fileDest);
                fileDest.Flush();
                fileDest.Close();
            }
            fileSource.Close();
        }
    }

Если вы используете код с сайта LLobel выше, вы узнаете, куда вставить вызов этого метода.

Также обратите внимание, что нельзя изменить порядок полей с помощью drag'n'drop в SQLServermanagementstudio;атрибут filestream в поле удаляется.

0 голосов
/ 22 июля 2011

Большой двоичный объект должен находиться в памяти процесса, который передает данные в SQL Server, так как все это необходимо передать в вызове.

Вы не можете передавать запрос в SQL, поэтому он будет считывать параметр в виде потока - следовательно, вам нужен весь файл в памяти.

Никакого обхода.

...