Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server sql server在一个查询中分解多个节点的xml_Sql Server_Xml_Tsql_Xpath_Xquery - Fatal编程技术网

Sql server sql server在一个查询中分解多个节点的xml

Sql server sql server在一个查询中分解多个节点的xml,sql-server,xml,tsql,xpath,xquery,Sql Server,Xml,Tsql,Xpath,Xquery,由于xml中的节点级别不同,在sql server中分解此xml时遇到问题。我如何通过一个查询来实现这一点。下面是xml的示例 <Report> <P> <Data> <Cust custID = "A" custName = "B" ></Cust> </Data> </P> <H> <Data1> <Seats>

由于xml中的节点级别不同,在sql server中分解此xml时遇到问题。我如何通过一个查询来实现这一点。下面是xml的示例

<Report>
<P>
    <Data>
             <Cust custID = "A" custName = "B" ></Cust>
 </Data>
</P>
<H>
    <Data1>
        <Seats>
            <Seat id = "abc" value = "123" ></Seat>
            <Date depart = "abc1" arrive = "1231" ></Date>
            <Records>
                <Record  recID = "C" col2 = "D" ></Record>
            </Records>
        </Seats>
        <Seats>
            <Seat id = "xyz" value = "756" ></Seat>
            <Date depart = "asd" arrive = "6781" ></Date>
            <Records>
                <Record  recID = "1" col2 = "6" ></Record>
                <Record  recID = "2" col2 = "7" ></Record>
            </Records>
        </Seats>
     </Data1>
    <Data2>
        <S id = "1" value = "eco" ></S>
        <S id = "2" value = "bus" ></S>
    </Data2>
    <Data3>
        <Guest id = "100" value = "aaa" recID="C"></Guest>
        <Guest id = "101" value = "bbb" recID="1"></Guest>
        <Guest id = "102" value = "ccc" recID="2"></Guest>
    </Data3>
 </H>
 </Report>


以下代码提供了一些模板,用于将任何位置的值读取到平面表格中。自己添加缺少的列。这应该很容易

DECLARE @xml XML=
N'<Report>
 <P>
    <Data>
      <Cust custID="A" custName="B" />
    </Data>
  </P>
  <H>
    <Data1>
      <Seats>
        <Seat id="abc" value="123" />
        <Date depart="abc1" arrive="1231" />
        <Records>
          <Record recID="C" col2="D" />
        </Records>
      </Seats>
      <Seats>
        <Seat id="xyz" value="756" />
        <Date depart="asd" arrive="6781" />
        <Records>
          <Record recID="1" col2="6" />
          <Record recID="2" col2="7" />
        </Records>
      </Seats>
    </Data1>
    <Data2>
      <S id="1" value="eco" />
      <S id="2" value="bus" />
    </Data2>
    <Data3>
      <Guest id="100" value="aaa" recID="C" />
      <Guest id="101" value="bbb" recID="1" />
      <Guest id="102" value="ccc" recID="2" />
    </Data3>
  </H>
</Report>';
在这个平面表格中获得数据后,您可以使用任何类型的
SELECT…GROUP BY
,为插入到特定明细表中做好准备

如果这对您没有帮助,您必须提供有关目标结构的更多信息

更新 根据您的评论,您希望将客人放在座位旁边,通过
@recID
链接。这可以通过将此值读入普通结果集列,然后使用
sql:column()
XQuery
谓词中使用此值来实现:

此操作的结果(不知道如何处理
值)


由于某些原因,结束标记被切断。您必须更具体地说明如何分割节点。你想要的结果是什么?行集不是分层的,因此必须选择如何将元素和属性映射到列。@DC07由于某种原因被切断:它没有缩进。XML将不会显示,除非它被标记为
code
(反勾号或缩进)hi-Shnugo,是的,这或多或少就是我想要的。我想,剩下的问题可以用SQL解决。问题是,例如,座位id“abc”实际上只适用于客人id“100”。通过记录id连接(我将其添加到xml中.,因为它丢失了)。在这个结果中,每一项都是交叉应用的other@DC07好吧,这会变得有点复杂,但你可以在我的更新中找到解决方案
 select @xml.value('(/Report/P/Data/Cust/@custID)[1]','nvarchar(max)') AS CustomerID
       ,@xml.value('(/Report/P/Data/Cust/@custName)[1]','nvarchar(max)') AS CustomerName
       ,B.Seat.value('(Seat/@id)[1]','nvarchar(max)') AS SeatId
       ,B1.Record.value('@recID','nvarchar(max)') AS SeatRecordId
       ,C.S.value('@id','int') AS S_Id
       ,D.Guest.value('@id','int') AS Guest_Id
 INTO #FlatTable
 FROM @xml.nodes('/Report/H') AS A(DataNode)
 OUTER APPLY A.DataNode.nodes('Data1/Seats') AS B(Seat)
 OUTER APPLY B.Seat.nodes('Records/Record') AS B1(Record) 
 OUTER APPLY A.DataNode.nodes('Data2/S') AS C(S) 
 OUTER APPLY A.DataNode.nodes('Data3/Guest') AS D(Guest);

 SELECT * FROM #FlatTable;
 select @xml.value('(/Report/P/Data/Cust/@custID)[1]','nvarchar(max)') AS CustomerID
       ,@xml.value('(/Report/P/Data/Cust/@custName)[1]','nvarchar(max)') AS CustomerName
       ,B.Seat.value('(Seat/@id)[1]','nvarchar(max)') AS SeatId
       ,B2.RecordId AS SeatRecordId
       ,B3.Guest.value('@id','int') AS Guest_Id
       ,C.S.value('@id','int') AS S_Id
 INTO #FlatTable
 FROM @xml.nodes('/Report/H') AS A(DataNode)
 OUTER APPLY A.DataNode.nodes('Data1/Seats') AS B(Seat)
 OUTER APPLY B.Seat.nodes('Records/Record') AS B1(Record) 
 OUTER APPLY (SELECT B1.Record.value('@recID','nvarchar(max)')) AS B2(RecordId)
 OUTER APPLY A.DataNode.nodes('Data3/Guest[@recID=sql:column("B2.RecordId")]') AS B3(Guest)
 OUTER APPLY A.DataNode.nodes('Data2/S') AS C(S);
+------------+--------------+--------+--------------+----------+------+
| CustomerID | CustomerName | SeatId | SeatRecordId | Guest_Id | S_Id |
+------------+--------------+--------+--------------+----------+------+
| A          | B            | abc    | C            | 100      | 1    |
+------------+--------------+--------+--------------+----------+------+
| A          | B            | abc    | C            | 100      | 2    |
+------------+--------------+--------+--------------+----------+------+
| A          | B            | xyz    | 1            | 101      | 1    |
+------------+--------------+--------+--------------+----------+------+
| A          | B            | xyz    | 1            | 101      | 2    |
+------------+--------------+--------+--------------+----------+------+
| A          | B            | xyz    | 2            | 102      | 1    |
+------------+--------------+--------+--------------+----------+------+
| A          | B            | xyz    | 2            | 102      | 2    |
+------------+--------------+--------+--------------+----------+------+