Создать условие where из значения XML с несколькими пространствами имен - PullRequest
1 голос
/ 03 марта 2020

Я хочу вернуть значение для моего условия where из XML. Я хотел бы вернуть значение из сообщений таблицы Запрос столбец . Который находится в XML формате данных. К сожалению, все, чего я мог достичь, это ничего не получить. Затем я попытался поместить значение в виде столбца, но всегда получаю значения NULL для значений

Вот столбец XML из запроса:

<InvoiceRequest xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/InternalReuqests">
  <ActiveUserID xmlns="http://schemas.datacontract.org/2004/07/Fix.ServiceBase">0</ActiveUserID>
  <LinqConfigId xmlns="http://schemas.datacontract.org/2004/07/Fix.ServiceBase">0</LinqConfigId>
  <RequestHeaderInfo xmlns:d2p1="Fix.Services" xmlns="http://schemas.datacontract.org/2004/07/Fix.ServiceBase">
    <d2p1:MapArchive i:nil="true" />
    <d2p1:HandledSuccessCategory>rscNone</d2p1:HandledSuccessCategory>
  </RequestHeaderInfo>
  <Username xmlns="http://schemas.datacontract.org/2004/07/Fix.ServiceBase" i:nil="true" />
  <SSID>S-1-6-25-123456789-123456789-123456789-12345</SSID>
  <miscdata xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
    <d2p1:string>date:2020.02.26 08:27:00</d2p1:string>
    <d2p1:string>hours:0</d2p1:string>
    <d2p1:string>Ready:True</d2p1:string>
    <d2p1:string>disct:False</d2p1:string>
    <d2p1:string>extdisct:False</d2p1:string>
    <d2p1:string>Matmove:False</d2p1:string>
    <d2p1:string>Matlim:0</d2p1:string>
    <d2p1:string>Comments:</d2p1:string>
  </miscdata>
  <ffreeID>468545</ffreeID>
</InvoiceRequest>

вот мой запрос sql:

   select id, Request.value('(/*:InvoiceRequest/*:ffreeID)[1]','varchar(max)')
     from messages

Я думал, что должен получить в первом столбце идентификатор из базы данных, а рядом с ним значение ffreeID, но значение Request.value всегда равно нулю.

Может кто-нибудь посмотрите, что мне не хватает?

Ответы [ 2 ]

1 голос
/ 03 марта 2020

Вот еще один способ, имитирующий макет таблицы. Все остальное напоминает решение @ Ларну. Весь кредит переходит к @ Larnu.

SQL

-- DDL and sample data population, start
DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY, Request XML);
INSERT INTO @tbl (Request)
VALUES
(N'<InvoiceRequest xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
                xmlns="http://schemas.datacontract.org/2004/07/InternalReuqests">
    <ActiveUserID xmlns="http://schemas.datacontract.org/2004/07/Fix.ServiceBase">0</ActiveUserID>
    <LinqConfigId xmlns="http://schemas.datacontract.org/2004/07/Fix.ServiceBase">0</LinqConfigId>
    <RequestHeaderInfo xmlns:d2p1="Fix.Services"
                       xmlns="http://schemas.datacontract.org/2004/07/Fix.ServiceBase">
        <d2p1:MapArchive i:nil="true"/>
        <d2p1:HandledSuccessCategory>rscNone</d2p1:HandledSuccessCategory>
    </RequestHeaderInfo>
    <Username xmlns="http://schemas.datacontract.org/2004/07/Fix.ServiceBase" i:nil="true"/>
    <SSID>S-1-6-25-123456789-123456789-123456789-12345</SSID>
    <miscdata xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
        <d2p1:string>date:2020.02.26 08:27:00</d2p1:string>
        <d2p1:string>hours:0</d2p1:string>
        <d2p1:string>Ready:True</d2p1:string>
        <d2p1:string>disct:False</d2p1:string>
        <d2p1:string>extdisct:False</d2p1:string>
        <d2p1:string>Matmove:False</d2p1:string>
        <d2p1:string>Matlim:0</d2p1:string>
        <d2p1:string>Comments:</d2p1:string>
    </miscdata>
    <ffreeID>468545</ffreeID>
</InvoiceRequest>');
-- DDL and sample data population, end

WITH XMLNAMESPACES(DEFAULT 'http://schemas.datacontract.org/2004/07/InternalReuqests')
SELECT ID
    , c.value('(ffreeID/text())[1]','INT') AS ffreeID
FROM @tbl AS tbl
    CROSS APPLY tbl.Request.nodes('/InvoiceRequest') AS t(c);

Выход

+----+---------+
| ID | ffreeID |
+----+---------+
|  1 |  468545 |
+----+---------+
1 голос
/ 03 марта 2020

Вам необходимо объявить пространство имен по умолчанию, которое для вашего xml равно http://schemas.datacontract.org/2004/07/InternalReuqests:

--Sample XML
DECLARE @xml xml = '<InvoiceRequest xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/InternalReuqests">
  <ActiveUserID xmlns="http://schemas.datacontract.org/2004/07/Fix.ServiceBase">0</ActiveUserID>
  <LinqConfigId xmlns="http://schemas.datacontract.org/2004/07/Fix.ServiceBase">0</LinqConfigId>
  <RequestHeaderInfo xmlns:d2p1="Fix.Services" xmlns="http://schemas.datacontract.org/2004/07/Fix.ServiceBase">
    <d2p1:MapArchive i:nil="true" />
    <d2p1:HandledSuccessCategory>rscNone</d2p1:HandledSuccessCategory>
  </RequestHeaderInfo>
  <Username xmlns="http://schemas.datacontract.org/2004/07/Fix.ServiceBase" i:nil="true" />
  <SSID>S-1-6-25-123456789-123456789-123456789-12345</SSID>
  <miscdata xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
    <d2p1:string>date:2020.02.26 08:27:00</d2p1:string>
    <d2p1:string>hours:0</d2p1:string>
    <d2p1:string>Ready:True</d2p1:string>
    <d2p1:string>disct:False</d2p1:string>
    <d2p1:string>extdisct:False</d2p1:string>
    <d2p1:string>Matmove:False</d2p1:string>
    <d2p1:string>Matlim:0</d2p1:string>
    <d2p1:string>Comments:</d2p1:string>
  </miscdata>
  <ffreeID>468545</ffreeID>
</InvoiceRequest>'; --Assumed this should be </InvoiceRequest>, not <InvoiceRequest>.

--Get value
WITH XMLNAMESPACES(DEFAULT 'http://schemas.datacontract.org/2004/07/InternalReuqests')
SELECT X.Request.value('(/InvoiceRequest/ffreeID/text())[1]','int')
FROM (VALUES(@XML))X(Request);
...