Tenho uma tabela, contendo uma coluna XML XmlMsg
. Esta coluna pode conter orderstatus
, vehiclestatus
, ....
Estou interessado apenas em orderstatus
nós, e mais exatamente nos dois casos seguintes:
- O último
orderpart
é "Pendente". - O último
orderpart
é "Pendente" e o penúltimo é "Concluído".
Um exemplo do primeiro é o seguinte (mostrando apenas a parte relevante):
<orderstatus responsecode="0"
...
numberoforderparts="3">
...
<orderparts>
<orderpart orderpartnumber="1"/>
<orderpart orderpartnumber="2"/>
<orderpart orderpartnumber="3">
<eventtype>Pending</eventtype>
...
</orderpart>
</orderparts>
</orderstatus>
Um exemplo do segundo é o seguinte (também mostrando apenas a parte relevante):
<orderstatus responsecode="0"
...
numberoforderparts="3">
...
<orderparts>
<orderpart orderpartnumber="1"/>
<orderpart orderpartnumber="2">
<eventtype>Completed</eventtype>
...
</orderpart>
<orderpart orderpartnumber="3">
<eventtype>Pending</eventtype>
...
</orderpart>
</orderparts>
</orderstatus>
Consegui obter a primeira lista com esta consulta:
SELECT *,
XmlMsg.value('(/orderstatus/@numberoforderparts)[1]', 'INT') AS NumberOfOrderParts,
-- Retrieve the last orderpart with eventtype="Pending"
XmlMsg.query('(/orderstatus/orderparts/orderpart[@orderpartnumber = (/orderstatus/@numberoforderparts)[1] and eventtype="Pending"])[1]') AS LastOrderPart,
-- Retrieve the second-to-last orderpart with eventtype="Completed"
XmlMsg.query('(/orderstatus/orderparts/orderpart[@orderpartnumber = (/orderstatus/@numberoforderparts)[1] - 1 and eventtype="Completed"])[1]') AS PreviousOrderPart
FROM
[dbo].[AWIMessageLogs]
WHERE
Source = 'RCV_RESP'
AND LogDateTime >= '2024-11-26'
AND LogDateTime <= '2024-11-26 15:00'
AND XmlMsg.exist('/orderstatus') = 1
-- Ensure that the last orderpart has eventtype="Pending"
AND XmlMsg.query('(/orderstatus/orderparts/orderpart[@orderpartnumber = (/orderstatus/@numberoforderparts)[1] and eventtype="Pending"])[1]') IS NOT NULL
No entanto, não tenho ideia de como obter a segunda lista.
Alguém tem alguma ideia?
Geralmente é mais fácil obter essas coisas usando o método nodes, algo como:
Então você pode usar algum LAG/LEAD para procurar os valores relevantes ou colocar os dados em uma tabela temporária e processá-los a partir daí.
Saída:
Você pode usar o XPath 1.0 para ambas as consultas:
Obtenha os
orderstatus
nós onde o últimoorderpart
está"Pending"
:Obtenha os
orderstatus
nós onde o últimoorderpart
está"Pending"
e o penúltimo é"Complete"
:db<>fiddle (por @Charlieface)