从符合条件的XML节点中选择值

时间:2017-05-18 09:36:52

标签: sql-server xml tsql xpath xquery

我有以下要查询的xml变成平面表结构。

<RiskBoundReportProcess>
    <RiskBoundReport>
        <Policy key="Pol126446">
            <LineOfBusinessCode>ISR</LineOfBusinessCode>
            <AssignedIdentifier>
                <RoleCode>Insured</RoleCode>
                <Id>BP-1438</Id>
            </AssignedIdentifier>
            <RiskParticipationPercentIndicator>true</RiskParticipationPercentIndicator>
            <PolicySection>
                <PolicyProducer>
                    <RoleCode>Coverholder</RoleCode>
                    <Producer>
                        <OrganizationReferences organizationReference="Coverholder"/>
                    </Producer>
                </PolicyProducer>
                <PolicyProducer>
                    <RoleCode>Underwriter</RoleCode>
                    <Producer>
                        <Contact>
                            <PersonReferences>
                                <PersonName>
                                    <FullName>Name</FullName>
                                </PersonName>
                            </PersonReferences>
                        </Contact>
                    </Producer>
                </PolicyProducer>
                <PolicyProducer>
                    <RoleCode>Broker</RoleCode>
                    <AssignedIdentifier>
                        <RoleCode>Broker</RoleCode>
                        <Id>112</Id>
                    </AssignedIdentifier>
                    <Producer>
                        <OrganizationReferences organizationReference="BrokerOrg112"/>
                    </Producer>
                </PolicyProducer>
                <PolicyProducer>
                    <RoleCode>LondonBroker</RoleCode>
                    <ProducerReferences producerReference="Binder1">
                        <ExternalIdentifier>
                            <TypeCode>UniqueMarketReference</TypeCode>
                            <Id>UMRGoesHere</Id>
                        </ExternalIdentifier>
                        <OrganizationReferences>
                            <OrganizationName>
                                <FullName>Partners Ltd</FullName>
                            </OrganizationName>
                        </OrganizationReferences>
                        <BindingAuthorityPeriod>
                            <StartDate>2014-05-01</StartDate>
                            <EndDate>2015-04-30</EndDate>
                        </BindingAuthorityPeriod>
                    </ProducerReferences>
                    <RiskParticipationPercent>1.0000</RiskParticipationPercent>
                </PolicyProducer>
            </PolicySection>
        </Policy>
    </RiskBoundReport>
</RiskBoundReportProcess>

到目前为止,我有两列。我现在想要为UniqueMarketReference创建一个列,该列可在以下节点

中找到
RiskBoundReportProcess/RiskBoundReport/Policy/PolicySection/PolicyProducer[RoleCode="LondonBroker"]/ProducerReferences/ExternalIdentifier/[TypeCode="UniqueMarketReference"]/Id

如何修改下面的SQL以包含它?

SELECT
    Policy.value('@key', 'VARCHAR(50)') AS PolicyId,
    Policy.value('LineOfBusinessCode[1]', 'VARCHAR(50)') AS LineOfBusinessCode
FROM @ACORDXML.nodes('/RiskBoundReportProcess/RiskBoundReport') AS RiskBoundReport(Nodes)

CROSS APPLY RiskBoundReport.Nodes.nodes('Policy') AS Policies(Policy)

我最终还会将The Insured,Coverholer和Underwriter作为专栏。

1 个答案:

答案 0 :(得分:0)

你非常接近......你提供的XPath/之前只有一个[TypeCode ...],这是非常接近的。

试试这样:

SELECT
    Policy.value(N'@key', N'VARCHAR(50)') AS PolicyId
   ,Policy.value(N'LineOfBusinessCode[1]', N'VARCHAR(50)') AS LineOfBusinessCode
   ,Policy.value(N'(/RiskBoundReportProcess/RiskBoundReport/Policy/PolicySection
                   /PolicyProducer[RoleCode="LondonBroker"]
                   /ProducerReferences/ExternalIdentifier[TypeCode="UniqueMarketReference"]/Id/text())[1]','VARCHAR(50)') AS LondonBroker
   ,Policy.value(N'(/RiskBoundReportProcess/RiskBoundReport/Policy/PolicySection
                   /PolicyProducer[RoleCode="Underwriter"]
                   /Producer/Contact/PersonReferences/PersonName/FullName/text())[1]','VARCHAR(50)') AS Underwriter
FROM @ACORDXML.nodes('/RiskBoundReportProcess/RiskBoundReport') AS RiskBoundReport(Nodes)
CROSS APPLY RiskBoundReport.Nodes.nodes('Policy') AS Policies(Policy);

您的某些节点看起来像1:n - 相关(<PersonReferences><PersonName>...)。这可能需要一些额外的努力(.nodes())......