Я всегда обнаруживал отсутствие встроенной агрегатной функции, которая просто объединяет значения, используя какой-то определенный пользователем разделитель, расстраивает.
Самая близкая вещь, которую я знаю, это хак XML:
select s.string as [text()]
from strings s
for xml path('')
Но, на мой взгляд, это очень странный способ сделать это, и вам все равно придется разбираться с делом с помощью концевого или ведущего разделителя мусора.Итак, я решил написать агрегат CLR:
select dbo.Fold(s.string, ', ')
from strings s
Это мило.За исключением того, что эта штука не очень хорошо работает, когда число строк достигает 5000. Я действительно не ожидаю, что она будет работать с таким большим количеством данных, но, к моему удивлению, производительность агрегата довольно быстро снижается по мере роста набора данных.Сначала я не понимал, почему, а потом понял, что проблема с обработкой UDF в SQL Server.
Я использую UDF с классом StringBuilder
, поэтомуреализовать IBinarySerialize
.Но по причинам, которые я не понимаю, SQL Server вызывает пару «запись / чтение» между каждой итерацией Accumulate
.Очевидно, это создает проблему производительности, когда строка становится большой.Можно ли как-нибудь избежать этой дорогостоящей сериализации?
К вашему сведению, хак на XML на несколько порядков быстрее.