I have to query an XML to extract the data and put it into columns. This works perfectly. However, I want to include a loop because the structure in the XML is as follows:
<BlockOrderMessage>
<FlightOrder>
<Flight>
<FlightNr>5</FlightNr>
<AircraftType>A255</AircraftType>
</Flight>
<PositionOrders>
<PositionOrder Unit="Unit 5">
<UnitName>UnitName5</UnitName>
<CardColor>Blue</CardColor>
</PositionOrder>
<PositionOrder Unit='Unit 6">
<UnitName>UnitName6</UnitName>
<CardColor>Red</CardColor>
</PositionOrder>
</PositionOrders>
</FlightOrder>
</BlockOrderMessage>
There's always only one , but there can be more ... Now, I can generate the column (when knowing the amount of ) using following code:
DECLARE @Data XML
SET @Data =
'<?xml version="1.0" encoding="UTF-8"?>
<BlockOrderMessage xmlns="http://www...."
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.... file:/C:/Users/.....xsd">
<FlightOrder>
<Flight>
<FlightNr>FlightNr0</FlightNr>
<AircraftType>AircraftType0</AircraftType>
<PositionOrders>
<PositionOrder Unit="Unit 5">
<UnitName>UnitName5</UnitName>
<CardColor>Blue</CardColor>
</PositionOrder>
<PositionOrder Unit="Unit 6">
<UnitName>UnitName6</UnitName>
<CardColor>Red</CardColor>
</PositionOrder>
</PositionOrders>
</FlightOrder>
</BlockOrderMessage>'
;WITH XMLNAMESPACES (DEFAULT 'http://www....')
SELECT @Data.value('(/BlockOrderMessage/FlightOrder/Flight/FlightNr)[1]','VARCHAR(20)') AS 'FlightNr',
@Data.value('(/BlockOrderMessage/FlightOrder/Flight/AircraftType)[1]','VARCHAR(20)') AS 'AircraftType',
@Data.value('(/BlockOrderMessage/FlightOrder/PositionOrders/PositionOrder/@Unit)[1]','VARCHAR(30)') AS 'PosOrder1_Unit ',
@Data.value('(/BlockOrderMessage/FlightOrder/PositionOrders/PositionOrder/UnitName)[1]','VARCHAR(30)') AS 'PosOrder1_UnitName',
@Data.value('(/BlockOrderMessage/FlightOrder/PositionOrders/PositionOrder/CardColor)[1]','VARCHAR(30)') AS 'PosOrder1_CardColor',
@Data.value('(/BlockOrderMessage/FlightOrder/PositionOrders/PositionOrder[2]/@Unit)[1]','VARCHAR(30)') AS 'PosOrder2_Unit',
@Data.value('(/BlockOrderMessage/FlightOrder/PositionOrders/PositionOrder[2]/UnitName)[1]','VARCHAR(30)') AS 'PosOrder2_UnitName',
@Data.value('(/BlockOrderMessage/FlightOrder/PositionOrders/PositionOrder[2]/CardColor)[1]','VARCHAR(30)') AS 'PosOrder2_CardColor'
But I want to insert a loop for the PositionOrder bit, I tried the following code (only the last part, since the rest stays the same):
;WITH XMLNAMESPACES (DEFAULT 'http://www....')
SELECT @Data.value('(/BlockOrderMessage/FlightOrder/Flight/FlightNr)[1]','VARCHAR(20)') AS 'FlightNr',
@Data.value('(/BlockOrderMessage/FlightOrder/Flight/AircraftType)[1]','VARCHAR(20)') AS 'AircraftType'
DECLARE @counter INT
SET @counter = 1
WHILE (@Data.value('(/BlockOrderMessage/FlightOrder/PositionOrders/PositionOrder/@Unit)[1]') IS NOT NULL)
BEGIN
;WITH XMLNAMESPACES (DEFAULT 'http://www....')
SELECT @Data.value('(/BlockOrderMessage/FlightOrder/PositionOrders/PositionOrder/@Unit)[1]','VARCHAR(30)') AS 'PosOrder_@counter_Unit ',
@Data.value('(/BlockOrderMessage/FlightOrder/PositionOrders/PositionOrder/UnitName)[1]','VARCHAR(30)') AS 'PosOrder_@counter_UnitName',
@Data.value('(/BlockOrderMessage/FlightOrder/PositionOrders/PositionOrder/CardColor)[1]','VARCHAR(30)') AS 'PosOrder_@counter_CardColor'
SET @counter = @counter +1
END
GO
Now, I have the following problems with this loop and the result of my query:
- The results of the query for the PositionOrder are all NULL, this wasn't the case when I did it without loops.
- I get two tables as query result, but I want them in one table. I tried to do it so I only use one SELECT statement, but I can't get the code right.
- I want the name of the column to show the counter number: So if we are in the second loop, we want the name of the column to be PosOrder_2_..., now it shows PosOrder_@counter_...
Does anybody know what I am doing wrong or how I should fix this problem?
Thanks in advance!
