在SQL Server中读取XML数据

时间:2018-06-05 08:56:39

标签: sql sql-server xml tsql xpath

在我的数据库中,我有一个包含这种格式的XML的表:

<grdCharges>
  <Row>
    <Code>92015</Code>
    <Description>Manifest Refraction</Description>
    <Units />
    <Mod1 />
    <Mod2 />
    <Mod3 />
    <Mod4 />
    <Ptr1>1</Ptr1>
    <Ptr2 />
    <Ptr3 />
    <Ptr4 />
  </Row>
  <Row>
    <Code>92014</Code>
    <Description>Established Patient Comprehensive 180 (108)</Description>
    <Units />
    <Mod1 />
    <Mod2 />
    <Mod3 />
    <Mod4 />
    <Ptr1>1</Ptr1>
    <Ptr2 />
    <Ptr3 />
    <Ptr4 />
  </Row>
</grdCharges>

我想将其转换为以下输出:

id   Code  Description   
1   92015  Manifest Refraction  
1   92014  Established Patient Comprehensive 180 (108)

我试过这样做:

Create table #XML  
  (    id int  
     , xmldata xml  
  )

insert into #xml values     
 ( 1   
   ,  '<grdCharges>
    <Row>
   <Code>92015</Code>
   <Description>Manifest Refraction</Description>
    <Units />
   <Mod1 />
   <Mod2 />
   <Mod3 />
  <Mod4 />
   <Ptr1>1</Ptr1>
   <Ptr2 />
   <Ptr3 />
   <Ptr4 />
      </Row>
      <Row>
    <Code>92014</Code>
    <Description>Established Patient Comprehensive 180 (108)</Description>
    <Units />
    <Mod1 />
    <Mod2 />
    <Mod3 />
    <Mod4 />
    <Ptr1>1</Ptr1>
    <Ptr2 />
    <Ptr3 />
    <Ptr4 />
    </Row>
    </grdCharges>'

    )

select  id,  
  X.Y.value('.','Varchar(100)') Code  
 ,P.Q.value('.','Varchar(100)') Description  
   from #xml  
         Cross apply xmldata.nodes('/grdCharges/Row/Code') X(Y)  
        Cross apply Y.nodes('/grdCharges/Row/Description') P(Q) 

但它给了我以下结果:

id  Code    Description
1   92015   Manifest Refraction
1   92015   Established Patient Comprehensive 180 (108)
1   92014   Manifest Refraction
1   92014   Established Patient Comprehensive 180 (108)

我认为问题在于第二次交叉申请。如何使用第二次交叉申请?

如果不是cross apply那么我还能做些什么来获得理想的结果?我需要一些帮助。

1 个答案:

答案 0 :(得分:0)

你自己的尝试非常接近......

使用APPLY获取重复节点的派生表。这是<Row>,而 <Row>中的节点是您要获取的值:

select  id,  
  X.Y.value('(Code/text())[1]','Varchar(100)') Code
 ,X.Y.value('(Description/text())[1]','Varchar(100)') Description  
from #xml  
Cross apply xmldata.nodes('/grdCharges/Row') X(Y)