Гость
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Выгрузка файла на диск из БД / 12 сообщений из 12, страница 1 из 1
21.01.2021, 21:34
    #40037768
Петр
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выгрузка файла на диск из БД
Храню файл в таблице в поле image в формате BASE64. (SQL 2008)
Подскажите как средствами sql мне выгрузить этот файл на диск. Выгрузку планирую повесить на триггер.
...
Рейтинг: 0 / 0
21.01.2021, 22:14
    #40037779
flexgen
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выгрузка файла на диск из БД
Петр
Храню файл в таблице в поле image в формате BASE64. (SQL 2008)
Подскажите как средствами sql мне выгрузить этот файл на диск. Выгрузку планирую повесить на триггер.


Есть несколько вариантов
  • использовать Ole Automation Procedures, поищи в сети процедуру usp_ExportImage;
  • использовать BCP, в сети полно примеров как и что надо делать;
  • использовать  SSIS, это самый простой вариант, как мне кажется.
...
Рейтинг: 0 / 0
21.01.2021, 22:58
    #40037787
Владислав Колосов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выгрузка файла на диск из БД
Петр,

base64 лучше хранить в varchar(max) поле.
...
Рейтинг: 0 / 0
23.01.2021, 08:44
    #40038224
uaggster
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выгрузка файла на диск из БД
Поднять версию MSSQLSERVER до 2012, и выгружать данные в filetable с внешним нетразакционным доступом.
И в триггере тогда будет можно :-).
... хотя я бы взвел service broker, и в триггере просто отправлял туда сообщения.
...
Рейтинг: 0 / 0
25.01.2021, 05:54
    #40038533
shalomb
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выгрузка файла на диск из БД
Это пример по чтению ,переделай Scripting.FileSystemObject под запись.





ALTER PROCEDURE [dbo].[spREADFileStream] @FILE_PATH VARCHAR(MAX) ,@FILE_NAME VARCHAR(100) ,@STRING VARCHAR(MAX) OUTPUT AS
BEGIN
DECLARE @objFileSystem INT ,@objTextStream INT ,@objErrorObject INT ,@strErrorMessage VARCHAR(1000) ,@Command VARCHAR(1000) ,@Chunk VARCHAR(8000) ,@strText VARCHAR(max) ,@intResult INT ,@YesOrNo INT
SELECT @strText = ''
SELECT @strErrorMessage = 'File System Object'
EXECUTE @intResult = sp_OACreate 'Scripting.FileSystemObject' ,@objFileSystem OUT
IF @intResult = 0
SELECT @objErrorObject = @objFileSystem, @strErrorMessage ='Opening file "' + @FILE_PATH + '\' +
@FILE_NAME + '"',@command = @FILE_PATH + '\' + @FILE_NAME
IF @intResult = 0
EXECUTE @intResult = sp_OAMethod @objFileSystem , 'OpenTextFile', @objTextStream OUT, @command,1,false,0 --//Forreading, FormatASCII
WHILE (@intResult = 0)
BEGIN
IF @intResult = 0
SELECT @objErrorObject = @objTextStream,
@strErrorMessage = 'Finding out if there is more to read in "' +@FILE_NAME + '"'
IF @intResult = 0
EXECUTE @intResult = sp_OAGetProperty @objTextStream, 'AtEndOfStream', @YesOrNo OUTPUT
IF @YesOrNo<>0
BREAK
IF @intResult = 0
SELECT @objErrorObject = @objTextStream,@strErrorMessage = ' Reading from the output file "' + @FILE_NAME + '"'
IF @intResult = 0
EXECUTE @intResult = sp_OAMethod @objTextStream, 'Read', @chunk OUTPUT,4000
SELECT @strText = @strText + @chunk
END
IF @intResult = 0
SELECT @objErrorObject = @objTextStream, @strErrorMessage = 'Closing the output file "' + @FILE_NAME + '"'
IF @intResult = 0
EXECUTE @intResult = sp_OAMethod @objTextStream, 'Close'
IF @intResult<>0
BEGIN
DECLARE @Source VARCHAR(255),@Description VARCHAR(255) ,@Helpfile VARCHAR(255),@HelpID INT
EXECUTE sp_OAGetErrorInfo @objErrorObject, @source OUTPUT,@Description OUTPUT,@Helpfile OUTPUT,@HelpID OUTPUT
SELECT @strErrorMessage = 'Error whilst ' + coalesce(@strErrorMessage,'doing something') + ', ' + coalesce(@Description,'')
SELECT @strText = @strErrorMessage
END
EXECUTE sp_OADestroy @objTextStream
SET @STRING = @strText
RETURN
END
...
Рейтинг: 0 / 0
19.07.2021, 16:24
    #40084688
Петр
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выгрузка файла на диск из БД
Для выгрузки файлов взял пример как советовал flexgen через OLE (код ниже). Для моего случая подходит, за одним исключением, у меня сейчас файлы хранятся в базе в формате base64 в поле с типом image
Как мне преобразовать их из него перед выгрузкой в файл?
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
CREATE TABLE Pictures (
   pictureName NVARCHAR(40) PRIMARY KEY NOT NULL
   , picFileName NVARCHAR (100)
   , PictureData VARBINARY (max)
   )
GO

CREATE PROCEDURE dbo.usp_ImportImage (@PicName NVARCHAR (100), @ImageFolderPath NVARCHAR (1000), @Filename NVARCHAR (1000))
AS
BEGIN
   DECLARE @Path2OutFile NVARCHAR (2000), @tsql NVARCHAR (2000);
   SET NOCOUNT ON
   SET @Path2OutFile = @ImageFolderPath + '\' + @Filename
   SET @tsql = 'insert into Pictures (pictureName, picFileName, PictureData) ' +
               ' SELECT ' + '''' + @PicName + '''' + ',' + '''' + @Filename + '''' + ', * ' + 
               'FROM Openrowset( Bulk ' + '''' + @Path2OutFile + '''' + ', Single_Blob) as img'
   EXEC (@tsql)
   SET NOCOUNT OFF
END
GO

CREATE PROCEDURE dbo.usp_ExportImage (@PicName NVARCHAR (100), @ImageFolderPath NVARCHAR(1000), @Filename NVARCHAR(1000))
AS
BEGIN
   DECLARE @ImageData VARBINARY (max);
   DECLARE @Path2OutFile NVARCHAR (2000);
   DECLARE @Obj INT
 
   SET NOCOUNT ON
 
   SELECT @ImageData = (
         SELECT convert (VARBINARY (max), PictureData, 1)
         FROM Pictures
         WHERE pictureName = @PicName
         );
 
   SET @Path2OutFile = @ImageFolderPath + '\' + @Filename
    BEGIN TRY
     EXEC sp_OACreate 'ADODB.Stream' ,@Obj OUTPUT;
     EXEC sp_OASetProperty @Obj ,'Type',1;
     EXEC sp_OAMethod @Obj,'Open';
     EXEC sp_OAMethod @Obj,'Write', NULL, @ImageData;
     EXEC sp_OAMethod @Obj,'SaveToFile', NULL, @Path2OutFile, 2;
     EXEC sp_OAMethod @Obj,'Close';
     EXEC sp_OADestroy @Obj;
    END TRY
    
 BEGIN CATCH
  EXEC sp_OADestroy @Obj;
 END CATCH
 
   SET NOCOUNT OFF
END
GO
...
Рейтинг: 0 / 0
19.07.2021, 16:46
    #40084695
aleks222
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выгрузка файла на диск из БД
Фигней занимаетесь. Напишите клиентское приложение для выгрузки.


ЗЫ. Но если очень хочется...

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
-- =============================================
-- Description:	Преобразование base64 в binary
-- =============================================
/* 
declare @b varchar(max)
set @b = '0JzQvtGA0LUg0KLRgNGN0LLQtdC7LiDQlNCe0JrQo9Cc0JXQndCi0Ksg0JTQm9CvINCa0JvQmNCV0J3QotCQINC/0L4g0YLRg9GA0YMgVFI4MDkyMDAwNA=='
select * from dbo.[base64-to-binary](@b)
*/
ALTER FUNCTION [dbo].[base64-to-binary]( @base64 varchar(max) )
RETURNS TABLE 
AS
RETURN ( select cast(N'' as xml).value('xs:base64Binary(sql:variable("@base64"))', 'varbinary(max)') as [binary] )
...
Рейтинг: 0 / 0
19.07.2021, 16:55
    #40084699
Петр
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выгрузка файла на диск из БД
aleks222
Фигней занимаетесь. Напишите клиентское приложение для выгрузки.


ЗЫ. Но если очень хочется...


не хочется, но выхода не вижу лучшего.

я не могу на вход функции подать varchar(max) - файл больше 8000 байт
...
Рейтинг: 0 / 0
19.07.2021, 16:57
    #40084701
aleks222
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выгрузка файла на диск из БД
Петр
aleks222
Фигней занимаетесь. Напишите клиентское приложение для выгрузки.


ЗЫ. Но если очень хочется...


не хочется, но выхода не вижу лучшего.

я не могу на вход функции подать varchar(max) - файл больше 8000 байт


Ученье - свет. Учись, студент.
...
Рейтинг: 0 / 0
19.07.2021, 17:14
    #40084704
Петр
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выгрузка файла на диск из БД
подставил преобразование, но исходный файл неверного формата экспортируется.
есть какие то соображения?

Код: sql
1.
2.
3.
4.
5.
6.
***
    SELECT @ImageData = (
         SELECT cast(N'' as xml).value('xs:base64Binary(sql:column("PictureData"))', 'varbinary(max)') as [binary]
         FROM Pictures
         WHERE pictureName = @PicName
         );
...
Рейтинг: 0 / 0
19.07.2021, 19:58
    #40084730
Критик
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выгрузка файла на диск из БД
Петр
подставил преобразование, но исходный файл неверного формата экспортируется.
есть какие то соображения?


Проверить начальные-конечные байты файла
...
Рейтинг: 0 / 0
20.07.2021, 00:18
    #40084762
Петр
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выгрузка файла на диск из БД
вообщем походу я заблудился с трех соснах.
для преобразования данных хранящихся в BASE64 - потребуется следующая функция
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
create FUNCTION [dbo].[Base64ToStr]
(
    @BASE64_STRING VARCHAR(MAX)
)
RETURNS VARCHAR(MAX)
AS
BEGIN
    RETURN 
    (
        SELECT UTF8Encoding = convert(VARCHAR(MAX), convert(XML, N'').value('xs:base64Binary(sql:variable("@BASE64_STRING"))', 'VARBINARY(MAX)'))   
    )
END


тогда конечный селект для записи в файл будет выглядеть так:
Код: sql
1.
2.
3.
4.
5.
SELECT @ImageData = (
         SELECT convert (VARBINARY (max), dbo.Base64ToStr(convert(varchar(max), <field>)), 0) 
         FROM <table>
         WHERE <***>
         );



возможно можно упростить преобразования, но я не вижу как
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Выгрузка файла на диск из БД / 12 сообщений из 12, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]