Как создать сценарий INSERT для таблицы с полем VARBINARY (MAX)? - PullRequest
11 голосов
/ 12 апреля 2011

У меня есть таблица с полем VARBINARY(MAX) (SQL Server 2008 с FILESTREAM)

Мое требование заключается в том, чтобы при развертывании в производство я мог предоставить своей ИТ-команде только группу сценариев SQL, которые будут выполняться в определенном порядке. В новой таблице, которую я делаю на производстве, есть это поле VARBINARY(MAX). Обычно с новыми таблицами я пишу скрипт CREATE TABLE. И, если у меня есть данные, которые мне нужны, я запишу сценарии INSERT. Не слишком сложно.

Но с VARBINARY(MAX) хранимая процедура, которую я использовал для генерации операторов INSERT, не удалась для этой таблицы. Я попытался выбрать это поле, распечатать его, скопировать, преобразовать в шестнадцатеричное и т. Д. Основная проблема, с которой я столкнулся, заключается в том, что он не выделяет все данные в поле. Я делаю проверку DATALENGTH([FileColumn]), и если исходная строка содержит 1 004 382 байта, максимум, что я могу получить скопированные или выбранные данные при повторной вставке, составляет 8000. Поэтому в основном это усеченные (то есть недействительные) данные .....

Как я могу сделать это лучше? Я пытался погуглить это как сумасшедший, но я, должно быть, что-то упустил. Помните, я не могу получить доступ к файловой системе. Это должно быть все по сценарию.

Ответы [ 4 ]

5 голосов
/ 12 апреля 2011

Не создавайте сценарии из SSMS

bcp для вывода / ввода данных или используйте что-то вроде Инструменты SSMS для генерации операторов INSERT

5 голосов
/ 12 апреля 2011

Если это делается один раз (или редко), вы можете попробовать создать сценарий для данных из мастера SSMS, как описано здесь:

http://sqlblog.com/blogs/eric_johnson/archive/2010/03/08/script-data-in-sql-server-2008.aspx

Или, есливам нужно делать это часто и хотеть автоматизировать, вы можете попробовать библиотеку SQL # SQLCLR (которую я написал, и хотя большая ее часть бесплатна, нужной вам функции здесь нет).Для этого используется функция DB_DumpData , которая также генерирует операторы INSERT.

Но, опять же, если это одноразовая или нечастая задача, попробуйте встроенный мастер экспорта данных.в студии управления.Это должно позволить вам затем создать сценарий SQL, который вы сможете запустить в Production.Я только что проверил это на таблице с полем VARBINARY(MAX), содержащим 3 365 964 байта данных, и мастер создания сценариев сгенерировал оператор INSERT со всей шестнадцатеричной строкой из 6,73 миллиона символов для этого одного значения.

ОБНОВЛЕНИЕ:
Еще один быстрый и простой способ сделать это способом, который позволил бы вам скопировать / вставить весь оператор INSERT в сценарий SQL и не беспокоиться о мастере экспорта BCP или SSMS, заключается впросто конвертируйте значение в XML.Сначала вы должны CONVERT от VARBINARY до VARCHAR(MAX), используя необязательный стиль «1», который дает шестнадцатеричную строку, начинающуюся с «0x».Если у вас есть шестнадцатеричная строка двоичных данных, вы можете объединить ее в оператор INSERT, и все это при преобразовании в XML может содержать все поле VARBINARY.Смотрите следующий пример:

DECLARE @Binary VARBINARY(MAX) = CONVERT(VARBINARY(MAX),
                                         REPLICATE(
                                           CONVERT(NVARCHAR(MAX), 'test string'),
                                           100000)
                                        )

SELECT 'INSERT INTO dbo.TableName (ColumnName) VALUES ('+
       CONVERT(VARCHAR(MAX), @Binary, 1) + ')' AS [Insert]
FOR XML RAW;
1 голос
/ 12 апреля 2011

Это более чем запутано, но в прошлом и в Интернете я видел, как это делается с использованием строки в кодировке base64.Вы используете значение xml, чтобы обернуть строку, и оттуда вы можете преобразовать ее в varbinary.Вот пример:
http://blogs.msdn.com/b/sqltips/archive/2008/06/30/converting-from-base64-to-varbinary-and-vice-versa.aspx

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

0 голосов
/ 12 апреля 2011

Я никогда не пробовал ничего подобного раньше, но из документации по SQL Server 2008 R2 кажется, что использование SUBSTRING будет работать для получения всего значения varbinary, хотя, возможно, вам придется работать с нимв кусках, используя UPDATE s с предложением .WRITE для добавления данных.

Обновление типов данных большого значения

ИспользованиеПредложение .WRITE (expression, @Offset, @Length) для частичного или полного обновления типов данных varchar (max), nvarchar (max) и varbinary (max).Например, частичное обновление столбца varchar (max) может удалить или изменить только первые 200 символов столбца, тогда как полное обновление приведет к удалению или изменению всех данных в столбце.

Для лучшей производительности, мы рекомендуем вставлять или обновлять данные с размерами блоков, кратными 8040 байтам.

Надеюсь, это поможет.

...