Udostępnij przez


nodes() Method (typ danych xml)

Dotyczy:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceBaza danych SQL w usłudze Microsoft Fabric

Metoda nodes() jest przydatna, gdy chcesz rozstrzygnąć instancję typu danych xml na dane relacyjne. Pozwala zidentyfikować węzły, które zostaną przypisane do nowego wiersza.

Każda instancja typu danych xml ma niejawnie dostarczony węzeł kontekstowy. Dla instancji XML przechowywanej w kolumnie lub zmiennej, tym węzłem jest węzeł dokumentu. Węzeł dokumentu to węzeł domyślny na górze każdej instancji typu danych xml .

Wynikiem metody nodes() jest zestaw wierszy zawierający logiczne kopie oryginalnych instancji XML. W tych kopiach logicznych węzeł kontekstowy każdej instancji wiersza jest ustawiony na jeden z węzłów identyfikowanych z wyrażeniem zapytania. Dzięki temu późniejsze zapytania mogą nawigować względem tych węzłów kontekstowych.

Możesz pobrać wiele wartości z zestawu wierszy. Na przykład możesz zastosować metodę value() do zestawu wierszy zwracanego przez nodes() i pobrać wiele wartości z oryginalnej instancji XML. Metoda value(), po zastosowaniu do instancji XML, zwraca tylko jedną wartość.

Składnia

nodes (XQuery) as Table(Column)  

Arguments

XQuery
To literal łańcuchowy, wyrażenie XQuery. Jeśli wyrażenie zapytania konstruuje węzły, te skonstruowane węzły są ujawnione w powstałym zbiorze wierszy. Jeśli wyrażenie zapytania prowadzi do pustej sekwencji, zbiór wierszy również jest pusty. Jeśli wyrażenie zapytania statycznie daje sekwencję zawierającą wartości atomowe zamiast węzłów, pojawia się błąd statyczny.

Tabela (kolumna)
To nazwa tabeli oraz nazwa kolumny dla powstałego zbioru wierszy.

Uwagi

Na przykład załóżmy, że masz następującą tabelę:

T (ProductModelID INT, Instructions XML)  

Poniższy dokument instrukcji produkcji jest przechowywany w tabeli. Pokazano tylko fragment. Zwróć uwagę, że w dokumencie znajdują się trzy lokalizacje produkcyjne.

<root>  
  <Location LocationID="10"...>  
     <step>...</step>  
     <step>...</step>  
      ...  
  </Location>  
  <Location LocationID="20" ...>  
       ...  
  </Location>  
  <Location LocationID="30" ...>  
       ...  
  </Location>  
</root>  

Wywołanie metody z wyrażeniem nodes() zapytania zwracałoby /root/Location zestaw wierszy z trzema wierszami, z których każdy zawierał logiczną kopię oryginalnego dokumentu XML oraz z elementem kontekstowym ustawionym na jeden z <Location> węzłów:

Product  
ModelID      Instructions  
----------------------------------  
1      <root><Location LocationID="10" ... />  
             <Location LocationID="20" ... />  
             <Location LocationID="30" .../></root>  
1      <root><Location LocationID="10" ... />  
             <Location LocationID="20" ... />  
             <Location LocationID="30" .../></root>  
1      <root><Location LocationID="10" ... />  
             <Location LocationID="20" ... />  
             <Location LocationID="30" .../></root>  

Następnie możesz zapytać ten zestaw wierszy, używając metod typów danych xml . Następujące zapytanie wyodrębnia poddrzewo elementu kontekstowego dla każdego wygenerowanego wiersza:

SELECT T2.Loc.query('.')  
FROM T  
CROSS APPLY Instructions.nodes('/root/Location') AS T2(Loc)   

Oto efekt:

ProductModelID  Instructions  
----------------------------------  
1        <Location LocationID="10" ... />  
1        <Location LocationID="20" ... />  
1        <Location LocationID="30" .../>  

Zwrócony zestaw wierszy zachował informacje o typie. Możesz zastosować metody typu xml, takie jak query(), value(), exist() oraz nodes(), do wyniku metody nodes(). Jednak nie możesz zastosować metody modify() do modyfikacji instancji XML.

Ponadto węzeł kontekstowy w rowsetie nie może zostać zmaterializowany. To znaczy, nie możesz użyć tego w instrukcji SELECT. Możesz jednak użyć go w IS NULL i COUNT(*).

Scenariusze użycia metody nodes() są takie same jak przy użyciu OPENXML (Transact-SQL), który zapewnia widok wierszowego XML. Jednak nie musisz używać kursorów, gdy używasz metody nodes() na tabeli zawierającej kilka wierszy dokumentów XML.

Zestaw wierszy zwracany przez metodę nodes() jest nienazwanym zbiorem wierszy. Musi więc być nazwana wyraźnie za pomocą aliasingu.

Funkcja nodes() nie może być bezpośrednio zastosowana do wyników funkcji zdefiniowanej przez użytkownika. Aby użyć funkcji nodes() z wynikiem skalarnej funkcji użytkownika, możesz:

  • Przypisz wynik funkcji zdefiniowanej przez użytkownika do zmiennej
  • Użyj tabeli pochodnej, aby przypisać alias kolumny wartości zwrotnej funkcji zdefiniowanej przez użytkownika, a następnie użyj CROSS APPLY do wyboru z aliasu.

Poniższy przykład pokazuje jeden ze sposobów CROSS APPLY wyboru z wyniku funkcji zdefiniowanej przez użytkownika.

USE AdventureWorks;  
GO  
  
CREATE FUNCTION XTest()  
RETURNS XML  
AS  
BEGIN  
RETURN '<document/>';  
END;  
GO  
  
SELECT A2.B.query('.')  
FROM  
(SELECT dbo.XTest()) AS A1(X)   
CROSS APPLY X.nodes('.') A2(B);  
GO  
  
DROP FUNCTION XTest;  
GO  

Przykłady

Używanie metody nodes() przeciwko zmiennej typu xml

W poniższym przykładzie dokument XML zawiera <Root> element najwyższego poziomu oraz trzy <row> elementy potomne. Zapytanie wykorzystuje metodę nodes() do ustawiania oddzielnych węzłów kontekstowych, po jednym dla każdego <row> elementu. Metoda nodes() zwraca zestaw wierszy z trzema wierszami. Każdy wiersz zawiera logiczną kopię oryginalnego XML, a każdy węzeł kontekstowy identyfikuje inny <row> element w oryginalnym dokumencie.

Zapytanie zwraca wtedy węzeł kontekstowy z każdego wiersza:

DECLARE @x XML   
SET @x='<Root>  
    <row id="1"><name>Larry</name><oflw>some text</oflw></row>  
    <row id="2"><name>moe</name></row>  
    <row id="3" />  
</Root>'  
SELECT T.c.query('.') AS result  
FROM   @x.nodes('/Root/row') T(c)  
GO  

W następującym przykładzie metoda zapytania zwraca element kontekstu oraz jego treść:

<row id="1"><name>Larry</name><oflw>some text</oflw></row>  
<row id="2"><name>moe</name></row>  
<row id="3"/>  

Zastosowanie nadrzędnego accessora na węzłach kontekstowych zwraca <Root> element dla wszystkich trzech:

SELECT T.c.query('..') AS result  
FROM   @x.nodes('/Root/row') T(c)  
GO  

Oto efekt:

<Root>  
    <row id="1"><name>Larry</name><oflw>some text</oflw></row>  
    <row id="2"><name>moe</name></row>  
    <row id="3" />  
</Root>  
<Root>  
    <row id="1"><name>Larry</name><oflw>some text</oflw></row>  
    <row id="2"><name>moe</name></row>  
    <row id="3" />  
</Root>  
<Root>  
    <row id="1"><name>Larry</name><oflw>some text</oflw></row>  
    <row id="2"><name>moe</name></row>  
    <row id="3" />  
</Root>  

Określenie metody nodes() względem kolumny typu xml

W tym przykładzie użyto instrukcji produkcji rowerów i jest przechowywanych w kolumnie typu xml Instructions w tabeli ProductModel .

W poniższym przykładzie metoda jest nodes() określana względem kolumny Instructions typu xml w tabeli ProductModel .

Metoda ustawia nodes()<Location>elementy jako węzły kontekstowe poprzez określenie ścieżki./MI:root/MI:Location Powstały zestaw wierszy zawiera logiczne kopie oryginalnego dokumentu, po jednej dla każdego <Location> węzła w dokumencie, z węzłem kontekstowym ustawionym na ten <Location> element. W rezultacie funkcja nodes() daje zbiór węzłów <Location> kontekstowych.

Metoda dla tego zestawu query() wierszy żąda self::node i zwraca element <Location> w każdym wierszu.

W tym przykładzie zapytanie ustawia każdy <Location> element jako węzeł kontekstowy w dokumencie instrukcji produkcji konkretnego modelu produktu. Możesz użyć tych węzłów kontekstowych do pobierania takich wartości:

  • Znajdź identyfikatory lokalizacji w każdym z nich <Location>

  • Pobieranie kroków produkcyjnych (<step> elementów potomnych) w każdym z nich <Location>

To zapytanie zwraca element kontekstowy, w którym określona jest skrócona składnia '.' dla w self::node() metodzie query() .

Należy zwrócić uwagę na następujące kwestie:

  • Metoda jest nodes() stosowana do kolumny Instrukcje i zwraca zestaw wierszy, T (C). Ten zestaw wierszy zawiera logiczne kopie oryginalnego dokumentu instrukcji produkcyjnych z /root/Location elementem kontekstu.

  • CROSS APPLY odnosi się nodes() do każdego wiersza w tabeli ProductModel i zwraca tylko te wiersze, które tworzą zbiór wyników.

    SELECT C.query('.') as result  
    FROM Production.ProductModel  
    CROSS APPLY Instructions.nodes('  
    declare namespace MI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";  
    /MI:root/MI:Location') as T(C)  
    WHERE ProductModelID=7  
    

    Oto częściowy wynik:

    <MI:Location LocationID="10"  ...>  
       <MI:step ... />  
          ...  
    </MI:Location>  
    <MI:Location LocationID="20"  ... >  
        <MI:step ... />  
          ...  
    </MI:Location>  
    ...  
    

Zastosowanie nodes() do zestawu wierszowego zwracanego przez inną metodę nodes()

Poniższy kod zapytuje dokumenty XML o instrukcje produkcyjne znajdujące się w kolumnie Instructions tabeli ProductModel . Zapytanie zwraca zestaw wierszy zawierający ID modelu produktu, lokalizacje produkcji oraz kroki produkcyjne.

Należy zwrócić uwagę na następujące kwestie:

  • Metoda jest nodes() stosowana do kolumny Instructions i zwraca zbiór T1 (Locations) wierszy. Ten zestaw wierszy zawiera logiczne kopie oryginalnego dokumentu instrukcji produkcyjnych, z elementem /root/Location jako kontekstem elementu.

  • nodes() jest stosowana do zbioru T1 (Locations) wierszy i zwraca ten zbiór T2 (steps) . Ten zestaw wierszy zawiera logiczne kopie oryginalnego dokumentu instrukcji produkcyjnych, z elementem /root/Location/step jako kontekstem elementu.

SELECT ProductModelID, Locations.value('./@LocationID','int') AS LocID,  
steps.query('.') AS Step         
FROM Production.ProductModel         
CROSS APPLY Instructions.nodes('         
declare namespace MI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";         
/MI:root/MI:Location') AS T1(Locations)         
CROSS APPLY T1.Locations.nodes('         
declare namespace MI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";         
./MI:step ') AS T2(steps)         
WHERE ProductModelID=7         
GO         

Oto efekt:

ProductModelID LocID Step         
----------------------------         
7      10   <step ... />         
7      10   <step ... />         
...         
7      20   <step ... />         
7      20   <step ... />         
7      20   <step ... />         
...         

Zapytanie ogłasza prefiks MI dwukrotnie. Zamiast tego możesz użyć WITH XMLNAMESPACES deklaracji prefiksu raz i użyć go w zapytaniu:

WITH XMLNAMESPACES (  
   'https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions' AS MI)  
  
SELECT ProductModelID, Locations.value('./@LocationID','int') AS LocID,  
steps.query('.') AS Step         
FROM Production.ProductModel         
CROSS APPLY Instructions.nodes('         
/MI:root/MI:Location') AS T1(Locations)         
CROSS APPLY T1.Locations.nodes('         
./MI:step ') as T2(steps)         
WHERE ProductModelID=7         
GO    

Zobacz też

Dodawanie przestrzeni nazw do zapytań za pomocą funkcji XMLNAMESPACES
tworzenie wystąpień danych XML
metody typów danych xml