如何使内部连接 ​​SELECT 的 FOR XML AUTO 输出将两个表输出到各自的元素?

How to make a FOR XML AUTO output of an Inner Joined SELECT output both tables to their own respective Elements?

我正在尝试创建一个存储过程,它使用 BIT 变量打印出内部连接 ​​Select 语句的 2 个可能的 FOR XML 结果之一。这是该过程的当前形式:

CREATE PROCEDURE dbo.CustomerAddress_Get
@IsAuto BIT = 0
AS
BEGIN
--@IsAuto If's
IF (@IsAuto == 0)
    BEGIN

    SELECT LEFT(GivenName,1), Surname, DOB, AccountId, Type, Balance FROM Custs
    INNER JOIN dbo.Accounts 
    ON Accounts.CustNo = Custs.CustNo
    FOR XML RAW ('CustomerAccount'), ELEMENTS, ROOT('CustomerAccountDetails')

    END
ELSE
    BEGIN

    SELECT LEFT(GivenName,1), Surname, DOB, AccountId, Type, Balance FROM Custs Customer
    INNER JOIN dbo.Accounts Account
    ON Account.CustNo = Customer.CustNo
    FOR XML AUTO, ELEMENTS, ROOT

    END
END;

我特别尝试更改的代码是这样的:

SELECT LEFT(GivenName,1), Surname, DOB, AccountId, Type, Balance FROM Custs
INNER JOIN dbo.Accounts 
ON Accounts.CustNo = Custs.CustNo
FOR XML AUTO, ELEMENTS, ROOT

Else SELECT...FOR AUTO 的当前 XML 输出示例;因此声明是:

<Customer>D<Surname>Grayson</Surname><DOB>1940-04-01T00:00:00</DOB><Account><AccountId>159</AccountId><Type>Chequing</Type><Balance>0.0000</Balance></Account><Account><AccountId>160</AccountId><Type>Savings </Type><Balance>500.0000</Balance></Account></Customer>

但是,我要求它更像这样:

<cu>
<FirstName>Catherine</FirstName>
<LastName>Abel</LastName>
<EmailAddress>catherine0@adventure-works.com</EmailAddress>
<ca>
<AddressType>Main Office</AddressType>
<ad>
  <City>Van Nuys</City>
  <StateProvince>California</StateProvince>
</ad>

我认为 FOR XML AUTO 的用途是什么,但它似乎并没有真正格式化结果 XML.

现在,与此相关的问题是,我如何才能将此 SELECT 放入客户(GivenName、Surname 和 DOB/DateOfBirth)和帐户(AccountId、Type 和 Balance)在 XML AUTO 输出中各自的元素中各自的详细信息?

这是根据您的标题使用动态创建的语句对问题的回答:

CREATE PROCEDURE dbo.CustomerAddress_Get
@IsAuto BIT = 0
AS
BEGIN
--@IsAuto If's
DECLARE @cmd NVARCHAR(MAX)=
(
    N'SELECT LEFT(GivenName,1), Surname, DOB, AccountId, Type, Balance FROM Custs
    INNER JOIN dbo.Accounts 
    ON Accounts.CustNo = Custs.CustNo
    FOR XML '
);

IF @IsAuto = 0
    SET @cmd=@cmd+N'RAW (''CustomerAccount''), ELEMENTS, ROOT(''CustomerAccountDetails'')';
ELSE
    SET @cmd=@cmd+N'AUTO, ELEMENTS, ROOT';

EXEC (@cmd);
END;

更新:你的第二个问题

如果您使用 FOR XML PATH,您可以控制 XML

的最终格式

在不了解您的表格的情况下,很难提出正确的解决方案(给定的数据和示例不匹配!),但应该是这样的:

SELECT LEFT(cu.GivenName,1) AS [cu/FirstLetter]
      ,cu.GivenName AS [cu/FirstName]
      ,cu.Surname AS [cu/LastName]
      ,cu.DOB AS [cu/Birthdate]
      ,cu.City AS [ad/City]
      ,cu.StateProvinve AS [ad/StateProvince]
      ,ac.AccountId AS [ac/AccountId]
      ,ac.Type AS [ac/Type]
      ,Balance AS [ac/Balance] 
FROM Custs AS cu
INNER JOIN dbo.Accounts AS ac
ON ac.CustNo = cu.CustNo
FOR XML PATH('Customer'),ROOT('root')

在这种情况下,我建议不要使用上面给出的动态创建 SQL 的方法,而是坚持使用现有的 IF ... ELSE ...

更新 2:Sub-select 而不是加入

您可以试试这样的方法。该代码将创建嵌入式 XML 作为 sub-select:

SELECT Custs.*
     ,(
        SELECT Accounts.* 
        FROM dbo.Accounts 
        WHERE Accounts.CustNo = Custs.CustNo
        FOR XML AUTO, ELEMENTS,TYPE
      ) AS [ad]
FROM Custs AS [cu]
FOR XML AUTO, ELEMENTS, ROOT