CLR UDF возвращает Varbinary (МАКСИМУМ)
-
20-08-2019 - |
Вопрос
Возможно ли, чтобы пользовательская функция SQL CLR возвращала тип данных varbinary(MAX)?
В документации он упоминает:
"Входные параметры и тип, возвращаемые функцией со скалярным значением, могут быть любым из скалярных типов данных, поддерживаемых SQL Server, за исключением rowversion, text, ntext, image, timestamp, table или cursor." - они не упоминают varbinary, но я не уверен...
У меня есть некоторые данные в байтовом массиве из .СЕТЕВАЯ сторона, которую мне нужно вернуть на SQL Server из среды CLR, и я пытаюсь избежать необходимости делать это с помощью выходного параметра из хранимой процедуры (вот как она сейчас работает в тестировании).
Спасибо!
Решение
Если вы определяете его как возвращающий SQL байты тип данных, это должно корректно сопоставляться с varbinary(MAX)
в SQL Server.
[SqlFunction]
public static SqlBytes Function1()
{
return new SqlBytes(Encoding.UTF8.GetBytes("Hello world."));
}
В то время как вы также можете использовать SqlBinary - файл тип данных, если вы развертываете через Visual Studio, он будет сопоставлен с varbinary(8000)
вместо того , чтобы varbinary(MAX)
.
Другие советы
Технически в интерфейсе от SQL Server к CLR-коду нет максимального значения в 8000 байт.В основном это разница в том, как определяется процесс или функция, хранящаяся в оболочке T-SQL.Это означает, что если процедура или функция T-SQL, вызывающая код CLR, определяет RETURNS
как VARBINARY(MAX)
, тогда это должно быть VARBINARY(MAX)
, независимо от того , указали вы это или нет SqlBytes
или SqlBinary
в качестве возвращаемого типа кода CLR.
И то, и другое SqlBytes
и SqlBinary
может обрабатывать ограничение в 2 ГБ, НО разница заключается в том, как код CLR принимает данные. SqlBinary
(точно так же, как SqlString
) принимает значение параметра сразу , в то время как SqlBytes
(точно так же, как SqlChars
) предоставляет потоковый интерфейс, поэтому он может быть более эффективным для очень больших значений.
Возвращаясь к проблеме, которую вы видите с предопределенной оболочкой функции SQL, которая является был вопрос о том, как Visual Studio (технически SSDT) автоматически генерируетsd t-SQL.Значение по умолчанию для SqlBinary
является был VARBINARY(8000)
в то время как значение по умолчанию для SqlBytes
является был VARBINARY(MAX)
.Таким же образом, значение по умолчанию для SqlString
является был NVARCHAR(4000)
в то время как значение по умолчанию для SqlChars
является был NVARCHAR(MAX)
.Те были значения по умолчанию, когда был задан этот вопрос.Начиная, возможно, с Visual Studio 2012, значение по умолчанию было изменено на использовать MAX
для всех 4 из этих типов данных.Это не обязательно хорошо, поскольку использование MAX
типы против не-MAX
типы.Итак, если вам не нужно более 8000 байт VARBINARY
или 4000 байт NVARCHAR
, затем вы захотите переопределить значение по умолчанию , используя один из следующих методов:
Ты можешь
ALTER
определение функции или процесса после того, как оно сгенерировано Visual Studio, и в этом случае вы даже можете изменить типы данных (либо входных параметров, либо возвращаемых значений) на любой размер, напримерVARBINARY(100)
илиNVARCHAR(50)
.Вы можете использовать
SqlFacet
декоратор, чтобы указать Visual Studio / SSDT автоматически генерировать определения функции или процесса с параметром размера, который вы предпочитаете, в отличие от параметра по умолчанию.В следующем примере показано указание размера как для входных параметров, так и для возвращаемого значения (обратите внимание, что-1
=MAX
):[return: SqlFacet(MaxSize = -1)] [Microsoft.SqlServer.Server.SqlFunction(Name = "FunctionName")] public static SqlBinary FuncName([SqlFacet(MaxSize = 50)] SqlString InputParam)
Используя любой из этих двух методов, вы можете сделать либо SqlBinary
или SqlBytes
сопоставьте с любым VARBINARY(1 - 8000)
или VARBINARY(MAX)
.Аналогично, вы можете сделать либо SqlString
или SqlChars
сопоставьте с eithert NVARCHAR(1 - 4000)
или NVARCHAR(MAX)
.
Похоже, что ответ положительный - вы можете использовать оба varbinary (MAX), вернув "SqlBinary", или вы можете использовать SqlBytes, как рекомендовано выше.