CLR UDF возвращает Varbinary (MAX) - PullRequest
1 голос
/ 08 мая 2009

Может ли пользовательская функция SQL CLR возвращать тип данных varbinary (MAX)?

В документации упоминается:

«Входными параметрами и типом, возвращаемым из функции со скалярным значением, может быть любой из типов скалярных данных, поддерживаемых SQL Server, кроме преобразования строк, текста, ntext, изображения, метки времени, таблицы или курсора.» - они не упоминают varbinary, но я не уверен ...

У меня есть некоторые данные байтового массива со стороны .NET, которые мне нужно вернуть в SQL Server из CLR, и я пытаюсь избежать необходимости делать это с выходным параметром из хранимой процедуры (вот как У меня сейчас работает в тесте).

Спасибо!

Ответы [ 3 ]

6 голосов
/ 22 января 2011

Технически не существует 8000 байт в интерфейсе от SQL Server к коду CLR. В основном это различие в том, как определяется обёртка T-SQL, сохраненная процедура или функция. Это означает, что если Proc или функция T-SQL, которая вызывает код CLR, определяет RETURNS как VARBINARY(MAX), то это должно быть VARBINARY(MAX), независимо от того, указали ли вы SqlBytes или SqlBinary в качестве возвращаемого типа код CLR.

И SqlBytes, и SqlBinary могут обрабатывать ограничение в 2 ГБ, НО разница в том, как код CLR принимает данные. SqlBinary (точно так же, как SqlString) принимает значение параметра одновременно, тогда как SqlBytes (так же, как SqlChars) предоставляет интерфейс потоковой передачи, поэтому он может быть более эффективным для очень больших значений.

Возвращаясь к проблеме, с которой вы сталкивались в предопределенной оболочке SQL-функции, что означает , было вопросом того, как Visual Studio (технически SSDT) ​​автоматически генерирует s д 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, то вы захотите переопределить значение по умолчанию одним из следующих способов:

  1. Вы можете ALTER определить функцию или Proc после того, как она сгенерирована Visual Studio, и в этом случае вы даже можете изменить типы данных (либо входных параметров, либо возвращаемых значений) на любой размер, например VARBINARY(100) или NVARCHAR(50).

  2. Вы можете использовать декоратор SqlFacet для указания Visual Studio / SSDT автоматически генерировать определения Function или Proc с опцией размера, которую вы предпочитаете, а не по умолчанию. В следующем примере показано задание размера для входных параметров и возвращаемого значения (обратите внимание, что -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 карту либо либо NVARCHAR(1 - 4000), либо NVARCHAR(MAX).

2 голосов
/ 08 мая 2009

Если вы определите его как возвращающий тип данных SqlBytes , это должно правильно отобразиться на varbinary(MAX) в SQL Server.

[SqlFunction]
public static SqlBytes Function1()
{
    return new SqlBytes(Encoding.UTF8.GetBytes("Hello world."));
}

Хотя вы также можете использовать тип данных SqlBinary , при развертывании через Visual Studio он будет отображен на varbinary(8000), а не на varbinary(MAX).

0 голосов
/ 08 мая 2009

Похоже, что ответ да - вы можете использовать оба varbinary (MAX), возвращая "SqlBinary", или вы можете использовать SqlBytes, как рекомендовано выше.

...