Пользовательский агрегат 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" ограничивает степень параллелизма.