做到一半时遇到一个问题,动态生成case when 拼装成的sql查询出的结果,按instanceID合并成一行的问题,将下图一的结果合并成图二的结果,
各列值的类型是不确定的(表中各列是用户通过系统自定义添加进去),要是数据型好办,用Sum函数。
图一
图二
想自定义一个类sum功能的对串进行拼接处理的聚合方法,在网上找了资料,发现可以用C#等语言开发自定义的聚合函数,因为.net是编译中 IL代码,理论上,只要是代码符合CTS,不同语言的代码是能互相调用。
在vs2008用C#开发聚合函数过程:
首先用VS2008/VS2005建立一个SQL Server项目,如图6所示。
点击“确定”按钮后,SQL Server项目会要求连接一个数据库,我们可以选择一个数据库,如图7所示。
然后在工程中加入一个聚合类(joinstr.cs),如图8所示(可以开发Trigger 等)。
joinstr.cs中的最终代码如下:
using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Text;
[Serializable]
[SqlUserDefinedAggregate(
Format.UserDefined, //use custom serialization to serialize the intermediate result
IsInvariantToNulls = true, //optimizer property
IsInvariantToDuplicates = false, //optimizer property
IsInvariantToOrder = false, //optimizer property
MaxByteSize = 8000) //maximum size in bytes of persisted value
]
public struct JionStr:IBinarySerialize
{
private StringBuilder sbIntermediate;
public void Init()
{
sbIntermediate = new StringBuilder();
}
public void Accumulate(SqlString Value)
{
if (Value == null || Value.ToString().ToLower().Equals("null"))
{
return;
}
else
{
sbIntermediate.Append(Value);
}
}
public void Merge(JionStr Group)
{
sbIntermediate.Append(Group.sbIntermediate);
}
public SqlString Terminate()
{
return new SqlString(sbIntermediate.ToString());
}
// This is a place-holder member field
private int var1;
#region IBinarySerialize Members
public void Read(System.IO.BinaryReader r)
{
sbIntermediate = new StringBuilder(r.ReadString());
}
public void Write(System.IO.BinaryWriter w)
{
w.Write(this.sbIntermediate.ToString());
}
#endregion
}