如何在读取 Sql 中的 xml 时向 COALESCE 添加条件

How to add condition to COALESCE while reading xml in Sql

我正在尝试读取 xml 并将其存储在 SQL 服务器中。

DECLARE @xml XML
SET @xml = 
 '<report>
    <personal>
       <search>
           <subject>
               <name>SearchName</name>
           </subject>
       </search>    
    </personal>
    <personal>
       <search>
           <subject>
               <name>SearchName</name>
           </subject>
       </search>
       <result>
           <history>
              <name>HistoryName</name>
           </history>
       </result>
    </personal>
    <personal>
       <search>
           <subject>
               <name>SearchName</name>
           </subject>
       </search>
       <result>
           <history>
              <dob>HistoryDOB</dob>
           </history>
       </result>
    </personal>
  </report>
'

我在这里尝试的是 - select输入名称,但这里的条件是

  1. 如果<personal>包含<result>则selectnamehistory/name

  2. if <personal> 不包含 <result> select subject/name

    [=45 下的 name =]
  3. 如果 <personal> 包含 <result> 但名称不存在则输入 null

我正在使用以下查询

SELECT 
COALESCE(
   A.Search.value('(result/history/name)[1]','varchar(max)'),
   A.Search.value('(search/subject/name)[1]','varchar(max)')
) AS Name
FROM @xml.nodes('/report/personal') as A(Search)

正在返回

 SearchName
 HistoryName
 SearchName

但它在第三个条件下失败了。

只需调整第二个 values 调用以专门请求您指定的内容 - 对于没有 result:[=15= 的节点,您只会使用 search/subject ]

SELECT 
COALESCE(
   A.Search.value('(result/history/name)[1]','varchar(max)'),
   A.Search.value('(search[not(../result)]/subject/name)[1]','varchar(max)')
) AS Name
FROM @xml.nodes('/report/personal') as A(Search)

结果:

Name
------------------
HistoryName
SearchName
NULL

您可以使用exist方法来检查<personal>是否包含<result>

使用它,您的算法可以直接转换为查询:

select
    case 
        when A.Search.exist('result') = 1
            then A.Search.value('(result/history/name)[1]','varchar(max)')
        else A.Search.value('(search/subject/name)[1]','varchar(max)')
    end as Name
FROM @xml.nodes('/report/personal') as A(Search)