在SQL Server2005中有FOR XML 用法,可以讲一个表作为一个字段。
我的设计想法主要是用在1对多的关系中表读取的问题。
表A 表B
在A中有一条记录而在B中有多条记录可以参照下面的写法:(我的项目中用到的,修改了字段主要是演示用)
select A.*,
(SELECT a, CAST(G_Univalence AS NVARCHAR(48)) AS G_Univalence,
--注意留下他的意义只是money字段在for xml中它采用科学计数法显示,在应用中不好处理
FROM B WHERE B.CB_ID = A.BP_ID FOR XML RAW,TYPE,ROOT('GrainConstraint')) AS GrainConstraint
--使用TYPE返回 xml字段类型
FROM A
在后台,使用SqlDataReader读取xml字段,GetSqlXml(),参照下面的代码.
public static bool ToDataTable(SqlXml sxSource, DataTable dt)
{
XmlReader xmlReader = sxSource.CreateReader();
string tempName;
int nColumnIndex;
Type type;
while (xmlReader.Read()) //每次循环1条记录
{
switch (xmlReader.NodeType)
{
case XmlNodeType.Element:
if (xmlReader.LocalName == "row")
{
DataRow dataRow = dt.NewRow();
for (int i = 0; i < xmlReader.AttributeCount; i++)
{
xmlReader.MoveToAttribute(i);
tempName = xmlReader.Name;
nColumnIndex = dt.Columns.IndexOf(tempName);
if (nColumnIndex >= 0)
{
type = dt.Columns[nColumnIndex].DataType;
if(type == typeof(Int32))
{
dataRow[tempName] = Int32.Parse(xmlReader.Value);
}
else if(type == typeof(Int64))
{
dataRow[tempName] = Int64.Parse(xmlReader.Value);
}
else if (type == typeof(float))
{
dataRow[tempName] = float.Parse(xmlReader.Value);
}
else if(type == typeof(decimal))
{
dataRow[tempName] = decimal.Parse(xmlReader.Value);
}
else
{
dataRow[tempName] = xmlReader.Value;
}
}
}
//下面为读取xml字段中的xml字段,将子xml字段转换为DataTable
while(xmlReader.Read())
{
if (xmlReader.NodeType == XmlNodeType.EndElement)
{
if (xmlReader.Name == "row")
{
break;
}
else
{
continue;
}
}
else if (xmlReader.NodeType == XmlNodeType.Element)
{
tempName = xmlReader.Name;
if (xmlReader.ReadToFollowing("NewDataSet"))
{
DataTable dtField = new DataTable(tempName);
XmlReader inner = xmlReader.ReadSubtree();
dtField.ReadXml(inner);
inner.Close();
dataRow[tempName] = dtField;
}
}
}
dt.Rows.Add(dataRow); //这时完成整条记录,添加
}
break;
}
}
xmlReader.Close();
xmlReader = null;
return true;
}