Как скачать файл из столбца varbinary с помощью T-SQL - PullRequest
1 голос
/ 03 апреля 2019

Я работаю с SQL Server 2016. У меня есть таблица file_data с столбцом data типа varbinary.

CREATE TABLE [dbo].[file_data]
(
    [file_data_id] [INT] IDENTITY(1,1) NOT NULL,
    [file_name] [VARCHAR](20) NOT NULL,
    [description] [VARCHAR](255) NOT NULL,
    [data] [VARBINARY](MAX) FILESTREAM  NOT NULL,
    [file_guid] [UNIQUEIDENTIFIER] ROWGUIDCOL  NOT NULL,

    CONSTRAINT [pk_file_data] 
        PRIMARY KEY CLUSTERED ([file_data_id] ASC)
                    WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
                          IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, 
                          ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] FILESTREAM_ON [filestream],
    UNIQUE NONCLUSTERED ([file_guid] ASC)
                    WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
                          IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, 
                          ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] FILESTREAM_ON [filestream]
GO

В этом столбце data хранится 1 файл, обычно текстовый файл. Таким образом, эта таблица имеет несколько строк.

Как я могу загрузить файл любой 1 строки из столбца data , используя T-SQL? Я использую Microsoft SQL Server Management Studio.

1 Ответ

1 голос
/ 03 апреля 2019

РЕДАКТИРОВАТЬ: Я просто перечитал ваш вопрос, и я думаю, что я неправильно понял проблему ...

Строка Таким образом, эта таблица состоит из нескольких строк меня зацепили ...

Если вы не хотите больше ничего, чтобы передать двоичное содержимое столбца таблицы в файловую систему, вы можете использовать BCP (см. Связанный ответ и имейте в виду, что это не будет действовать под вашей учетной записью, поэтому права доступа и целевые каталоги могут не соответствовать вашим ожиданиям). Но я бы использовал какой-нибудь внешний инструмент, возможно, powershell, подключился к базе данных и просто прочитал содержимое в файл.

Я не буду удалять свой прежний ответ, так как он тоже может помочь.

Я почти уверен, что T-SQL - неподходящий инструмент для этого. Мой ответ может вам помочь, он хотя бы покажет некоторые принципы ...

A BLOB-столбец (в вашем случае VARBINARY(MAX)) - не более чем бессмысленная цепочка байтов. SQL-сервер не знает, как интерпретировать это как значимые данные.

Я использую простую строковую переменную для макета содержимого файла:

DECLARE @TestText VARCHAR(MAX)=
N'This is the first line
This is the second line';

- Теперь эта строка приводится к varbinary и присваивается BLOB-переменной.
- Это - в принципе - то, что у вас есть в вашей колонке

DECLARE @YourFileStore VARBINARY(MAX)=CAST(@TestText AS VARBINARY(MAX));
SELECT @YourFileStore;

- Это вы вернетесь

0x5468697320697320746865206669727374206C696E650D0A5468697320697320746865207365636F6E64206C696E65

- это HEX-строка, где каждые две цифры представляют символ (54 - это T, 68 - h и т. Д.
Где-то посередине вы найдете последовательность 0D0A, которая является переводом строки.
- Пока мы знаем , как интерпретировать двоичный файл, мы можем просто повторно преобразовать его в прежний тип. Это вернет прежнюю строку:

SELECT CAST(@YourFileStore AS VARCHAR(MAX));

- Чтение этой строки строка за строкой потребует разбиения строки на разрывы строки.
- Вы не указали версию своего SQL-сервера. Здесь я использую OPENJSON (нужен v2016 +).

SELECT *
FROM OPENJSON('["' + REPLACE(CAST(@YourFileStore AS VARCHAR(MAX)),CHAR(13)+CHAR(10),'","') + '"]');

Когда это будет работать для вас:

Это может работать для вас, если все BLOB-объекты имеют одинаковое содержимое (по структуре), а SQL-Server может использовать простой CAST или CONVERT для получения значимого типа данных.

Когда это не сработает для вас:

Если текстовые файлы не простые UCS-2 (почти такие же, как UTF-16), что означает NVARCHAR(MAX) или обычный ASCII , что означает VARCHAR(MAX).

Любая кодировка (например, utf-8), неправильный endian или ASCII> 127 (ищите сопоставления ) может вернуть только мусор.

Что вы должны сделать:

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

Вы должны всегда хранить данные в соответствующем типе . BLOB предназначены для данных, где вы не хотите заглядывать внутрь (как на картинке). Ваши данные должны храниться в отдельных строках с общим идентификатором и номером строки для воссоздания полного текста.

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