Právě jsem zveřejnil patch od Pavla Stěhuleho, který přidává XMLTABLE funkčnost do PostgreSQL 10. XMLTABLE je velmi užitečná funkce diktovaná standardem SQL/XML, která vám umožňuje převést data XML do relační podoby, abyste je mohli smíchat se zbytkem relačních dat. Tato funkce má mnoho využití; Pokračujte ve čtení pro některé podrobnosti.
Pravděpodobně nejzajímavější případ použití XMLTABLE je extrahovat data z nějakého dokumentu XML a vložit je do relační tabulky během zpracování ETL v databázi. Nicméně XMLTABLE lze za běhu použít na data uložená ve sloupcích XML, takže jakmile budou data v relační formě, můžete použít libovolné standardní operace, jako je přidání KAM klauzule, provádění agregací, připojování k jiným tabulkám a tak dále.
Jednoduchý příklad
Předpokládejme například, že spravujete hotelový řetězec a že data jsou uložena takto:
CREATE TABLE hoteldata AS SELECT xml
$$<hotels>
<hotel id="mancha">
<name>La Mancha</name>
<rooms>
<room id="201"><capacity>3</capacity><comment>Great view of the Channel</comment></room>
<room id="202"><capacity>5</capacity></room>
</rooms>
<personnel>
<person id="1025">
<name>Ferdinando Quijana</name><salary currency="PTA">45000</salary>
</person>
</personnel>
</hotel>
<hotel id="valpo">
<name>Valparaíso</name>
<rooms>
<room id="201"><capacity>2</capacity><comment>Very noisy</comment></room>
<room id="202"><capacity>2</capacity></room>
</rooms>
<personnel>
<person id="1026"><name>Katharina Wuntz</name><salary currency="EUR">50000</salary></person>
<person id="1027"><name>Diego Velázquez</name><salary currency="CLP">1200000</salary></person>
</personnel>
</hotel>
</hotels>$$ AS hotels;
Pomocí XMLTABLE , můžete to přeměnit na relačně formátovanou tabulku sestávající z číslí pokojů a kapacity s poznámkami pro každý hotel ve vašem řetězci:
SELECT xmltable.*
FROM hoteldata,
XMLTABLE ('/hotels/hotel/rooms/room' PASSING hotels
COLUMNS
id FOR ORDINALITY,
hotel_name text PATH '../../name' NOT NULL,
room_id int PATH '@id' NOT NULL,
capacity int,
comment text PATH 'comment' DEFAULT 'A regular room'
);
id | název_hotelu | id_místnosti | kapacita | komentář |
---|---|---|---|---|
1 | La Mancha | 201 | 3 | Skvělý pohled na kanál |
2 | La Mancha | 202 | 5 | Běžná místnost |
3 | Valparaíso | 201 | 2 | Velmi hlučné |
4 | Valparaíso | 202 | 2 | Běžná místnost |
Vysvětlení syntaxe
Pojďme si prostudovat výše uvedený dotaz. XMLTABLE klauzule musí být v FROM část dotazu. Máme také hotelová data v OD , což je to, co dodává data do XMLTABLE .
Nejprve PASSING klauzule je místo, kde specifikujeme data XML, která chceme zpracovat. V tomto případě data pocházejí z hotelů ve sloupci hoteldata stůl. Říkáme tomu výraz dokumentu .
Těsně před PASSING klauzule vidíte výraz XPath '/hotels/hotel/rooms/room' . Říkáme tomu výraz generující řádek nebo jen řádkový výraz .
Máme SLOUPCE klauzule další, deklarující několik sloupců. Pro každý sloupec uvádíme typ dat a také volitelnou PATH klauzuli, kterou nazýváme sloupcový výraz .
XMLTABLE Operační teorie spočívá v tom, že řádkový výraz se aplikuje na výraz dokumentu a rozdělí dokument na kousky, aby se vygenerovaly řádky; pro každý takto vygenerovaný řádek jsou použity různé sloupcové výrazy k získání hodnot pro každý sloupec.
Sloupcový výraz je výraz XPath, který získává hodnotu začínající z XML pro aktuální řádek. Pokud není PATH je zadán, pak se jako výraz XPath použije samotný název sloupce. Všimněte si, že ve sloupci název_hotelu použili jsme cestu s „../ “, což znamená „jít nahoru“ v dokumentu XML a získat hodnoty z objektů „kontejner“ v dokumentu. Můžeme také použít xml PATH '.' v řádku, což nám poskytuje úplný zdrojový kód XML pro daný řádek.
Jeden sloupec může být označen jako PRO ORDINALITA . Sloupec je pak typu INTEGER a je očíslován postupně pro každý řádek získaný z dokumentu. (Pokud existuje více vstupních dokumentů, například když máte v tabulce více řádků, počítadlo začíná od 1 pro každý nový dokument.
K dispozici je také VÝCHOZÍ doložka. Pokud XPath pro sloupec neodpovídá hodnotě pro určitý řádek, pak DEFAULT je použita hodnota.
Některé z těchto sloupců byly označeny jako NOT NULL . Pokud neexistuje žádná shoda a žádné DEFAULT je specifikována klauzule (nebo DEFAULT také vyhodnotí jako NULL ), dojde k chybě.
Nebudu se podrobněji zabývat XPath, což je mocný jazyk, ale jako užitečné zdroje mohu nabídnout článek o XPath na Wikipedii a dokument s oficiálním doporučením od W3C.
Úplná syntaxe XMLTABLE
Dokumentovaná synopse syntaxe je:
xmltable
( [XMLNAMESPACES(namespace uri
ASnamespace name
[, ...])]row_expression
PASSING [BY REF]document_expression
[BY REF] COLUMNSname
{type
[PATHcolumn_expression
] [DEFAULTexpr
] [NOT NULL | NULL] | FOR ORDINALITY } [, ...] )
Všimněte si, že výraz dokumentu může být odkazem na nějakou tabulku, kterou máte v klauzuli FROM, nebo to může být úplný dokument XML jako řetězcový literál. Klauzule BY REF nemají žádný účinek; jsou zde kvůli kompatibilitě se standardem as jinými databázovými systémy.
Nepokryl jsem XMLNAMESPACES klauzule v tomto příspěvku; To nechávám na budoucí splátku.
Použití SQL nahoře
Jak již bylo zmíněno, jakmile XMLTABLE zpracuje data do relační formy, můžete pomocí známých nástrojů dělat, co chcete. Pokud jste například měli jiný dokument XML s více zaměstnanci v každém hotelu,
INSERT INTO hoteldata VALUES (xml $$<hotels> <hotel id="mancha"> <name>La Mancha</name> <personnel> <person id="1028"> <name>Sancho Panza</name><salary currency="PTA">35000</salary> </person> </personnel> </hotel> <hotel id="valpo"> <name>Valparaíso</name> <personnel> <person id="1029"><name>Kurt Werner</name><salary currency="EUR">30000</salary></person> </personnel> </hotel> </hotels>$$);
Je snadné získat celkové platy pro každou měnu, kterou musíte zaplatit v každém hotelu,
SELECT hotel, currency, sum(salary) FROM hoteldata, XMLTABLE ('/hotels/hotel/personnel/person' PASSING hotels COLUMNS hotel text PATH '../../name' NOT NULL, salary integer PATH 'salary' NOT NULL, currency text PATH 'salary/@currency' NOT NULL ) GROUP BY hotel, currency;
hotel | měna | součet |
---|---|---|
Valparaíso | CLP | 1200000 |
Valparaíso | EUR | 80 000 |
La Mancha | PTA | 80 000 |
Závěr
V tomto článku jsem se zabýval novou funkcí XMLTABLE se objeví v PostgreSQL verze 10. Myslím, že XMLTABLE je skvělá funkce pro integraci externích dat a doufám, že i pro vás bude cenná. Prosím otestujte a nahlaste případné problémy, abychom je mohli vyřešit před konečným vydáním. Pokud máte rádi XMLTABLE , nezapomeňte nám dát vědět zanecháním komentáře!