Я пытаюсь получить некоторый xml, и похоже, что моя структура не соответствует ни одному учебному примеру, который я проверял, я не могу выбрать ... из xml.nodes. Как я могу получить все значения для идентификатора меры (aba, cbp) и значения den для ABA (= 777). введите описание изображения здесь

Это был мой первый подход, и он не работает

    SELECT xmldata
 , n0.b.value('(@type)[1]', 'varchar(100)') as  c1   --<  'GGM'
 , n.b.value('(@id)[1]', 'varchar(100)') as  m1   --<  ABA
 , n.b.value('(@id)[2]', 'varchar(100)') as  m2   --<  CBP
 FROM z
 CROSS APPLY z.xmldata.nodes('//submission/component/audit/data/measures/measure') AS n(b)
 CROSS APPLY z.xmldata.nodes('//submission/component') AS n0(b)

Ниже тестовая нагрузка:

   DECLARE @MyXML XML;
    SET @MyXML =
     ('<?xml version="1.0" encoding="UTF-8"?>
    <submission vendor-id="9999" guid="1234-5678-4578-4784" xmlns="http://www.ncqa.org/ns/2006/idss/hedis">
    <metadata>
        <version>41</version>
        <timestamp/>
        <sub-id>1434588</sub-id>
        <org-id/>
        <org-name/>
        <product-line>NC15</product-line>
        <reporting-product/>
        <special-project/>
        <special-area/>
        <hcfa-contract/>
        <hcfa-area/>
        <year-end-date>12/31/2016</year-end-date>
        <audit>true</audit>
    </metadata>
    <component type="GGM">
    <audit>
       <measures>
            <measure id="aba">
            <reported>true</reported>
            <benefit>true</benefit>
            <data-elements>
            <data-element id="rate">
            <audit-designation>false</audit-designation>
            <comment/>
            </data-element>
            </data-elements>
            </measure>
            <measure id="cbp">
            <reported>true</reported>
            <benefit>true</benefit>
            <data-elements>
            <data-element id="rate">
            <audit-designation>false</audit-designation>
            <comment/>
            </data-element>
            </data-elements>
            </measure>

       </measures>

       <data>
       <measures>
            <measure id="aba" measure-version-id="44444-222222-33333">
            <data-elements>
                <data-element id="den">
                <value>777</value>
                </data-element>
                <data-element id="elignu">
                <value>48</value>
                </data-element>
                <data-element id="eligpop">
                <value>777</value>
                </data-element>
            </data-elements>

        </measure>
        <measure id="cbp" measure-version-id="11111-222222-33333">
            <data-elements>
            <data-element id="admexc">
            <value>0</value>
            </data-element>
            <data-element id="collmeth">
            <value>H</value>
            </data-element>
            <data-element id="dentot">
            <value>355</value>
            </data-element>
            <data-element id="eligtot">
            <value>123</value>
            </data-element>
            <data-element id="empexc">
            <value>0</value>
            </data-element>


            </data-elements>
            </measure>  

       </measures>

       </data>
       </audit>
    </component> 
    </submission>')

     SELECT @MyXML as xmldata into z;
2
Mike S 20 Июн 2017 в 01:37
Спасибо за тестовую загрузку ! +1 с моей стороны
 – 
Shnugo
20 Июн 2017 в 09:50

1 ответ

Лучший ответ

Сообщение об ошибке, которое вы показываете:

Msg 9506, уровень 16, состояние 1, строка 1 «Узлы» метода XMLDT можно вызывать только для столбцов типа xml.

... указывает на столбец таблицы, который содержит XML, но неправильно набран. Сначала вам нужно будет разыграть это (например, CAST StringXML AS XML). Если возможно, вы должны сохранить значение в формате XML. Это намного быстрее !!

О чтении вашего XML

В вашем верхнем узле <submission> есть пространство имен по умолчанию xmlns="something". При чтении XML вы должны либо объявить это пространство имен, либо использовать подстановочный знак пространства имен (*:). Общий совет: будьте как можно более конкретными!

Попробуйте так:

Считывание одного значения из <metadata>:

WITH XMLNAMESPACES(DEFAULT 'http://www.ncqa.org/ns/2006/idss/hedis')
SELECT @MyXML.value(N'(/submission/metadata/version)[1]',N'int') AS metadata_version;

- Вероятно, вам нужен запрос

WITH XMLNAMESPACES(DEFAULT 'http://www.ncqa.org/ns/2006/idss/hedis')
SELECT m.value(N'@id',N'nvarchar(max)')
      ,m.value(N'(data-elements/data-element[@id="den"]/value/text())[1]',N'int')
FROM @MyXML.nodes(N'/submission/component/audit/data/measures/measure') AS A(m); 

То же для ленивых (не рекомендуется)

SELECT m.value(N'@id',N'nvarchar(max)')
      ,m.value(N'(*:data-elements/*:data-element[@id="den"]/*:value/text())[1]',N'int')
FROM @MyXML.nodes(N'//*:data//*:measure') AS A(m); 
2
Shnugo 20 Июн 2017 в 09:48