从XML字段插入关系表数据

时间:2017-02-28 22:42:23

标签: sql xml database tsql stored-procedures

我的XML结构如下所示:

SET @TheXML = 
<MailingCompany>
    <Mailman>
            <Name>Jamie</Name>
            <Age> 24 </Age>
                <Letter>
                    <DestinationAddress> 440 Mountain View Parade </DestinationAddress>
                    <DestinationCountry> USA </DestinationCountry>
                    <OriginCountry> Australia </OriginCountry>
                    <OriginAddress> 120 St Kilda Road </OriginAddress>
                </Letter>
    </Mailman>
</MailingCompany>

基本上我有一个书面查询,提取Mailman和Letter的每个子项,并将值插入关系表,如下所示:

INSERT INTO dbo.[Mailman]
SELECT  
    NULLIF(t.value('Name[1]','varchar(100)'),'') as Name,
    NULLIF(t.value('Age[1]','varchar(10)'),'') as Age
FROM @TheXML.nodes('MailingCompany/Mailman') as MailmanTemp(t)

SET @MailPersonFK = SCOPE_IDENTITY();


INSERT INTO dbo.[Letter]
SELECT 
    NULLIF(t.value('DestinationAddress[1]','varchar(100)'),'') as DestinationAddress,
    NULLIF(t.value('DestinationCountry[1]','varchar(100)'),'') as DestinationCountry,
    NULLIF(t.value('OriginCountry[1]','varchar(100)'),'') as OriginCountry,
    NULLIF(t.value('OriginAddress[1]','varchar(100)'),'') as OriginAddress
    @MailPersonFK AS MailmanID
FROM @TheXML.nodes('MailingCompany/Mailman/Letter') as LetterTemp(t)

我的问题是我只想在节点&#39; Name&#39;之后插入Mailman表。填充了数据。插入带有节点&#39; DestinationAddress&#39;。

的Letter也是一样的

它可能也很有用,注意父节点并不总是MailingCompany,而Mailman可以有很多字母。

全部谢谢!

1 个答案:

答案 0 :(得分:1)

我相信将nodes()方法中的XPath更改为以下内容将符合您的要求:

/*/Mailman[Name[text()!=""]]

在这里,我们获得Mailman元素,只要它们是任何顶级元素的子元素,并且只有它们包含文本数据(同样,隐含地,它们必须存在)。

/*/Mailman/Letter[DestinationAddress[text()!=""]]

这个字母获取的是任何顶级节点的子节点,如果有的话,它将获得多个Letter元素。并对文本内容应用相同的测试。

在您提供的XML上成功测试:

  • <Name>Jamie</Name> - 返回姓名和年龄
  • <Name></Name> - 没有返回
  • 没有<Name>元素 - 没有返回。

目的地址的类似测试。