Определяемый пользователем агрегат в SQL Server 2008 - Как развернуть с MaxByteSize = -1?
-
05-07-2019 - |
Вопрос
Я читал здесь (и в других местах), что в SQL Server 2008 возможно создать определяемый пользователем агрегат, который может возвращать строку длиной более 8000 символов.Это именно то, что мне нужно.
Предположительно, метод заключается в том, чтобы установить maxByteSize равным -1 вместо числа между 1 и 8000;это должно допускать любой размер до 2 ГБ.
По какой-то причине, по-видимому, вы не сможете выполнить развертывание непосредственно из Visual Studio 2008, если используете этот параметр;поэтому вам нужно выполнить развертывание вручную.
Итак:Я создаю свой проект - GroupConcat (который должен имитировать агрегатор group_concat MySQL), который выдает мне в папке bin проекта файл "SqlClassLibrary.dll".В соответствии с инструкциями на странице, связанной выше, я создаю сборку в SQL Server.Команда выполняется успешно.Однако, когда я пытаюсь на самом деле использование агрегатор groupconcat:
select department, dbo.groupconcat(projectNumber) from projectleads group by department
... там написано, что он не может быть найден.Все это отлично работает, если я установлю maxByteSize равным 8000 и разверну непосредственно из VS2008, но мне нужно > 8000.Кто-нибудь знает, что я делаю не так?
Спасибо -дэн
ПРИМЕЧАНИЕ: Мне определенно нужно иметь функцию агрегатора groupconcat, а не использовать некоторые из приемов SQL Server, которые я часто видел.
Решение 2
Разобрался в этом...После создания решения в Vis Studio, предполагая, что я удалил .созданную им DLL в c: emp и вызвал ее GroupConcat.dll:
CREATE ASSEMBLY GroupConcat from 'C:\temp\GroupConcat.dll' with permission_set = safe
GO
CREATE AGGREGATE groupconcat(@input nvarchar(max))
RETURNS nvarchar(max)
EXTERNAL NAME GroupConcat
GO
Вот и все.
Другие советы
В качестве альтернативы вы можете использовать MaxSize
свойство SqlFacetAttribute
чтобы указать размер переменной.Обратите внимание, что в приведенном ниже примере я применил этот атрибут к SqlString
параметры в Accumulate
метод и к возвращаемому значению Terminate
способ.Это приводит к следующей подписи SQL:
AGGREGATE [dbo].[Concatenate] (@value nvarchar(max), @order int, @seperator nvarchar(max)) RETURNS nvarchar(max)
[Serializable]
[SqlUserDefinedAggregate(
Format.UserDefined,
IsInvariantToOrder = true,
IsInvariantToNulls = true,
IsInvariantToDuplicates = false,
IsNullIfEmpty = false,
MaxByteSize = -1)]
public struct Concatenate : IBinarySerialize
{
public void Init();
public void Accumulate([SqlFacet(MaxSize = -1)] SqlString value,
SqlInt32 order,
[SqlFacet(MaxSize = -1)] SqlString seperator);
public void Merge(Concatenate group);
[return: SqlFacet(MaxSize = -1)]
public SqlString Terminate();
public void Read(BinaryReader r);
public void Write(BinaryWriter w);
}
Я не знаю, является ли это более "правильным", чем то, что вы в итоге сделали, но это кажется более естественным.