Part 1: Proper XML Struture
In order to get anything other than a flat XML layout, you need to use either FOR XML EXPLICIT
mode, or nested FOR XML AUTO
queries. Please see the following MSDN sections for complete details, including examples:
Also, you do not need to generate the <SubParentBranchID>
element as it is entirely superfluous. One of the nice things about XML is being able to get the parent node from your current location :).
Part 2: Exporting to a File
This can be done rather easily with a simple SQLCLR function to save the contents of a variable (or query) into a text file.
[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;
}
And there is no need to do any NULL
checking of the input parameters via .IsNull()
since I am using the RETURNS NULL ON NULL INPUT
option:
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];
Then you can use like this:
DECLARE @Output XML;
SET @Output = (
SELECT ...
FOR XML ...;
);
DECLARE @ErrorMessage NVARCHAR(4000);
SET @ErrorMessage = dbo.SaveXmlToFile(N'path/to/file.xml', @Output);
A few easy steps to get the above SQLCLR function working (and pretty much any Assembly you create that needs EXTERNAL_ACCESS
or UNSAFE
):
The assembly needs to be signed. In Visual Studio, go to Project Properties -> SQLCLR tab -> Signing... button.
"CLR Integration" needs to be enabled:
EXEC sp_configure 'clr enabled', 1;
RECONFIGURE;
Create an Asymmetric Key in [master]
from the DLL:
USE [master];
CREATE ASYMMETRIC KEY [KeyName]
FROM EXECUTABLE FILE = 'Path\to\SomeAssemblyName.dll';
Create a Login [master]
from the DLL:
CREATE LOGIN [SomeLoginName]
FROM ASYMMETRIC KEY [KeyName];
Grant the Key-based Login the appropriate permission:
GRANT EXTERNAL ACCESS ASSEMBLY TO [SomeLoginName];
Please notice how none of those steps was to turn the database property of TRUSTWORTHY
to ON
!!!
An alternate means of getting this SQLCLR function without doing any coding, compiling, creating of Asymmetric Keys or Logins, etc, is to get a pre-done library that you just install. The SQL# library contains several File System functions and bypasses all of the steps shown above. Please note that I am the author of SQL#, and while there is a Free version, the File System functions are only available in the Full version.
ELEMENTS
e.g.FOR XML PATH ('Branch'), ROOT('BranchInfo'), ELEMENTS
to see you get the desired output. – Kin Shah Oct 2 '15 at 14:55ELEMENTS
is not the issue here. The issue is producing a multi-level structure as opposed to the default flat structure. And that can only be done by using the two methods I mention in Part 1 of my answer. – Solomon Rutzky Oct 2 '15 at 16:19