【问题标题】:SQL for xml auto elements wrap nodeSQL for xml 自动元素包装节点
【发布时间】:2015-11-11 09:11:37
【问题描述】:

我有以下代码:

SELECT distinct 
msi.SupplierNumber
    ,Province.[Name] [ProvinceName]
    ,District.[Code] [DistrictCode]
    ,District.[Name] [DistrictName]
    ,Municipality.[Code] [MunicipalityCode]
    ,Municipality.[Name] [MunicipalityName]
    ,City.[Code] [CityCode]
    ,City.[Name] [CityName]
    ,Suburb.[Code] [SuburbCode]
    ,Suburb.[Name] [SuburbName]
    ,Ward.[Code] [WardCode]
FROM
    dbo.MasterSupplierIdentification msi WITH (NOLOCK)
    INNER JOIN dbo.[LinkMasterSupplierCommodity] lmsc WITH (NOLOCK) ON lmsc.MasterSupplierIdentificationID = msi.MasterSupplierIdentificationID
    INNER JOIN dbo.[MasterCommodityGroup] mcg WITH (NOLOCK) ON mcg.[MasterCommodityGroupID] = lmsc.MasterCommodityID
    INNER JOIN dbo.[MasterCommodityLocation] mcl WITH (NOLOCK) ON mcl.[MasterCommodityID] = mcg.[MasterCommodityID]
    INNER JOIN dbo.[MDWard] Ward WITH (NOLOCK) ON Ward.[WardID] = mcl.[WardID]
    INNER JOIN dbo.[MDSuburb] Suburb WITH (NOLOCK) ON Suburb.[SuburbID] = Ward.[SuburbID]
    INNER JOIN dbo.[MDCity] City WITH (NOLOCK) ON City.[CityID] = Suburb.[CityID]
    INNER JOIN dbo.[MDMunicipality] Municipality WITH (NOLOCK) ON Municipality.[MunicipalityID] = City.[MunicipalityID]
    INNER JOIN dbo.[MDDistrict] District WITH (NOLOCK) ON District.[DistrictID] = Municipality.[DistrictID]
    INNER JOIN dbo.[MDProvince] Province WITH (NOLOCK) ON Province.[ProvinceID] = District.[ProvinceID]
WHERE 
    msi.SupplierNumber = 'MAAA0000002'
    and Suburb.Code = '181001001'
for xml auto, Root('Suppliers'), elements xsinil

返回:

<Suppliers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <msi>
        <SupplierNumber>MAAA0000002</SupplierNumber>
        <Province>
        <ProvinceName>Western Cape</ProvinceName>
            <District>
            <DistrictCode>105</DistrictCode>
            <DistrictName>Central Karoo</DistrictName>
                <Municipality>
                <MunicipalityCode>181</MunicipalityCode>
                <MunicipalityName>Laingsburg</MunicipalityName>
                    <City>
                    <CityCode>181001</CityCode>
                    <CityName>Laingsburg NU</CityName>
                        <Suburb>
                        <SuburbCode>181001001</SuburbCode>
                        <SuburbName>Laingsburg NU</SuburbName>
                            <Ward>
                                <WardCode>1</WardCode>
                            </Ward>
                            <Ward>
                                <WardCode>12</WardCode>
                            </Ward>
                            <Ward>
                                <WardCode>2</WardCode>
                            </Ward>
                       </Suburb>
                   </City>
               </Municipality>
           </District>
       </Province>
  </msi>

在此特定示例中,Wards 重复。我想把它包裹在一个父节点中。似乎唯一的方法是使用子查询,我在子查询中指定的不是AUTO而是PATH和ROOT,并将其作为TYPE返回。

【问题讨论】:

    标签: sql sql-server xml tsql for-xml


    【解决方案1】:

    你的最后一句话是正确的。如果您想查看嵌套在父节点中的数据(1:many 关系),则必须将它们包含为一个块。

    一个提示:你在任何地方都使用WITH (NOLOCK)。除非您真的知道自己在做什么,除非您有充分的理由这样做,否则这是一件危险的事情。很常见,但不是很好的做法...

    像这样尝试(未经测试):

    SELECT distinct 
    msi.SupplierNumber
        ,Province.[Name] [ProvinceName]
        ,District.[Code] [DistrictCode]
        ,District.[Name] [DistrictName]
        ,Municipality.[Code] [MunicipalityCode]
        ,Municipality.[Name] [MunicipalityName]
        ,City.[Code] [CityCode]
        ,City.[Name] [CityName]
        ,Suburb.[Code] [SuburbCode]
        ,Suburb.[Name] [SuburbName]
    
        ,WardXml.XmlAsBlock
    FROM
        dbo.MasterSupplierIdentification msi WITH (NOLOCK)
        INNER JOIN dbo.[LinkMasterSupplierCommodity] lmsc WITH (NOLOCK) ON lmsc.MasterSupplierIdentificationID = msi.MasterSupplierIdentificationID
        INNER JOIN dbo.[MasterCommodityGroup] mcg WITH (NOLOCK) ON mcg.[MasterCommodityGroupID] = lmsc.MasterCommodityID
        INNER JOIN dbo.[MasterCommodityLocation] mcl WITH (NOLOCK) ON mcl.[MasterCommodityID] = mcg.[MasterCommodityID]
        INNER JOIN dbo.[MDWard] Ward WITH (NOLOCK) ON Ward.[WardID] = mcl.[WardID]
        INNER JOIN dbo.[MDSuburb] Suburb WITH (NOLOCK) ON Suburb.[SuburbID] = Ward.[SuburbID]
        INNER JOIN dbo.[MDCity] City WITH (NOLOCK) ON City.[CityID] = Suburb.[CityID]
        INNER JOIN dbo.[MDMunicipality] Municipality WITH (NOLOCK) ON Municipality.[MunicipalityID] = City.[MunicipalityID]
        INNER JOIN dbo.[MDDistrict] District WITH (NOLOCK) ON District.[DistrictID] = Municipality.[DistrictID]
        INNER JOIN dbo.[MDProvince] Province WITH (NOLOCK) ON Province.[ProvinceID] = District.[ProvinceID]
    
        CROSS APPLY
        (
          SELECT WardCode FROM dbo.[MDWard] Ward WITH (NOLOCK) 
          WHERE Ward.[WardID] = mcl.[WardID]
          FOR XML PATH('Ward'),TYPE
        ) AS WardXml(XmlAsBlock)
    WHERE 
        msi.SupplierNumber = 'MAAA0000002'
        and Suburb.Code = '181001001'
    for xml auto, Root('Suppliers'), elements xsinil
    

    【讨论】:

    • 谢谢。 NOLOCK 是明确的决定,我知道后果。查询失败,我不是 SQL 大师,所以即使我了解原理,我也无法让查询工作。我得到:“.Net SqlClient 数据提供者:消息 4104,级别 16,状态 1,第 19 行无法绑定多部分标识符“Ward.SuburbID”。.Net SqlClient 数据提供者:消息 421,级别 16,状态1,第1行xml数据类型不能选择为DISTINCT,因为它不可比较。”----该类型导致我理解的DISTINCT问题,但我不理解的块,符号和郊区。
    • @japieson,是的,我没有看到Ward-SuburbID。试试我编辑的版本。一个可能的问题是,您的 Ward-join 下方的连接可能提供多于一行。在这种情况下,所有数据都应该嵌套......这取决于你。如果您无法解决此问题,请尝试不使用 DISTINCT 并返回。我希望这可以解决您的问题,您将投票并通过投票柜台下方的支票接受它,Thx
    • Distinct 由于将 xml 作为类型返回而引发异常。如果我删除不同的或类型以摆脱该问题,则病房仍然没有被包裹。 WardXml 节点对每个病房重复,所以我仍然没有父包装病房。我正在显示部分结果: Laingsburg NU10206012001815
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-08
    • 2016-01-25
    相关资源
    最近更新 更多