XML w relacyjnych bazach danych
kasiaKasia
Pierwszy opracowany przez firmę IBM język strukturalizowania dokumentów, był GML (Generalized Markup Language). Składnia tego standardu stopniowo ewoluowała, dostosowując się do rosnącego za potrzebowania na rozmaitą funkcjonalność. Rozwój ten zaowocował zdefiniowaniem w 1986 roku SGML-a jako normy ISO.
SGML to profesjonalnych system zarządzania dokumentami. Ze względu na udostępniane skomplikowane opcje uproszczono w 1998 roku wprowadzono uniwersalny język formalny przeznaczony XML (Extensible Markup Language).
W środowisku relacyjnych baz danych opisane wyżej uwarunkowania spowodowały potrzebę przetwarzania dokumentów XML. Wymagało to stworzenia możliwości realizowania trzech podstawowych operacji:
- Przechowywanie dokumentów XML
- Przekształcanie danych relacyjnych do postaci XML
- Pobieranie danych z dokumentu XML.
Pierwsze funkcjonalności wspierające współpracę z dokumentów XML wprowadzono w MS SQL Server 2000 poprzez: - Funkcje OPENXML (konwertującą dokument XML do postaci tabeli relacyjnej)
- Klauzule FOR XML w poleceniu SELECT (konwertującą wynik zapytania do postaci dokumentu XML)
Klauzule FOR XML obsługuje następujące tryby: - RAW
- AUTO
- EXPLICIT
- PATH
Wymienione mechanizmy zostaną omówione na podstawie przykładów, przy zastosowaniu tabel:
[Tabela: Osoby2]
IdOsoby | Nazwisko | Imie | DataUrodzenia | CzyKobieta | Pesel | IdMiasta | Znacznik | plec | wiek | nic |
---|---|---|---|---|---|---|---|---|---|---|
45 | Kot | Janina | 1985-07-29 | 1 | 85072911986 | 1 | 0x00000000000007FD | Kobieta | 27 | NULL |
46 | Kot | Jan | 1983-03-12 | 1 | 83031234501 | 2 | 0x00000000000007FE | Kobieta | 29 | NULL |
47 | Kret | Zosia | 1983-03-15 | 1 | 83031534581 | 2 | 0x00000000000007FF | Kobieta | 29 | NULL |
74 | Piasek | Zosia | 1987-04-29 | 1 | 87042945367 | 8 | 0x000000000000081E | Kobieta | 25 | NULL |
75 | Piasek | Zosia | 1987-04-29 | 1 | 87042945367 | 8 | 0x000000000000081F | Kobieta | 25 | NULL |
76 | Piasek | Zosia | 1987-04-29 | 1 | 87042945367 | 8 | 0x0000000000000820 | Kobieta | 25 | NULL |
77 | Piasek | Zosia | 1987-04-29 | 1 | 87042945367 | 8 | 0x0000000000000821 | Kobieta | 25 | NULL |
79 | Zajac | Helena | 1977-09-09 | 1 | 77090934567 | 1 | 0x0000000000000823 | Kobieta | 35 | NULL |
81 | Zaajac | Helena | 1977-09-09 | 1 | 77090934567 | 2 | 0x0000000000000825 | Kobieta | 35 | NULL |
82 | Krolik | Jan | 1988-08-08 | 0 | 88080834556 | 9 | 0x0000000000000826 | Mężczyzna | 24 | NULL |
83 | Krolik | Jan | 1988-08-08 | 0 | 88080834556 | 9 | 0x0000000000000827 | Mężczyzna | 24 | NULL |
84 | Jenot | Janina | 1988-08-08 | 1 | 88080834546 | 10 | 0x0000000000000828 | Kobieta | 24 | NULL |
[Tabela: Miasta]
IdMiasta | Nazwa |
---|---|
2 | Dęblin |
6 | Kielce |
9 | Kolobrzeg |
10 | Lublin |
8 | nowe miasto nad Pilica |
4 | Opole |
3 | Sopot |
1 | Warszawa |
[Tabela: kategorie]
id | higher_id | Name | Sequence |
---|---|---|---|
1 | 0 | Samochod | 1 |
2 | 0 | Kemping | 2 |
3 | 1 | Fiat | 1 |
4 | 1 | Skoda | 2 |
7 | 3 | 2 | |
5 | 1 | Audi | 3 |
6 | 2 | Krotka | 1 |
[Tabela: Klasy]
idklasy | Nazwa | RokSzkolny | cos |
---|---|---|---|
1 | Ia | 2011/2012 | sshhhdgguu |
2 | IIa | 2011/2012 | sshhhdgguu |
3 | IIc | 2011/2012 | sshhhdgguu |
4 | IVb | 2011/2012 | sshhhdgguu |
5 | IId | 2011/2012 | sshhhdgguu |
6 | Va | 2011/2012 | sshhhdgguu |
13 | Ic | 2011/2012 | sshhhdgguu |
14 | VIa | 2011/2012 | sshhhdgguu |
15 | VIa | 2011/2012 | sshhhdgguu |
16 | Vb | 2011/2012 | sshhhdgguu |
18 | Vc | 2011/2012 | sshhhdgguu |
20 | Vd | 2012/2012 | sshhhdgguu |
21 | Ve | 2012/2012 | sshhhdgguu |
22 | Vf | 2012/2012 | sshhhdgguu |
23 | Vg | 2012/2012 | sshhhdgguu |
24 | IIe | 2012/2012 | sshhhdgguu |
[Tabela: Uczniowie]
iducznia | Nazwisko | Imie | DataUrodzenia | CzyChlopak | Pesel | idklasy |
---|---|---|---|---|---|---|
1 | InnyGość | NULL | 1410-07-14 | 0 | 10071451147 | 2 |
3 | Gazela | Basia | 1992-02-22 | 0 | 92022277654 | 2 |
4 | Kurka | Jola | 1992-06-02 | 0 | 92060288788 | 2 |
5 | Gąska | Wacek | 1991-03-11 | 1 | 91031199123 | 1 |
6 | Krówka | Rysio | 1992-05-15 | 1 | 92051577646 | 1 |
7 | Zebra | Wojtek | 1993-03-13 | 1 | 93030399846 | 1 |
8 | Gazela | Basia | 1992-11-11 | 0 | 92111177446 | 2 |
9 | Sarenka | Rysio | 1992-12-12 | 0 | 92121278766 | 3 |
10 | Konik | Kasia | 1993-03-12 | 0 | 93031275446 | 2 |
11 | Ryba | Jan | 1993-05-15 | 1 | 93051587746 | 2 |
12 | Kura | Kasia | 1993-02-22 | 0 | 93022277654 | 2 |
13 | Łoś | Jola | 1993-06-02 | 0 | 93060288788 | 2 |
14 | Miś | Wacek | 1993-03-11 | 1 | 93031199123 | 4 |
15 | Okoń | Rysio | 1993-05-15 | 1 | 93051577646 | 4 |
16 | Płotka | Wojtek | 1993-03-13 | 1 | 93030399846 | 2 |
17 | Różyczka | Basia | 1993-11-11 | 0 | 93111177446 | 2 |
18 | Stokrotka | Rysio | 1993-12-12 | 0 | 93121278766 | 2 |
19 | Wilczek | Jasio | 1999-12-12 | 0 | 99121209876 | 3 |
- RAW **
Użycie jednego z podstawowych trybów znajduje się w poniższym przykładzie.
Przykład 1)
SELECT TOP 3 Nazwisko,
Imie,
CASE CzyKobieta
WHEN 0 THEN 'Mężczyzna'
ELSE 'Kobieta'
END AS Plec
FROM Osoby2
FOR XML RAW
Wynik zapytania wygenerował jedną kolumnę z jednym wierszem. Jako odnośnik do dokumentu XML. Po kliknięciu zostaje otwarte nowe okno z danymi umieszczonymi w atrybutach. Należy zwrócić uwagę, że nie pojawił się element główny, jedynie rekordy zostały objęte w znaczniku *row *jako atrybuty.
<row Nazwisko="Kot" Imie="Janina" Plec="Kobieta" />
<row Nazwisko="Kot" Imie="Jan" Plec="Kobieta" />
<row Nazwisko="Kret" Imie="Zosia" Plec="Kobieta" />
Przykład 2)
Do trybu RAW można zdefiniować parametr, a także zdefiniowanie znacznika głównego korzystając z opcji ROOT . Drugi przykład przedstawiła te mechanizmy:
SELECT TOP 3 Nazwisko,
Imie,
CASE CzyKobieta
WHEN 0 THEN 'Mężczyzna'
ELSE 'Kobieta'
END AS Plec
FROM Osoby2
FOR XML RAW('osoba') , ROOT
Ponownie zostaje wygenerowana kolumna z jednym polem, jako odnośnik do dokumentu. W momencie jego użycia tak, jak w poprzednim przykładzie otwiera się nowe okno. Gdzie
wynik wygenerował dodatkowo znacznik główny jako <root> , zwrócony dokument XML jest poprawnie sformułowany. Wprowadzony parametr do trybu RAW('osoba') modyfikuje nazwę znacznika w którym są wyświetlone rekordy pobrane z tabeli:
<root>
<osoba Nazwisko="Kot" Imie="Janina" Plec="Kobieta" />
<osoba Nazwisko="Kot" Imie="Jan" Plec="Kobieta" />
<osoba Nazwisko="Kret" Imie="Zosia" Plec="Kobieta" />
</root>
Przykład 3)
Dla ROOT można podać także z parametrem , do poniższego przykłądu również dopisano opcje ELEMENTS. Poższysze zapytanie SQL:
SELECT TOP 3 Nazwisko,
Imie,
CASE CzyKobieta
WHEN 0 THEN 'Mężczyzna'
ELSE 'Kobieta'
END AS Plec
FROM osoby
FOR XML RAW('osoba'), ROOT('ListaOsob'), ELEMENTS
Powyższe zapytanie SQL, zwraca określony znacznik główny * <ListaOsob> *. Zawarty w nim znacznik * <osoba> * zawiera zestawy elementów podrzędnych. Odpowiada za to opcja * ELEMENTS * powodująca, że zamiast atrybutów, do umieszczenia zawartości kolumn wykorzystane są elementy, które odpowiadają nazwom kolumn objętych instrukcją SQL. Wartości nie są już objęte jako atrybuty:
<ListaOsob>
<osoba>
<Nazwisko>Kot</Nazwisko>
<Imie>Janina</Imie>
<Plec>Kobieta</Plec>
</osoba>
<osoba>
<Nazwisko>Kot</Nazwisko>
<Imie>Jan</Imie>
<Plec>Kobieta</Plec>
</osoba>
<osoba>
<Nazwisko>Kret</Nazwisko>
<Imie>Zosia</Imie>
<Plec>Kobieta</Plec>
</osoba>
</ListaOsob>
Przykład 4)
Korzystając z nowej tabeli *kategorie * w zapytaniu poniżej zmodyfikowano RAW('kategorie') , opcje ROOT('ListaKategorie') dodano również ELEMENTS XSINIL , XMLSCHEMA :
SELECT id,
higher_id,
Name,
sequence
FROM kategorie
FOR XML RAW('kategorie'), ROOT('ListaKategorie'), ELEMENTS XSINIL,XMLSCHEMA
W momecie klikniecia w nowym oknie, powyższy przykład zawierający ELEMENTS XSINIL powoduje dodanie argumentu do gównego znacznika *xmlns:xsi=http:*www.w3.org/2001/XMLSchema-instance// Dla wartości zawierających NULL powoduje dodanie atrybutu xsi: nil = "true" .
Zapytanie SQL posiada również, dyrekywę *XMLSCHEMA * , którą można wykonać jedynie dla trybów RAW lub AUTO. Dodanie do znaczników pseudo-atrybutów XML namespace, standardu służącego do definiowania struktury dokumentu XML. Deklaracja przestrzeni nazw ma następującą składnię:
xmlns: prefix = "URI".
Gdzie Uniform Resource Identifier (URI) to ciąg znaków, który identyfikuje zasob sieci Internet.
Kiedy przestrzeń nazw jest definiowana dla danego elementu, wszystkie elementy podrzędne z tego samego prefiksu związane są z tą samą przestrzenią nazw.
W powyższym przykładzie atrybut * xmlns * w znaczniku <kategorie> posiada prefiksy xsd.
<ListaKategorie xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsd:schema targetNamespace="urn:schemas-microsoft-com:sql:SqlRowSet2" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:sqltypes="http://schemas.microsoft.com/sqlserver/2004/sqltypes" elementFormDefault="qualified">
<xsd:import namespace="http://schemas.microsoft.com/sqlserver/2004/sqltypes" schemaLocation="http://schemas.microsoft.com/sqlserver/2004/sqltypes/sqltypes.xsd" />
<xsd:element name="kategorie">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="id" type="sqltypes:int" nillable="1" />
<xsd:element name="higher_id" type="sqltypes:int" nillable="1" />
<xsd:element name="Name" nillable="1">
<xsd:simpleType>
<xsd:restriction base="sqltypes:nchar" sqltypes:localeId="1045" sqltypes:sqlCompareOptions="IgnoreCase IgnoreKanaType IgnoreWidth">
<xsd:maxLength value="10" />
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="sequence" type="sqltypes:int" nillable="1" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<kategorie xmlns="urn:schemas-microsoft-com:sql:SqlRowSet2">
<id>1</id>
<higher_id>0</higher_id>
<Name>Samochod </Name>
<sequence>1</sequence>
</kategorie>
<kategorie xmlns="urn:schemas-microsoft-com:sql:SqlRowSet2">
<id>2</id>
<higher_id>0</higher_id>
<Name>Kemping </Name>
<sequence>2</sequence>
</kategorie>
<kategorie xmlns="urn:schemas-microsoft-com:sql:SqlRowSet2">
<id>3</id>
<higher_id>1</higher_id>
<Name>Fiat </Name>
<sequence>1</sequence>
</kategorie>
<kategorie xmlns="urn:schemas-microsoft-com:sql:SqlRowSet2">
<id>4</id>
<higher_id>1</higher_id>
<Name>Skoda </Name>
<sequence>2</sequence>
</kategorie>
<kategorie xmlns="urn:schemas-microsoft-com:sql:SqlRowSet2">
<id>7</id>
<higher_id>3</higher_id>
<Name> </Name>
<sequence>2</sequence>
</kategorie>
<kategorie xmlns="urn:schemas-microsoft-com:sql:SqlRowSet2">
<id>5</id>
<higher_id>1</higher_id>
<Name>Audi </Name>
<sequence>3</sequence>
</kategorie>
<kategorie xmlns="urn:schemas-microsoft-com:sql:SqlRowSet2">
<id>6</id>
<higher_id>2</higher_id>
<Name>Krotka </Name>
<sequence>1</sequence>
</kategorie>
</ListaKategorie>
Przykład 5)
Ostatnie zapytanie SQL zawiera dodatkowo dyrektywę z parametrem XMLSCHEMA('urn: XMLSCHEMA.com') :
SELECT id,
higher_id,
Name,
sequence
FROM kategorie
FOR XML RAW('kategorie'), ROOT('ListaKategorie'), ELEMENTS XSINIL, XMLSCHEMA('urn:XMLSCHEMA.pl')
Wynik zwraca odnośnik w postaci tabeli. Po uruchomieniu , utworzony dokument XML przedstawiła się następująco:
<ListaKategorie xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsd:schema targetNamespace="urn:XMLSCHEMA.pl" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:sqltypes="http://schemas.microsoft.com/sqlserver/2004/sqltypes" elementFormDefault="qualified">
<xsd:import namespace="http://schemas.microsoft.com/sqlserver/2004/sqltypes" schemaLocation="http://schemas.microsoft.com/sqlserver/2004/sqltypes/sqltypes.xsd" />
<xsd:element name="kategorie">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="id" type="sqltypes:int" nillable="1" />
<xsd:element name="higher_id" type="sqltypes:int" nillable="1" />
<xsd:element name="Name" nillable="1">
<xsd:simpleType>
<xsd:restriction base="sqltypes:nchar" sqltypes:localeId="1045" sqltypes:sqlCompareOptions="IgnoreCase IgnoreKanaType IgnoreWidth">
<xsd:maxLength value="10" />
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="sequence" type="sqltypes:int" nillable="1" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<kategorie xmlns="urn:XMLSCHEMA.pl">
<id>1</id>
<higher_id>0</higher_id>
<Name>Samochod </Name>
<sequence>1</sequence>
</kategorie>
<kategorie xmlns="urn:XMLSCHEMA.pl">
<id>2</id>
<higher_id>0</higher_id>
<Name>Kemping </Name>
<sequence>2</sequence>
</kategorie>
<kategorie xmlns="urn:XMLSCHEMA.pl">
<id>3</id>
<higher_id>1</higher_id>
<Name>Fiat </Name>
<sequence>1</sequence>
</kategorie>
<kategorie xmlns="urn:XMLSCHEMA.pl">
<id>4</id>
<higher_id>1</higher_id>
<Name>Skoda </Name>
<sequence>2</sequence>
</kategorie>
<kategorie xmlns="urn:XMLSCHEMA.pl">
<id>7</id>
<higher_id>3</higher_id>
<Name> </Name>
<sequence>2</sequence>
</kategorie>
<kategorie xmlns="urn:XMLSCHEMA.pl">
<id>5</id>
<higher_id>1</higher_id>
<Name>Audi </Name>
<sequence>3</sequence>
</kategorie>
<kategorie xmlns="urn:XMLSCHEMA.pl">
<id>6</id>
<higher_id>2</higher_id>
<Name>Krotka </Name>
<sequence>1</sequence>
</kategorie>
</ListaKategorie>
Wynik zwróci te same dane jak z przykładu 4, wyłącznie będzie różnić się pseudo-arybutem xmlns="urn:XMLSCHEMA.pl" Nazwa deklaracja musi spełniać kryteria przestrzeni nazw (ang. Namespace name).
AUTO
Tryb AUTO jest nieco zbliżony do RAW, z tą różnicą, że potrafi budować proste hierarchie w dokumencie XML. Domyślnie generuje nazwę znacznika, taką samą jak nazwa tabeli, a atrybuty są identyczne jak nazwy kolumn. Ponadto obsługuje wszystkie opcje omawiane przy FOR XML RAW. Warto kilka tych informacji przeanalizować na podstawie kilku przykładów:
Przykład 1)
SELECT TOP 3 Os.Nazwisko,Os.IdOsoby,
Mi.Nazwa
FROM Osoby2 AS Os
INNER JOIN Miasta AS Mi
ON Os.IdMiasta = Mi.IdMiasta
FOR XML AUTO, ROOT('Osoby')
Wyżej wymienione zapytanie SQL, zwraca kolumnę z jednym rekordem jako odnośnik do pliku XML. Gdy użytkownik kliknie na link, otwiera się nowe okno z rekordami zawartymi w instrukcji:
<Osoby>
<Os Nazwisko="Kot" IdOsoby="46">
<Mi Nazwa="Dęblin" />
</Os>
<Os Nazwisko="Kret" IdOsoby="47">
<Mi Nazwa="Dęblin" />
</Os>
<Os Nazwisko="Zaajac" IdOsoby="81">
<Mi Nazwa="Dęblin" />
</Os>
</Osoby>
Pierwszy znacznik jest określony przez klauzurę ROOT('Osoby') . Jeśli nie będzie ona zawarta, wynik będzie reprezentował się bez tego znacznika, a jeśli wyłącznie z *ROOT * zostanie automatycznie dodany główny znacznik * <root> * Wewnątrz jego uporządkowanie wyświetlonych znaczników, jest uszeregowane według kolejności podanych nazw tabel w zapytaniu SQL. Nazwy znaczników odpowiadają aliansom nazw tabel podanych w klauzurze FROM . Atrybuty wyświetlone w znaczniku również odpowiadają kolejności wystąpienia w zapytaniu SQL.
Przykład 2)
SELECT TOP 3 Mi.Nazwa, Os.Nazwisko, Os.IdOsoby
FROM Miasta AS Mi
INNER JOIN Osoby2 AS Os
ON Mi.IdMiasta = Os.IdMiasta
FOR XML AUTO, ROOT('Osoby'), ELEMENTS XSINIL
Po uruchomieniu odnośnika do dokumentu XML, zostają wyświetlone dane w następujący sposób:
<Osoby xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Mi>
<Nazwa>Dęblin</Nazwa>
<Os>
<Nazwisko>Kot</Nazwisko>
<IdOsoby>46</IdOsoby>
</Os>
<Os>
<Nazwisko>Kret</Nazwisko>
<IdOsoby>47</IdOsoby>
</Os>
<Os>
<Nazwisko>Zaajac</Nazwisko>
<IdOsoby>81</IdOsoby>
</Os>
</Mi>
</Osoby>
Zestaw wartości kolumn są teraz uwzględnione jako elementy podrzędne, a nie atrybuty. Dołączenie do elementu znacznika atrybutu xsi:nil="true" dla rekordu o wartości NULL , jest możliwe przez dodanie *XSINIL * do opcji ELEMENTS . Dla głównego znacznika został dodany dodatkowo atrybut * xmlns: xsi xmlns:xsi="http:*www.w3.org/2001/XMLSchema-instance" //
Przykład 3)
SELECT TOP 3 Mi.Nazwa, Os.Nazwisko, Os.IdOsoby
FROM Miasta AS Mi
INNER JOIN Osoby2 AS Os
ON Mi.IdMiasta = Os.IdMiasta
FOR XML AUTO, ROOT('Osoby'),ELEMENTS , XMLSCHEMA('urn:XMLSCHEMA.pl');
Zapytanie generuje tabele, z zawartością odnośnika. Gdy użytkownik kliknie na niego pojawia się zawartość dokumentu XML w nowym oknie prezentująca się następująco:
<Osoby>
<xsd:schema targetNamespace="urn:XMLSCHEMA.pl" xmlns:schema="urn:XMLSCHEMA.pl" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:sqltypes="http://schemas.microsoft.com/sqlserver/2004/sqltypes" elementFormDefault="qualified">
<xsd:import namespace="http://schemas.microsoft.com/sqlserver/2004/sqltypes" schemaLocation="http://schemas.microsoft.com/sqlserver/2004/sqltypes/sqltypes.xsd" />
<xsd:element name="Mi">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Nazwa">
<xsd:simpleType>
<xsd:restriction base="sqltypes:varchar" sqltypes:localeId="1045" sqltypes:sqlCompareOptions="IgnoreCase IgnoreKanaType IgnoreWidth">
<xsd:maxLength value="50" />
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element ref="schema:Os" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="Os">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Nazwisko">
<xsd:simpleType>
<xsd:restriction base="sqltypes:varchar" sqltypes:localeId="1045" sqltypes:sqlCompareOptions="IgnoreCase IgnoreKanaType IgnoreWidth">
<xsd:maxLength value="50" />
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="IdOsoby" type="sqltypes:int" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<Mi xmlns="urn:XMLSCHEMA.pl">
<Nazwa>Dęblin</Nazwa>
<Os>
<Nazwisko>Kot</Nazwisko>
<IdOsoby>46</IdOsoby>
</Os>
<Os>
<Nazwisko>Kret</Nazwisko>
<IdOsoby>47</IdOsoby>
</Os>
<Os>
<Nazwisko>Zaajac</Nazwisko>
<IdOsoby>81</IdOsoby>
</Os>
</Mi>
</Osoby>
Wynik ma podobną strukturę jak dokument XML z przykładu 4 dla trybu RAW. Wyświetlenie zawartości danych pozostaje identyczne jak w przykładzie 2 z trybu AUTO. Zmieniony zostaje jedynie atrybut dla każdego pierwszego znacznika w jego obrębie, nie będącym głównym. Dodane zostają również znaczniki informujące o referencji:
<xsd:element ref="schema:Os" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="Os">
<xsd:complexType>
<xsd:sequence>
do tabeli oznaczonej w tym przykładzie aliansem Os . Gdy opcja XMLSCHEMA jest bez parameru zosatje wygenreowany arybut *<Mi xmlns="urn:schemas-microsoft-com:sql:SqlRowSet9"> * , ustalony w analizowanym przykładzie.
EXPLICIT
EXPLICIT ma ściśle określone wymagania co do postaci zbioru wynikowego, który ma być przekształcony na postać dokumentu XML. W klauzuli SELECT pierwsza kolumna musi być nazwana jako Tag . Z kolei druga kolumna posiada nazwę Parent .Tag oraz Parent są liczbami typu całkowitego.
Przykład 1)
Zapytanie SQL składa się z dwóch zapytań SELECT połączonych operatorem UNION ALL.
SELECT TOP 5
1 AS Tag,
NULL AS Parent,
u.iducznia AS [uczniowie!1!UczniowieIducznia!ELEMENT],
NULL AS [uczniowie!2!Nazwisko!ELEMENT],
NULL AS [uczniowie!2!Imie!ELEMENT]
from Klasy k JOIN Uczniowie u
ON u.idklasy = k.idklasy
UNION ALL
SELECT TOP 5
2 AS Tag,
1 AS Parent,
k.idklasy,
k.RokSzkolny,
k.Nazwa
from Klasy k JOIN Uczniowie u
ON u.idklasy = k.idklasy
FOR XML EXPLICIT;
Wynik wykonania zapytania, tym razem z klauzulą FOR XML EXPLICIT, zawiera dokument XML o strukturze zaplanowanej przy tworzeniu zapytania.
<uczniowie>
<UczniowieIducznia>5</UczniowieIducznia>
</uczniowie>
<uczniowie>
<UczniowieIducznia>6</UczniowieIducznia>
</uczniowie>
<uczniowie>
<UczniowieIducznia>7</UczniowieIducznia>
</uczniowie>
<uczniowie>
<UczniowieIducznia>8</UczniowieIducznia>
</uczniowie>
<uczniowie>
<UczniowieIducznia>9</UczniowieIducznia>
<uczniowie>
<Nazwisko>2011/2012</Nazwisko>
<Imie>Ia</Imie>
</uczniowie>
<uczniowie>
<Nazwisko>2011/2012</Nazwisko>
<Imie>Ia</Imie>
</uczniowie>
<uczniowie>
<Nazwisko>2011/2012</Nazwisko>
<Imie>Ia</Imie>
</uczniowie>
<uczniowie>
<Nazwisko>2011/2012</Nazwisko>
<Imie>IIa</Imie>
</uczniowie>
<uczniowie>
<Nazwisko>2011/2012</Nazwisko>
<Imie>IIc</Imie>
</uczniowie>
</uczniowie>
Bez klauzury FOR XML EXPLICIT:
SELECT TOP 5
1 AS Tag,
NULL AS Parent,
u.iducznia AS [uczniowie!1!UczniowieIducznia!ELEMENT],
NULL AS [uczniowie!2!Nazwisko!ELEMENT],
NULL AS [uczniowie!2!Imie!ELEMENT]
from Klasy k JOIN Uczniowie u
ON u.idklasy = k.idklasy
UNION ALL
SELECT TOP 5
2 AS Tag,
1 AS Parent,
k.idklasy,
k.RokSzkolny,
k.Nazwa
from Klasy k JOIN Uczniowie u
ON u.idklasy = k.idklasy;
Wynik będzie przedstawiła się następująco:
Tag | Parent | uczniowie!1!UczniowieIducznia!ELEMENT | uczniowie!2!Nazwisko!ELEMENT | uczniowie!2!Imie!ELEMENT |
---|---|---|---|---|
1 | NULL | 5 | NULL | NULL |
1 | NULL | 6 | NULL | NULL |
1 | NULL | 7 | NULL | NULL |
1 | NULL | 8 | NULL | NULL |
1 | NULL | 9 | NULL | NULL |
2 | 1 | 1 | 2011/2012 | Ia |
2 | 1 | 1 | 2011/2012 | Ia |
2 | 1 | 1 | 2011/2012 | Ia |
2 | 1 | 1 | 2011/2012 | IIa |
2 | 1 | 1 | 2011/2012 | IIc |
Wynik kolumn Tag i Parent, przedstawia informacje dotyczące hierarchii. W pierwszym select będą dwie pierwsze kolumny zawsze implementowane w następującej postaci: |
[rodzic_wartość],
[NULL],
Drugi select również będzie miał następującą składnie:
[dziecko_wartość],
[rodzic_wartość],
Nie jest konieczne dodanie aliansu AS . Jednak w naszym przykładzie zostało to zastosowane. W pozostałych kolumnach zostaną wprowadzone wartości NULL .
Każdy rekord otrzymuje swój numer Tag oraz numer Parent. Numery te decydują, gdzie zostaną umieszczone dane z poszczególnych wierszy. Wartość 0 lub *NULL *dla kolumny Parent wskazują, że odpowiadający element nie posiada rodzica.
PATH
Pomaga w przedstawieniu dokumentu XML. Umieszczenie identyfikatorów jako atrybuty oraz pozostałe wartości przedstwia poniższe zapytanie SQL:
SELECT
[@kasiaKasia].[dbo].[Osoby2].[IdOsoby] 'IdOsoby',
[@kasiaKasia].[dbo].[Osoby2].[Nazwisko] 'Osoby/@Nazwisko',
[@kasiaKasia].[dbo].[Osoby2].[Imie] 'Osoby/@Imie',
[@kasiaKasia].[dbo].[Osoby2].[DataUrodzenia] 'Osoby/@DataUrodzenia',
[@kasiaKasia].[dbo].[Miasta].[IdMiasta] 'Id_Miasta',
[@kasiaKasia].[dbo].[Miasta].[Nazwa] 'Miasta/@Nazwa',
[@kasiaKasia].[dbo].[Miasta].[IdMiasta] 'Miasta/@IdMiasta'
FROM [@kasiaKasia].[dbo].[Miasta]
JOIN [@kasiaKasia].[dbo].[Osoby2] ON [@kasiaKasia].[dbo].[Osoby2].[IdMiasta] = [@kasiaKasia].[dbo].[Miasta].[IdMiasta]
FOR XML PATH('Osoby')
Z powyższego zapytania zostanie wygenerowany link do dokumentu XML, po jego uruchomieniu plik XML , przestawia się w następujący wsposób:
<Osoby>
<IdOsoby>46</IdOsoby>
<Osoby Nazwisko="Kot" Imie="Jan" DataUrodzenia="1983-03-12" />
<Id_Miasta>2</Id_Miasta>
<Miasta Nazwa="Dęblin" IdMiasta="2" />
</Osoby>
<Osoby>
<IdOsoby>47</IdOsoby>
<Osoby Nazwisko="Kret" Imie="Zosia" DataUrodzenia="1983-03-15" />
<Id_Miasta>2</Id_Miasta>
<Miasta Nazwa="Dęblin" IdMiasta="2" />
</Osoby>
<Osoby>
<IdOsoby>81</IdOsoby>
<Osoby Nazwisko="Zaajac" Imie="Helena" DataUrodzenia="1977-09-09" />
<Id_Miasta>2</Id_Miasta>
<Miasta Nazwa="Dęblin" IdMiasta="2" />
</Osoby>
Dokument XML przedstawiła elementy <Osoby> Dla każdego z nich są wyświetlony rekord osoby. Zastosowanie @ prowadzi do wypisania atrybutów, zgodnie z nazwą kolumn. Umieszczenie nowego węzła można uzyskać poprzez wprowadzenie '/'. Nazwa atrybutu podaję się w cudy słowniach, nie jest konieczne wprowadzanie identycznych jak nazwy kolumn.
Typ danych XML zawiera pięć metod, które mają za zadanie manipulować zawartością dokumentu XML oraz modyfikować dokument. Dodatkowo dają one możliwość wykonania operacji odwrotnej do działania klauzuli FOR XML – czyli do przetransformowania danych z XML w wiersz zbioru wyników (rowset).
Wyrażenia metod zbudowane są oparte o podstawy języka XQuery oraz XPath:
Value - zwraca wskazana wartość skalarną (zawartość atrybutu lub elementu)
Query - zwraca wskazany XML
Exists - zwraca wartość logiczną określająca czy wskazany element istnieje w dokumencie XML
Nodes - zwraca wskazane węzły dokumenty XML
Modify - umożliwia operacje modyfikacji dokumentu XML