Сценарий для сохранения варбинальных данных на диск

StackOverflow https://stackoverflow.com/questions/4056050

Вопрос

У меня есть некоторые варбинарные данные, хранящиеся в таблице в MS SQL Server 2005. У кого-нибудь есть код SQL, который принимает запрос в качестве входа (позволяет вернуть запрос, гарантирует, что один столбец varbinary возвращается) и выводит байты на диск (один файл За ряд?) Я уверен, что это было задано тысячу раз ранее, но Googling поднимается в основном .NET Solutions. Я хочу решение SQL.

Это было полезно?

Решение

Подход BCP не работает для меня. Байты, которые он пишет на диск, не может быть десериализирован обратно на объекты .NET, которые я сохранил. Это означает, что байты на диске не эквивалентны тому, что хранится. Возможно, BCP пишет какой-то заголовок. Я не уверен.

Я нашел следующий код здесь внизу статьи. Работает отлично! Хотя он был предназначен для сохраненных изображений BMP, он работает с любым варбиным.

DECLARE @SQLIMG VARCHAR(MAX),
    @IMG_PATH VARBINARY(MAX),
    @TIMESTAMP VARCHAR(MAX),
    @ObjectToken INT

DECLARE IMGPATH CURSOR FAST_FORWARD FOR 
        SELECT csl_CompanyLogo from mlm_CSCompanySettingsLocalizations

OPEN IMGPATH 

FETCH NEXT FROM IMGPATH INTO @IMG_PATH 

WHILE @@FETCH_STATUS = 0
    BEGIN
        SET @TIMESTAMP = 'd:\' + replace(replace(replace(replace(convert(varchar,getdate(),121),'-',''),':',''),'.',''),' ','') + '.bmp'

        PRINT @TIMESTAMP
        PRINT @SQLIMG

        EXEC sp_OACreate 'ADODB.Stream', @ObjectToken OUTPUT
        EXEC sp_OASetProperty @ObjectToken, 'Type', 1
        EXEC sp_OAMethod @ObjectToken, 'Open'
        EXEC sp_OAMethod @ObjectToken, 'Write', NULL, @IMG_PATH
        EXEC sp_OAMethod @ObjectToken, 'SaveToFile', NULL, @TIMESTAMP, 2
        EXEC sp_OAMethod @ObjectToken, 'Close'
        EXEC sp_OADestroy @ObjectToken

        FETCH NEXT FROM IMGPATH INTO @IMG_PATH 
    END 

CLOSE IMGPATH
DEALLOCATE IMGPATH

Другие советы

Вы можете использовать BCP, а не T-SQL, но хорошо работает.

BCP "SELECT FileContent FROM table WHERE ID = 1" queryout "C:\file.txt" -T

Я добавляю это, чтобы построить ответ Джонпинара, так что другие, которые хотят использовать LinqPad, могут получить рабочий раствор быстрее.

/*
This LinqPad script saves data stored in a VARBINARY field to the specified folder.
1. Connect to SQL server and select the correct database in the connection dropdown (top right)
2. Change the Language to C# Program
3. Change "Attachments" to the name of your table that holds the VARBINARY data
4. Change "AttachmentBuffer" to the name of the field that holds the data
5. Change "Id" to the unique identifier field name
6. Change "1090" to the identity of the record you want to save
7. Change the path to where you want to save the file. Make sure you choose the right extension.

Notes: Windows 10 may give you "Access Denied" error when trying to save directly to C:\. Rather save to a subfolder.
*/

void Main()
{
    var context = this;
    var query = 
        from ci in context.Attachments
        where ci.Id == 1090
        select ci.AttachmentBuffer
    ;
    byte[] result = query.Single().ToArray();
    File.WriteAllBytes(@"c:\DEV\dumpfile.xlsx", result);
    Console.WriteLine("Done");
}

Я знаю, что это старый пост, но я понял, почему следующее не работает и как это исправить:

BCP "SELECT FileContent FROM table WHERE ID = 1" queryout "C:\file.JPG" -T -N

Причина в BCP положит длину префикса в самом начале файла. Это либо 4 байта, либо 8 байта, зависит от типа данных столбца FileContent (Text, nText, изображение: 4 varchar (max), varbinary (max): 8 см. https://msdn.microsoft.com/en-us/library/ms190779.aspx.)

Используйте бинарный редактор, например, в Visual Studio, для удаления Prefix Bytes, и все работает идеально. :-)

Если у вас есть LinqPad, это работает:

void Main()
{
    var context = this;
    var query = 
        from ci in context.Images
        where ci.ImageId == 10
        select ci.Image
    ;
    var result = query.Single ();
    var bytes = Convert.FromBase64String(result);
    File.WriteAllBytes(@"c:\image.bmp", bytes);
}

Просто альтернатива. Вы можете использовать Toad Freeware Toad для SQL Server и сэкономить непосредственно из редактора.

Вы можете пойти на свой веб-сайт https://www.toadworld.com. И получить бесплатное программное обеспечение там или 30-дневную пробную версию по полной версии. Это под загрузкой и выбрать Toad для SQL Server.

enter image description here

Вы делаете регулярное выберите оператор в TOAD на линии, который имеет изображение, которое вы хотите сохранить. Когда вы видите результаты, вы можете нажать на столбец Image BYTE и справа, вы видите вкладку PDF, если это документ PDF или слева, вы видите вкладку Image. Когда вы нажимаете на вкладку, вы можете увидеть логотип сохранения внизу, чтобы сохранить изображение или файл.

SQL предназначен для работы с объектами базы данных, так что от его точки зрения что-либо еще не существует. Конечно, есть расширенные процедуры, такие как xp_cmdshell Это позволяет вам взаимодействовать с операционной системой, но они являются проприетарными расширениями и не являются частью T-SQL.

Возможно, ближайший подход будет использовать атрибут FileStream для двоичных типов SQL Server 2008, которые позволяют хранить некоторые столбцы непосредственно в качестве файлов в папке, а не с помощью базы данных:

Обзор FileStream

Примечание Чтобы хранилище FileStream предназначена для поддержания больших файлов из базы данных, чтобы увеличить производительность, а не для разрешения прямого доступа к файлам (т.е. T-SQL все еще не имеет концепции файловой системы). Я мое мнение, прямой доступ к файловой системе от SQL будет победить некоторые из целей базы данных (в основном, имеющие данные, хранящиеся в структурированном виде).

Поэтому я бы порекомендовал следовать совету Dustin и использовать инструмент, такой как BCP или любые другие данные DUMPER.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top