我正在尝试使用 SQL“FOR XML”子句生成的 xml 加载 ac# 数据集。似乎如果我格式化 XML 以便包含架构,则不会加载数据。如果我离开模式,我会得到数据,但不是正确的数据类型。
如何从使用 FOR XML 子句生成的 XML 加载数据集,以便加载类型信息和数据?(FOR XML AUTO|RAW,XMLDATA|XMLSCHEMA 的某种组合???)
更新
将其更改为使用从字符串构建的 XmlReader 而不是从 SqlXml 变量创建的读取器允许将类型信息和数据都带入数据集,只要架构信息包含在 xml 中。当然,我认为这意味着对 xml 进行额外的解析。有更好的解决方案吗?
string xml = cmd.Parameters["@xml"].Value.ToString();
StringReader str = new StringReader(String.Format(@"<root>{0}</root>", xml));
System.Xml.XmlReader xmr = System.Xml.XmlReader.Create(str);
ds.ReadXml(xmr);
SQL:
ALTER PROCEDURE prc_GetXmlData @xml XML OUTPUT
AS
BEGIN
IF OBJECT_ID('test') IS NOT NULL
DROP TABLE test
CREATE TABLE test (field1 INT, field2 BIT, field3 MONEY, field4 VARCHAR(8000))
INSERT INTO test
(field1, field2, field3, field4)
VALUES
(3, 1, 99.45, 'testvalue')
--what combination????
SELECT @xml = (SELECT * FROM test FOR XML RAW, XMLDATA)
END
C#:
static void Main(string[] args)
{
try
{
SqlConnection con = new SqlConnection(<<connectionstring>>);
SqlCommand cmd = new SqlCommand("prc_GetXmlData", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@xml", SqlDbType.Xml).Direction = ParameterDirection.Output;
try
{
con.Open();
cmd.ExecuteNonQuery();
}
finally
{
if (con.State == ConnectionState.Open)
con.Close();
}
System.Data.SqlTypes.SqlXml sqlXml = (System.Data.SqlTypes.SqlXml)cmd.Parameters["@xml"].SqlValue;
DataSet ds = new DataSet();
ds.ReadXml(sqlXml.CreateReader());
for (int t = 0; t < ds.Tables.Count; t++)
{
Console.WriteLine("Column DataTypes:");
for (int c = 0; c < ds.Tables[t].Columns.Count; c++)
{
Console.WriteLine("ds.Tables[{0}].Columns[{1}].DataType={2}", t, c, ds.Tables[t].Columns[c].DataType);
}
Console.WriteLine("Rowcount:{0}", ds.Tables[0].Rows.Count);
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
Console.WriteLine();
Console.WriteLine("Press any key to exit...");
Console.ReadKey(true);
}