【问题标题】:Parse XML in a SQL Server stored procedure在 SQL Server 存储过程中解析 XML
【发布时间】:2021-05-07 02:11:41
【问题描述】:

我有

INSERT INTO [PubMed.Author] (pmid, ValidYN, LastName, FirstName, ForeName, Suffix, Initials, Affiliation)
    SELECT
        pmid, 
        nref.value('@ValidYN', 'varchar(max)') ValidYN, 
        nref.value('LastName[1]', 'varchar(max)') LastName, 
        nref.value('FirstName[1]', 'varchar(max)') FirstName,
        nref.value('ForeName[1]', 'varchar(max)') ForeName,
        nref.value('Suffix[1]', 'varchar(max)') Suffix,
        nref.value('Initials[1]', 'varchar(max)') Initials,
        nref.value('Affiliation[1]', 'varchar(max)') Affiliation
    FROM
        [Publication.PubMed.XML] 
    CROSS APPLY
        XMLData.nodes('//AuthorList/Author') AS R(nref)
    WHERE
        pmid = @pmid

当 PubMed 只列出一个附属机构时,它曾经工作得很好

<Author ValidYN="Y">
    <LastName>Smith</LastName>
    <ForeName>John</ForeName>
    <Initials>J</Initials>
    <Affiliation>Department of Medicine, XYZ, NY USA; The Stony Brook Cancer Center, Stony Brook, NY 
11794, USA.</Affiliation>  
</Author>

但是它已经将 Affiliation 更改为多节点

<Author ValidYN="Y">
    <LastName>Smith</LastName>
    <ForeName>John</ForeName>
    <Initials>J</Initials>
    <AffiliationInfo> 
        <Affiliation>Department of Medicine, XYZ, NY USA; </Affiliation> 
    </AffiliationInfo>
    <AffiliationInfo>
        <Affiliation>The Stony Brook Cancer Center, Stony Brook, NY 11794, USA.</Affiliation>  ​
   ​</AffiliationInfo>
​</Author>

我的问题是如何更改我的代码以连接所有从属关系并将其添加到我的插入中?

【问题讨论】:

  • 当您说concatenate 时,您觉得怎么样?单个值,每个值之间有逗号,还有别的吗?
  • 单个值 - 是但不是逗号,因为这将在附属字符串中,但可能是双栏 ||它们之间,因此可以将其保存到单个字段中,但如果需要,将来会分开。

标签: xml sql-server-2016


【解决方案1】:

请尝试以下解决方案。

主要的变化不是这一行:

nref.value('Affiliation[1]','varchar(max)') Affiliation

如下:

nref.query('data(AffiliationInfo/Affiliation/text())').value('.','varchar(max)') Affiliation

SQL

DECLARE @xml XML = 
N'<Author ValidYN="Y">
    <LastName>Smith</LastName>
    <FirstName>John</FirstName>
    <Initials>J</Initials>
    <AffiliationInfo>
        <Affiliation>Department of Medicine, XYZ, NY USA;</Affiliation>
    </AffiliationInfo>
    <AffiliationInfo>
        <Affiliation>The Stony Brook Cancer Center, Stony Brook, NY 11794, USA.</Affiliation>​
   ​</AffiliationInfo>
</Author>';

SELECT nref.value('@ValidYN','varchar(max)') AS ValidYN
    , nref.value('(LastName/text())[1]','varchar(max)') AS LastName
    , nref.value('(FirstName/text())[1]','varchar(max)') AS FirstName
    , nref.value('(ForeName/text())[1]','varchar(max)') AS ForeName
    , nref.value('(Suffix/text())[1]','varchar(max)') AS Suffix
    , nref.value('(Initials/text())[1]','varchar(max)') AS Initials
    , nref.query('data(AffiliationInfo/Affiliation/text())').value('.','varchar(max)') AS Affiliation
FROM @xml.nodes('/Author') AS t(nref);

SQL #2

SELECT nref.value('@ValidYN','varchar(max)') AS ValidYN
    , nref.value('(LastName/text())[1]','varchar(max)') AS LastName
    , nref.value('(FirstName/text())[1]','varchar(max)') AS FirstName
    , nref.value('(ForeName/text())[1]','varchar(max)') AS ForeName
    , nref.value('(Suffix/text())[1]','varchar(max)') AS Suffix
    , nref.value('(Initials/text())[1]','varchar(max)') AS Initials
    , nref.query('
        for $r in AffiliationInfo/Affiliation/text()
        let $token := concat("[", $r, "]")
        return $token
        ').value('text()[1]','varchar(max)')AS Affiliation
FROM @xml.nodes('/Author') AS t(nref);

【讨论】:

  • .value('text()[1]' 比 . 快
  • 该解决方案效果很好,正是我所要求的,但我有一个问题。是否可以在连接的字符串之间放置一些东西?喜欢 || ?
  • 我也会试试 .value('text()[1]' -- 谢谢
  • @user1314159 你可以把.query改成...query(concat(data(AffiliationInfo/Affiliation/text()), "||")).value...
  • @user1314159,我添加到答案 SQL #2 部分。看看吧。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-07
  • 2016-11-03
  • 2013-03-18
相关资源
最近更新 更多