简体   繁体   English

引用xml.nodes的sql server 2008中的while循环

[英]While loop in sql server 2008 that refers to xml.nodes

I have the following issue: 我有以下问题:

I have these 2 while loops that iterates through a node of an xml file but I can't see where to paste the while loop as it needs to be able to reference the xml nodes stated. 我有这2个while循环,它循环遍历xml文件的一个节点,但是我看不到在while循环中粘贴的位置,因为它需要能够引用所述的xml节点。

DECLARE @cnt INT = 1, @temprouteor varchar(50),@temproute varchar(50);
SET @cnt = 1



WHILE @cnt < COUNT(IDC.nodes('Segment/Leg'))-1 

BEGIN
SET @temprouteor = @temprouteor + LORC.value('@CRSCode' , 'Varchar(50)' ) + '/'
SET @cnt = @cnt +1
END

WHILE @cnt = COUNT(IDC.nodes('Segment/Leg')) 
BEGIN
SET @temproute = @temprouteor + LDESC.value('@CRSCode' , 'Varchar(50)' );
END

The 3 nodes are: 这三个节点是:

LEGC
LORC
LDESC

Does anyone have any ideas on how I can achieve this? 有谁对我如何实现这一目标有任何想法?

 <Leg Ref="101" Direction="Outbound" Departure="2016-12-22T06:51:00"       Arrival="2016-12-22T07:04:00" TransportMode="TRAIN">
 <Origin UICCode="7034740" NLCCode="3474" CRSCode="TVP" Name="TIVERTON   PARKWAY" /> 
 <Destination UICCode="7034710" NLCCode="3471" CRSCode="TAU" Name="TAUNTON" /> 
 <TOC Code="GW" Name="Great Western Railway" /> 
 <Reservation PassengerRef="77814233" AccomodationUnit="B33" /> 
 <TrainRoute Ref="101" OriginDeparture="2016-12-22T05:30:00" DestinationArrival="2016-12-22T09:21:00">
 <Origin UICCode="7035800" NLCCode="3580" CRSCode="PLY" Name="PLYMOUTH" /> 
 <Destination UICCode="7030870" NLCCode="3087" CRSCode="PAD" Name="LONDON PADDINGTON" /> 
 </TrainRoute>
 </Leg>
 <Leg Ref="102" Direction="Outbound" Departure="2016-12-22T07:18:00" Arrival="2016-12-22T09:00:00" TransportMode="TRAIN">
 <Origin UICCode="7034710" NLCCode="3471" CRSCode="TAU" Name="TAUNTON" /> 
 <Destination UICCode="7030870" NLCCode="3087" CRSCode="PAD" Name="LONDON PADDINGTON" /> 
 <TOC Code="GW" Name="Great Western Railway" /> 
 <Reservation PassengerRef="77814233" AccomodationUnit="D64" /> 
 <TrainRoute Ref="102" OriginDeparture="2016-12-22T05:53:00" DestinationArrival="2016-12-22T09:00:00">
 <Origin UICCode="7035800" NLCCode="3580" CRSCode="PLY" Name="PLYMOUTH" /> 
 <Destination UICCode="7030870" NLCCode="3087" CRSCode="PAD" Name="LONDON PADDINGTON" /> 
 </TrainRoute>
 </Leg>
 <Leg Ref="103" Direction="Outbound" Departure="2016-12-22T09:15:00" Arrival="2016-12-22T09:21:00" TransportMode="TRAIN">
 <Origin UICCode="7030870" NLCCode="3087" CRSCode="PAD" Name="LONDON PADDINGTON" /> 
 <Destination UICCode="7030000" NLCCode="3000" CRSCode="AML" Name="ACTON MAIN LINE" /> 
 <TOC Code="GW" Name="Great Western Railway" /> 
 <TrainRoute Ref="103" OriginDeparture="2016-12-22T09:15:00" DestinationArrival="2016-12-22T09:40:00">
 <Origin UICCode="7030870" NLCCode="3087" CRSCode="PAD" Name="LONDON PADDINGTON" /> 
 <Destination UICCode="7031360" NLCCode="3136" CRSCode="GFD" Name="GREENFORD" /> 
 </TrainRoute>
 </Leg>
 <Leg Ref="601" Direction="Return" Departure="2016-12-22T14:33:00" Arrival="2016-12-22T14:42:00" TransportMode="TRAIN">
 <Origin UICCode="7030000" NLCCode="3000" CRSCode="AML" Name="ACTON MAIN LINE" /> 
 <Destination UICCode="7030870" NLCCode="3087" CRSCode="PAD" Name="LONDON PADDINGTON" /> 
 <TOC Code="GW" Name="Great Western Railway" /> 
 <TrainRoute Ref="601" OriginDeparture="2016-12-22T14:16:00" DestinationArrival="2016-12-22T14:42:00">
 <Origin UICCode="7031360" NLCCode="3136" CRSCode="GFD" Name="GREENFORD" /> 
 <Destination UICCode="7030870" NLCCode="3087" CRSCode="PAD" Name="LONDON PADDINGTON" /> 
 </TrainRoute>
 </Leg>
 <Leg Ref="602" Direction="Return" Departure="2016-12-22T15:06:00" Arrival="2016-12-22T17:18:00" TransportMode="TRAIN">
 <Origin UICCode="7030870" NLCCode="3087" CRSCode="PAD" Name="LONDON PADDINGTON" /> 
 <Destination UICCode="7034740" NLCCode="3474" CRSCode="TVP" Name="TIVERTON PARKWAY" /> 
 <TOC Code="GW" Name="Great Western Railway" /> 
 <Reservation PassengerRef="77814233" AccomodationUnit="B84" /> 
 <TrainRoute Ref="602" OriginDeparture="2016-12-22T15:06:00" DestinationArrival="2016-12-22T20:42:00">
 <Origin UICCode="7030870" NLCCode="3087" CRSCode="PAD" Name="LONDON PADDINGTON" /> 
 <Destination UICCode="7035260" NLCCode="3526" CRSCode="PNZ" Name="PENZANCE" /> 
 </TrainRoute>
 </Leg>

Expected output is to see a concatenated routing of all the legs of the train journey. 预期的输出是看到火车行程的所有分支的级联路线。

In this case: TVP/TAU/PAD/AML/PAD/TVP 在这种情况下:TVP / TAU / PAD / AML / PAD / TVP

Attention 注意

WHILE @cnt < COUNT(IDC.nodes('Segment/Leg'))-1 @cnt <COUNT(IDC.nodes('Segment / Leg'))-1

Shows clearly, that there is deeper nesting, at least one more element around your <Leg> elements called <Segment> . 清楚地表明,嵌套更深,在<Leg>元素周围至少还有一个元素称为<Segment> I do not know your full XML. 我不知道您的完整XML。 You've either to reflect this in your XPath or you use .nodes(//Leg) for a deep search (not recommended). 您要么在XPath反映出来,要么使用.nodes(//Leg)进行深度搜索 (不建议使用)。

I reduced this to two <Leg> nodes. 我将其减少为两个<Leg>节点。 The same applies with more of them: 对于更多的人也是如此:

DECLARE @xml XML=
N'<Leg Ref="101" Direction="Outbound" Departure="2016-12-22T06:51:00" Arrival="2016-12-22T07:04:00" TransportMode="TRAIN">
  <Origin UICCode="7034740" NLCCode="3474" CRSCode="TVP" Name="TIVERTON   PARKWAY" />
  <Destination UICCode="7034710" NLCCode="3471" CRSCode="TAU" Name="TAUNTON" />
  <TOC Code="GW" Name="Great Western Railway" />
  <Reservation PassengerRef="77814233" AccomodationUnit="B33" />
  <TrainRoute Ref="101" OriginDeparture="2016-12-22T05:30:00" DestinationArrival="2016-12-22T09:21:00">
    <Origin UICCode="7035800" NLCCode="3580" CRSCode="PLY" Name="PLYMOUTH" />
    <Destination UICCode="7030870" NLCCode="3087" CRSCode="PAD" Name="LONDON PADDINGTON" />
  </TrainRoute>
</Leg>
<Leg Ref="102" Direction="Outbound" Departure="2016-12-22T07:18:00" Arrival="2016-12-22T09:00:00" TransportMode="TRAIN">
  <Origin UICCode="7034710" NLCCode="3471" CRSCode="TAU" Name="TAUNTON" />
  <Destination UICCode="7030870" NLCCode="3087" CRSCode="PAD" Name="LONDON PADDINGTON" />
  <TOC Code="GW" Name="Great Western Railway" />
  <Reservation PassengerRef="77814233" AccomodationUnit="D64" />
  <TrainRoute Ref="102" OriginDeparture="2016-12-22T05:53:00" DestinationArrival="2016-12-22T09:00:00">
    <Origin UICCode="7035800" NLCCode="3580" CRSCode="PLY" Name="PLYMOUTH" />
    <Destination UICCode="7030870" NLCCode="3087" CRSCode="PAD" Name="LONDON PADDINGTON" />
  </TrainRoute>
</Leg>';

--This is the query -这是查询

 SELECT l.value('@Ref','int') AS Leg_Ref
       ,l.value('@Direction','nvarchar(max)') AS Leg_Direction
       ,l.value('@Departure','datetime') AS Leg_Departure
       --more attributes in <Leg>
       ,l.value('(Origin/@UICCode)[1]','int') AS Origin_UICCode
       --more attributes in `<Leg><Origin>`
       --Same approach for following elements
       ,l.value('(TrainRoute/Origin/@UICCode)[1]','int') AS TrainRoute_Origin
       --and so on...
 FROM @xml.nodes('/Leg') AS A(l)

The result for the first two elements: 前两个元素的结果:

101 Outbound    2016-12-22 06:51:00.000 7034740 7035800
102 Outbound    2016-12-22 07:18:00.000 7034710 7035800

UPDATE Found your later added expected output 更新找到您以后添加的预期输出

TVP/TAU/PAD/AML/PAD/TVP TVP / TAU / PAD / AML / PAD / TVP

This will fetch the nodes in question: 这将获取有问题的节点:

 SELECT l.value('@Ref','int') AS Leg_Ref
       ,l.value('(Origin/@CRSCode)[1]','nvarchar(max)') AS Origin_CRSCode
       ,l.value('(Destination/@CRSCode)[1]','nvarchar(max)') AS Destination_CRSCode
 FROM @xml.nodes('/Leg') AS A(l)

returns for the sample data 返回样本数据

 Leg_Ref    Origin_CRSCode  Destination_CRSCode
101         TVP             TAU
102         TAU             PAD
103         PAD             AML
601         AML             PAD
602         PAD             TVP

But I do not know, how these nodes are connected. 但是我不知道这些节点是如何连接的。 You'd probably need a recursive CTE. 您可能需要递归CTE。

UPDATE 2 更新2

From your comments I think you want this: 从您的评论中,我认为您想要这样做:

WITH AllLegs AS
(
     SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS PosNr
           ,l.value('@Ref','int') AS Leg_Ref
           ,l.value('(Origin/@CRSCode)[1]','nvarchar(max)') AS Orig
           ,l.value('(Destination/@CRSCode)[1]','nvarchar(max)') AS Dest
     FROM @xml.nodes('/Leg') AS A(l)
)
SELECT Orig + '/' + Dest
    + (
        SELECT '/' + Dest FROM AllLegs WHERE PosNr>1 ORDER BY PosNr FOR XML PATH('')
      )
 FROM AllLegs WHERE PosNr=1

The result 结果

 TVP/TAU/PAD/AML/PAD/TVP

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM