将结果导出到 XML

its*_*tab 6 xml sql-server t-sql

我正在尝试从 SQL 查询创建 XML 文件。输出应如下图所示

在此处输入图片说明

标签BranchID再次出现的地方,SubParentBranchID好像有多个SubBranchIDBranchID. 在下图中,BranchID94 有两个SubBranchID63 和 64。

我管理了这个 SQL 查询

SELECT
a.[heading_id] as BranchID,
c.[name] as BranchName,
a.[business_id] as SubBranchID, 
a.[heading_id] as SubParentBranchID,
b.[name] as SubBranchName
   FROM [BUSINESSHEADINGLINK] as a
   join [BUSINESS] as b on a.business_id = b.business_id
   join [HEADING] as c on   a.heading_id = c.heading_id 
FOR XML PATH ('Branch'), ROOT('BranchInfo')
Run Code Online (Sandbox Code Playgroud)

这给了我以下 XML

在此处输入图片说明

在这里你可以看到我既没有标签<SubBranches>也没有<SubBranch>. 我也没有<SubParentBranchID>。XML 文件应如下所示:

在此处输入图片说明

任何人都可以帮助我使用 SQL 代码吗?

我也想C:/temp在执行后保存它。

Sol*_*zky 9

第 1 部分:正确的 XML 结构

为了获得除平面 XML 布局之外的任何内容,您需要使用FOR XML EXPLICIT模式或嵌套FOR XML AUTO查询。有关完整的详细信息,包括示例,请参阅以下 MSDN 部分:

此外,您不需要生成<SubParentBranchID>元素,因为它完全是多余的。XML 的优点之一是能够从您当前的位置获取父节点:)。

第 2 部分:导出到文件

这可以通过简单的 SQLCLR 函数轻松完成,将变量(或查询)的内容保存到文本文件中。

[Microsoft.SqlServer.Server.SqlFunction(IsDeterministic = false, IsPrecise = true)]
public static SqlString SaveXmlToFile([SqlFacet(MaxSize = 4000)] SqlString FilePath,
    SqlXml XmlData)
{
    try
    {
        File.WriteAllText(FilePath.Value, XmlData.Value, Encoding.Unicode);
    }
    catch (Exception __Exception)
    {
        return __Exception.Message;
    }

    return String.Empty;
}
Run Code Online (Sandbox Code Playgroud)

由于我正在使用该选项NULL,因此无需对输入参数进行任何检查:.IsNull()RETURNS NULL ON NULL INPUT

[Microsoft.SqlServer.Server.SqlFunction(IsDeterministic = false, IsPrecise = true)]
public static SqlString SaveXmlToFile([SqlFacet(MaxSize = 4000)] SqlString FilePath,
    SqlXml XmlData)
{
    try
    {
        File.WriteAllText(FilePath.Value, XmlData.Value, Encoding.Unicode);
    }
    catch (Exception __Exception)
    {
        return __Exception.Message;
    }

    return String.Empty;
}
Run Code Online (Sandbox Code Playgroud)

然后你可以像这样使用:

CREATE FUNCTION [dbo].[SaveXmlToFile](@FilePath NVARCHAR(4000), @XmlData XML)
RETURNS NVARCHAR(4000)
WITH EXECUTE AS CALLER,
     RETURNS NULL ON NULL INPUT
AS EXTERNAL NAME [SomeAssemblyName].[FileUtils].[SaveXmlToFile];
Run Code Online (Sandbox Code Playgroud)

几个简单的步骤,以获得上述SQLCLR功能工作(和几乎任何你大会创造需求EXTERNAL_ACCESSUNSAFE):

  1. 大会需要签字。在 Visual Studio 中,转到项目属性 -> SQLCLR 选项卡 -> 签名...按钮。

  2. 需要启用“CLR 集成”:

    DECLARE @Output XML;
    
    SET @Output = (
       SELECT ...
       FOR XML ...;
    );
    
    DECLARE @ErrorMessage NVARCHAR(4000);
    SET @ErrorMessage = dbo.SaveXmlToFile(N'path/to/file.xml', @Output);
    
    Run Code Online (Sandbox Code Playgroud)
  3. 创建非对称密钥[master]从DLL:

    EXEC sp_configure 'clr enabled', 1;
    RECONFIGURE;
    
    Run Code Online (Sandbox Code Playgroud)
  4. [master]从 DLL创建登录:

    USE [master];
    CREATE ASYMMETRIC KEY [KeyName]
    FROM EXECUTABLE FILE = 'Path\to\SomeAssemblyName.dll';
    
    Run Code Online (Sandbox Code Playgroud)
  5. 授予基于密钥的登录适当的权限:

    CREATE LOGIN [SomeLoginName]
    FROM ASYMMETRIC KEY [KeyName];
    
    Run Code Online (Sandbox Code Playgroud)

请注意这些步骤中没有一个是将 的数据库属性TRUSTWORTHY变为ON!!!


在不进行任何编码、编译、创建非对称密钥或登录等的情况下获取此 SQLCLR 函数的另一种方法是获取您刚刚安装的预完成库。在SQL#库包含了几个文件系统的功能和绕过上述所有的步骤。请注意,我是 SQL# 的作者,虽然有免费版本,但文件系统功能仅在完整版本中可用。

  • 究竟是什么太复杂了?这里有两个部分。如果您想在 T-SQL 中以本机方式生成多级 XML,那么您对第 1 部分没有太多选择。对于第 2 部分,只需安装一个预先完成的 SQLCLR 函数,就可以_轻松_许多_。而且我确实出售了一个包,其中包含一个名为 [SQL#](http://SQLsharp.com/) 的函数(以及 250 多个其他函数)。有免费版,但文件系统功能只有完整版。 (5认同)