Пользовательский агрегат SQL Server возвращает ошибку, если агрегирует 0 строк

У меня есть этот пользовательский агрегат SQL Server:

[SqlUserDefinedAggregate(Format.UserDefined, Name="median", IsInvariantToDuplicates=false, IsInvariantToNulls=true, IsInvariantToOrder=true, IsNullIfEmpty=true, MaxByteSize=8000)]
public class MedianCalculator : IBinarySerialize {
    private List<double> values;

    public void Init() {
        values = new List<double>();
    }

    public void Accumulate(SqlDouble value) {
        if (!value.IsNull)
            values.Add(value.Value);
    }

    public void Merge(MedianCalculator other) {
        values.AddRange(other.values);
    }

    public SqlDouble Terminate() {
        if (values == null || values.Count == 0)
            return SqlDouble.Null;
        values.Sort();
        return (values[(int)Math.Floor((values.Count - 1) / 2.0)] + values[(int)Math.Ceiling((values.Count - 1) / 2.0)]) / 2.0;
    }

    public void Read(BinaryReader r) {
        int c = r.ReadInt32();
        values = new List<double>(c);
        for (int i = 0; i < c; i++)
            values.Add(r.ReadDouble());
    }

    public void Write(BinaryWriter w) {
        w.Write(values.Count);
        for (int i = 0; i < values.Count; i++)
             w.Write(values[i]);
    }
}

После развертывания этого агрегата я пытаюсь выполнить этот запрос:

select dbo.median(x) from (select 1 as x where 1 = 0) t

и я получаю эту ошибку:

A severe error occurred on the current command.  The results, if any, should be discarded.

Тем не менее, это работает:

create table #t(x int)
select dbo.median(x) from #t
drop table #t

и возвращает NULL, как и ожидалось.

Это похоже на ошибку в SQL Server, но как я могу обойти это?

select @@version
Microsoft SQL Server 2005 - 9.00.4035.00 (Intel X86)   Nov 24 2008 13:01:59   Copyright (c) 1988-2005 Microsoft Corporation  Developer Edition on Windows NT 6.1 (Build 7100: ) 

2 ответа

Измените свойство IsNullIfEmpty атрибута SqlUserDefinedAggregateAttribute на false и это будет работать.

Это определенно ошибка в SQL Server, надеюсь, кто-то важный заметит это и откроет проблему Connect.

Я не знаю о свойстве IsNullIfEmpty, но что помогло мне с этой ошибкой, так это использование в запросе "OPTION(MAXDOP 1)". По-видимому, существует некоторая проблема параллелизма с агрегатными функциями CLR в SQL Server 2005, и "MAXDOP 1" ограничивает степень параллелизма.

Другие вопросы по тегам