如何使用SQL Server查询导出XML?

时间:2010-10-17 07:55:57

标签: sql-server-2008

假设我有一张像这样的表Employee

EmpID, EmpName

1    , hatem

我写了一个查询:select * from Employee for xml auto

所以输出将是XML格式。

我想知道如何将结果导出到XML文件以保存在我的计算机驱动器上,因为我需要从此文件夹中读取XML文件并在我的.net应用程序中反序列化它们。

2 个答案:

答案 0 :(得分:15)

如果您只需要存储XML而不需要执行任何其他操作,这可能是实现此目的的最简单方法 - 使用简单的ADO.NET:

string query = "SELECT EmployeeID, LastName, FirstName, Title, BirthDate, HireDate FROM dbo.Employees FOR XML AUTO";

using(SqlConnection _con = new SqlConnection("server=(local);database=Northwind;integrated security=SSPI;"))
using (SqlCommand _cmd = new SqlCommand(query, _con))
{
    _con.Open();
    string result = _cmd.ExecuteScalar().ToString();
    _con.Close();

    File.WriteAllText(@"D:\test.xml", result);
}

这将创建一个文件D:\test.xml(或更改该文件以匹配您的系统),并将这些XML标记放入该文件中。

SqlCommand对象还有一个.ExecuteXmlReader()方法,该方法将返回一个XmlReader对象来扫描和操作XML - 而不仅仅是返回一个字符串。使用对你最有意义的东西!

PS:同样,FOR XML AUTO的输出有点......让我们说......不是最理想的。它使用dbo.Employee作为它的主要XML标签等等......对于SQL Server 2008,我强烈建议您考虑使用FOR XML PATH - 它允许您调整和自定义布局XML输出。

将原始XML输出与FOR XML AUTO

进行比较
<dbo.Employees _x0040_ID="1" LastName="Davolio" FirstName="Nancy" Title="Sales Representative" BirthDate="1948-12-08T00:00:00" HireDate="1992-05-01T00:00:00" />
<dbo.Employees _x0040_ID="2" LastName="Fuller" FirstName="Andrew" Title="Vice President, Sales" BirthDate="1952-02-19T00:00:00" HireDate="1992-08-14T00:00:00" />

针对此查询 - 只是为了看到差异:

SELECT 
    [EmployeeID] AS '@ID',
    [LastName], [FirstName],
    [Title],
    [BirthDate], [HireDate]
FROM 
    [dbo].[Employees]
FOR XML PATH('Employee'), ROOT('Employees')

输出是:

<Employees>
  <Employee ID="1">
    <LastName>Davolio</LastName>
    <FirstName>Nancy</FirstName>
    <Title>Sales Representative</Title>
    <BirthDate>1948-12-08T00:00:00</BirthDate>
    <HireDate>1992-05-01T00:00:00</HireDate>
  </Employee>
  <Employee ID="2">
    <LastName>Fuller</LastName>
    <FirstName>Andrew</FirstName>
    <Title>Vice President, Sales</Title>
    <BirthDate>1952-02-19T00:00:00</BirthDate>
    <HireDate>1992-08-14T00:00:00</HireDate>
  </Employee>

答案 1 :(得分:1)

我遇到了同样的问题,并且我创建了一个将XML导出到文件的.NET CLR:

using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Text;
using System.Xml;
using System.IO;


public sealed class StringWriterWithEncoding : StringWriter
{
    private readonly Encoding encoding;

    public StringWriterWithEncoding(Encoding encoding)
    {
        this.encoding = encoding;
    }

    public override Encoding Encoding
    {
        get { return encoding; }
    }
}

public partial class StoredProcedures
{
    [Microsoft.SqlServer.Server.SqlProcedure]
    public static void XMLExport (SqlXml InputXml, SqlString OutputFile)
    {
        try
        {
            if (!InputXml.IsNull && !OutputFile.IsNull)
            {               

                XmlDocument doc = new XmlDocument();
                doc.LoadXml(InputXml.Value);

                StringWriterWithEncoding sw = new StringWriterWithEncoding(System.Text.Encoding.UTF8);
                XmlWriterSettings settings = new XmlWriterSettings
                {
                    Indent = true,
                    IndentChars = "  ",
                    NewLineChars = "\r\n",
                    NewLineHandling = NewLineHandling.Replace,
                    Encoding = System.Text.Encoding.UTF8
                };

                using (XmlWriter writer = XmlWriter.Create(sw, settings))
                {
                    doc.Save(writer);
                }


                System.IO.File.WriteAllText(OutputFile.ToString(), sw.ToString(), System.Text.Encoding.UTF8);
            }
            else
            {
                throw new Exception("Parameters must be set");
            }
        }
        catch
        {
            throw;
        }
    }
}

以下是如何使用它的示例:

DECLARE @x xml
SET @x = '<Test><Something>1</Something><AnotherOne>2</AnotherOne></Test>'

EXEC dbo.XmlExport @x, 'c:\test.xml'

输出是一个格式良好的XML文件:

<?xml version="1.0" encoding="utf-8"?>
<Test>
  <Something>1</Something>
  <AnotherOne>2</AnotherOne>
</Test>