To bardzo dobre podejście i zostało całkiem dobrze przyjęte. Istnieje kilka podejść i ten post na blogu opisuje dużo z nich.
Jednym z interesujących rozwiązań, które istnieje, jest użycie środowiska CLR do wykonania pracy za Ciebie, co znacznie zmniejszy złożoność zapytania dzięki kompromisowi polegającemu na uruchamianiu kodu zewnętrznego. Oto próbka tego, jak klasa może wyglądać w zespole.
using System;
using System.Collections.Generic;
using System.Data.SqlTypes;
using System.IO;
using Microsoft.SqlServer.Server;
[Serializable]
[SqlUserDefinedAggregate(Format.UserDefined, MaxByteSize=8000)]
public struct strconcat : IBinarySerialize{
private List values;
public void Init() {
this.values = new List();
}
public void Accumulate(SqlString value) {
this.values.Add(value.Value);
}
public void Merge(strconcat value) {
this.values.AddRange(value.values.ToArray());
}
public SqlString Terminate() {
return new SqlString(string.Join(", ", this.values.ToArray()));
}
public void Read(BinaryReader r) {
int itemCount = r.ReadInt32();
this.values = new List(itemCount);
for (int i = 0; i <= itemCount - 1; i++) {
this.values.Add(r.ReadString());
}
}
public void Write(BinaryWriter w) {
w.Write(this.values.Count);
foreach (string s in this.values) {
w.Write(s);
}
}
}
A to sprawiłoby, że zapytanie byłoby trochę bardziej podobne do tego.
SELECT CategoryId,
dbo.strconcat(ProductName)
FROM Products
GROUP BY CategoryId ;
Co jest oczywiście nieco prostsze. Weź to za to, co jest warte :)
Dzień dobry!