当创建一个定制的聚合函数需要指定的enumeration format:什么是IBinarySerialize接口方法用于?
格式枚举由SqlUserDefinedTypeAttribute和 SqlUserDefinedAggregateAttribute以指示用户定义类型(UDT)或聚集体的序列化格式 。
,并在使用UserDefined
格式,你的类必须实现IBinarySerialize Interface并覆盖其read
和write
方法。
我的问题是这些方法究竟需要做什么?
看着examples,我猜他们应该可以读写聚合结果吗?
例如,我想创建一个连接不同数字的SQL CLR函数。在T-SQL中,我可以有1到255个不同的数字(TINYINT值)。我需要从他们(使用分隔符)创建一个字符串,但也排序数字。该功能似乎工作,但我不是很确定我有重载的方法如预期:
[Serializable]
[
Microsoft.SqlServer.Server.SqlUserDefinedAggregate
(
Microsoft.SqlServer.Server.Format.UserDefined,
IsInvariantToNulls = true,
IsInvariantToDuplicates = true,
IsInvariantToOrder = false,
MaxByteSize = 1024
)
]
public class ConcatenateAnswersPos : Microsoft.SqlServer.Server.IBinarySerialize
{
private List<byte> intermediateResult;
public void Init()
{
intermediateResult = new List<byte>();
}
public void Accumulate(SqlByte value)
{
intermediateResult.Add((byte)value);
}
public void Merge(ConcatenateAnswersPos other)
{
intermediateResult.AddRange(other.intermediateResult);
}
public SqlString Terminate()
{
if (intermediateResult != null)
{
intermediateResult.Sort();
return new SqlString(string.Join(";", intermediateResult));
}
else
{
return new SqlString("");
}
}
public void Read(BinaryReader r)
{
if (r == null) throw new ArgumentNullException("r");
intermediateResult = new List<byte>();
string[] answers = r.ReadString().Split(';');
foreach (string answer in answers)
{
intermediateResult.Add(Convert.ToByte(answer));
}
}
public void Write(BinaryWriter w)
{
if (w == null) throw new ArgumentNullException("w");
intermediateResult.Sort();
w.Write(string.Join(";", intermediateResult));
}
}
你用'Write' *写的全部内容必须能够被'Read'读取(不会再少一些,因为一般读者会坐在不属于你的基础流上),而是*什么*正是你放入这个界面的客户端(通常SQL Server代码)是非常不透明的。 –
我会从'Write'方法中拿出'Sort'。在这些数据对调用者来说实际上是可见的之前,它将通过调用Read来重新处理,然后(可能在一些'Merge's之后)会调用Terminate来获得实际结果。 –