2009-03-07 6 views
3

Я прочитал here (и в другом месте), что в SQL Server 2008 возможно построить пользовательский агрегат, который может вернуть строку длиной более 8000 символов. Это именно то, что мне нужно.Пользовательский агрегат в SQL Server 2008 - Как развернуть с помощью MaxByteSize = -1?

Предположительно, метод заключается в том, чтобы установить maxByteSize в -1 вместо числа btw 1 и 8000; это должно допускать размеры до 2 ГБ.

По какой-то причине, по-видимому, вы не можете установить прямо из Visual Studio 2008, если вы используете этот параметр; поэтому вам нужно вручную развернуть.

Итак: Я строю свой проект - GroupConcat (который должен имитировать агрегатор MySQL group_concat), который дает мне в папке bin файла файл «SqlClassLibrary.dll». В соответствии с инструкциями на вышеперечисленной странице я создаю сборку в SQL Server. Команда выполняется успешно. Однако, когда я пытаюсь на самом деле использования groupconcat агрегатор:

select department, dbo.groupconcat(projectNumber) from projectleads group by department

... он говорит, что это не может быть найден. Все это работает отлично, если я устанавливаю maxByteSize на 8000 и развертываю непосредственно из VS2008, но мне нужно> 8000. Кто-нибудь знает, что я делаю неправильно?

Благодаря -дан

Примечание: я специально нужно иметь функцию groupconcat агрегатор, а не использовать некоторые трюки SQL Server я часто видел.

ответ

1

Фигурные это ... После построения решения в Vis Studio, при условии, что я уронил .dll, он создает в C: \ Temp и назвал его 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 

Это делает его ,

3

В качестве альтернативы вы можете использовать MaxSize property of SqlFacetAttribute, чтобы указать размер varchar. Обратите внимание, что в приведенном ниже примере я применил этот атрибут к параметрам 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); 
} 

Я не знаю, если это больше «правильный», чем то, что вы в конечном итоге делает, но это кажется более естественным.

+0

Очень полезно знать. +1. Благодаря! – DanM