PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

XMLTABLE в PostgreSQL

Току-що поставих пач от Павел Стюле, който добавя XMLTABLE функционалност към PostgreSQL 10.  XMLTABLE е много полезна функция, продиктувана от стандарта SQL/XML, която ви позволява да превърнете вашите XML данни в релационна форма, за да можете да ги смесвате с останалите си релационни данни. Тази функция има много приложения; продължете да четете за някои подробности за него.

Вероятно най-интересният случай на използване на XMLTABLE е да се извлекат данни от някакъв XML документ за вмъкване в релационна таблица по време на ETL обработка в базата данни. Въпреки това XMLTABLE може да се използва в движение върху данни, съхранявани в XML колони, така че след като данните са в релационна форма, можете да приложите всякакви стандартни операции, които искате, като например добавяне на WHERE клаузи, извършване на агрегиране, присъединяване към други таблици и т.н.

Прост пример

Като пример, да предположим, че администрирате хотелска верига и че данните се съхраняват по следния начин:

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;

С XMLTABLE , можете да превърнете това в релативно форматирана таблица, състояща се от номера на стаи и капацитет, с пояснения за всеки хотел във вашата верига:

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 име на хотел room_id капацитет коментар
1 Ла Манча 201 3 Страхотен изглед към канала
2 Ла Манча 202 5 Обикновена стая
3 Валпараисо 201 2 Много шумен
4 Валпараисо 202 2 Обикновена стая

Обяснение на синтаксиса

Нека проучим заявката по-горе. XMLTABLE клаузата трябва да влезе в FROM част от заявката. Имаме и хотелски данни в ОТ , което подава данните в XMLTABLE .

Първо, ПРАВЯНЕ клаузата е мястото, където указваме XML данните, които искаме да обработим. В този случай данните идват от хотелите колона в данните за хотела маса. Наричаме това изразът на документа .

Точно преди МИНАВАНЕ клауза виждате XPath израз '/hotels/hotel/rooms/room' . Ние наричаме това израз, генериращ ред или просто изразът на реда .

Имаме КОЛОНИ клауза следваща, декларираща няколко колони. За всяка колона посочваме тип данни, както и незадължителен PATH клауза, която наричаме израз на колона .

XMLTABLE Теорията на работа на „е“ е, че изразът на реда се прилага към израза на документа, като се нарязва документът на парчета, за да се генерират редове; за всеки генериран по този начин ред се прилагат различните изрази на колона, за да се получат стойностите за всяка колона.

Изразът на колоната е израз XPath, който получава стойност, започваща от XML за текущия ред. Ако няма PATH е посочено, тогава самото име на колона се използва като XPath израз. Имайте предвид, че в колоната име_хотел използвахме път с „../ “, което означава „да се качите нагоре“ в XML документа, за да вземете стойности от обектите „контейнер“ в документа. Можем също да използваме xml PATH '.' в ред, което ни дава пълния изходен XML за този ред.

Една колона може да бъде маркирана ЗА РЕДНОСТ . Тогава колоната е от тип INTEGER , и се номерира последователно за всеки ред, получен от документа. (Ако има множество входни документи, например когато имате няколко реда в таблица, броячът започва от 1 за всеки нов документ).

Има и ПО ПОДРАЗБИРАНЕ клауза. Ако XPath за колона не съвпада със стойност за определен ред, тогава DEFAULT се използва стойност.

Някои от тези колони са маркирани като NOT NULL . Ако няма съвпадение и няма DEFAULT е посочена клауза (или DEFAULT също се оценява на NULL ), възниква грешка.

Няма да навлизам в повече подробности за XPath, който е мощен език, но мога да предложа статията на XPath в Wikipedia и официалния препоръчителен документ от W3C като полезни ресурси.

Пълният синтаксис на XMLTABLE

Документираният синопсис на синтаксиса е:

xmltable( [XMLNAMESPACES(namespace uri AS namespace name[, ...])] row_expression PASSING [BY REF] document_expression [BY REF] COLUMNS name { type [PATH column_expression] [DEFAULT expr] [NOT NULL | NULL] | FOR ORDINALITY } [, ...] )

Имайте предвид, че изразът на документа може да бъде препратка към някаква таблица, която имате в клаузата FROM, или може да бъде пълен XML документ като низов литерал. Клаузите BY REF нямат никакъв ефект; те са там за съвместимост със стандарта и с други системи за бази данни.

Не съм покрил XMLNAMESPACES клауза в тази публикация; Оставям го за бъдеща вноска.

Прилагане на SQL отгоре

Както споменахме, след като XMLTABLE обработи данните в релационна форма, можете да правите каквото искате, като използвате добре познати инструменти. Например, ако имате друг XML документ с повече персонал във всеки хотел,

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>$$);

Лесно е да получите общите заплати за всяка валута, която трябва да плащате във всеки хотел,

  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;
хотел валута сума
Валпараисо CLP 1200000
Валпараисо EUR 80 000
Ла Манча PTA 80 000

Заключение

В тази статия разгледах новата функция XMLTABLE да се появи в PostgreSQL версия 10. Мисля, че XMLTABLE е страхотна функция за интегриране на външни данни и се надявам и вие да го намерите за ценно. Моля, тествайте го и докладвайте за всички проблеми, за да можем да ги разрешим преди окончателното издание. Ако харесвате XMLTABLE , не забравяйте да ни уведомите, като оставите коментар!


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Инсталиране на PostgreSQL на Docker

  2. сериен в postgres се увеличава, въпреки че добавих на конфликт не прави нищо

  3. Проследяване на висока наличност за PostgreSQL със сърдечен ритъм

  4. Как работи функцията to_number() в PostgreSQL

  5. Как да разположите Teamcity с PostgreSQL за висока наличност