XML в Oracle SQL — 100 практических примеров

🟢 XML в Oracle SQL. Введение

XML в Oracle — это не просто формат обмена, а целый маленький мир внутри базы.
Здесь можно хранить XML-документы, собирать их из реляционных таблиц, разбирать на колонки,
фильтровать по XPath и XQuery, агрегировать, сериализовать, валидировать и использовать в интеграциях.
Люблю эту тему за контраст: с одной стороны — строгая структура данных, с другой — очень гибкая модель представления.
Если хочется подружить реляционный мир и обменные форматы без лишней боли, XML в Oracle умеет это очень красиво.

Синтаксис

-- хранение
CREATE TABLE xml_docs (
  doc_id NUMBER,
  payload XMLTYPE
);

-- генерация XML
SELECT XMLELEMENT("root", XMLFOREST(col1 AS "col1", col2 AS "col2"))
FROM dual;

-- разбор XML в строки и столбцы
SELECT x.*
FROM XMLTABLE('/root/item'
  PASSING XMLTYPE('<root><item>1</item></root>')
  COLUMNS item_val VARCHAR2(30) PATH '.'
) x;

Чаще всего в Oracle XML-сценариях используются
SELECT,
CREATE TABLE,
XMLTABLE,
XMLQUERY,
XMLCAST,
XMLELEMENT,
XMLFOREST,
XMLAGG,
XMLSERIALIZE
и тип XMLTYPE.

Где используют

  • интеграции между системами и обмен сообщениями
  • хранение полу-структурированных документов
  • генерация XML-ответов из реляционных таблиц
  • разбор XML-файлов и сообщений в таблицы
  • построение витрин и API-ответов
  • миграции и совместимость со старыми корпоративными форматами

100 примеров

1. Создание таблицы с колонкой XMLTYPE

CREATE TABLE xml_docs (
  doc_id NUMBER PRIMARY KEY,
  payload XMLTYPE
)

2. Вставка простого XML-документа

INSERT INTO xml_docs(doc_id,payload)
VALUES (
  1,
  XMLTYPE('<order><id>1001</id><status>NEW</status></order>')
)

3. Выбор всего XML-документа из таблицы

SELECT doc_id,payload
FROM xml_docs

4. Генерация XML через XMLELEMENT

SELECT XMLELEMENT("hello",'world') AS xml_val
FROM dual

5. Генерация XML с атрибутом через XMLATTRIBUTES

SELECT XMLELEMENT(
         "user",
         XMLATTRIBUTES(100 AS "id"),
         'Alice'
       ) AS xml_val
FROM dual

6. Создание нескольких тегов через XMLFOREST

SELECT XMLFOREST(
         'Alice' AS "name",
         'alice@example.com' AS "email"
       ) AS xml_val
FROM dual

7. Комбинация XMLELEMENT и XMLFOREST

SELECT XMLELEMENT(
         "customer",
         XMLFOREST(
           10 AS "customer_id",
           'Alice' AS "customer_name"
         )
       ) AS xml_val
FROM dual

8. XML для строки пользователя из таблицы

SELECT XMLELEMENT(
         "user",
         XMLFOREST(
           user_id AS "id",
           email AS "email"
         )
       ) AS user_xml
FROM users

9. XML-список через XMLAGG

SELECT XMLELEMENT(
         "users",
         XMLAGG(
           XMLELEMENT("user", XMLFOREST(user_id AS "id", email AS "email"))
         )
       ) AS users_xml
FROM users

10. Сериализация XMLTYPE в CLOB

SELECT XMLSERIALIZE(
         CONTENT XMLELEMENT("msg",'ok')
         AS CLOB
       ) AS xml_clob
FROM dual

11. Сериализация XML с отступами

SELECT XMLSERIALIZE(
         CONTENT XMLELEMENT("msg",XMLFOREST('ok' AS "status"))
         AS CLOB INDENT SIZE = 2
       ) AS xml_pretty
FROM dual

12. Извлечение подузла через XMLQUERY

SELECT XMLQUERY(
         '/order/status'
         PASSING XMLTYPE('<order><id>1001</id><status>NEW</status></order>')
         RETURNING CONTENT
       ) AS status_xml
FROM dual

13. Извлечение значения и приведение типа через XMLCAST

SELECT XMLCAST(
         XMLQUERY('/order/id/text()'
           PASSING XMLTYPE('<order><id>1001</id></order>')
           RETURNING CONTENT
         ) AS NUMBER
       ) AS order_id
FROM dual

14. Проверка существования узла через XMLEXISTS

SELECT CASE
         WHEN XMLEXISTS(
           '/order/status'
           PASSING XMLTYPE('<order><status>NEW</status></order>')
         )
         THEN 1 ELSE 0
       END AS has_status
FROM dual

15. Разбор одного узла в колонку через XMLTABLE

SELECT x.order_id
FROM XMLTABLE(
       '/order'
       PASSING XMLTYPE('<order><id>1001</id></order>')
       COLUMNS order_id NUMBER PATH 'id'
     ) x

16. Разбор нескольких колонок через XMLTABLE

SELECT x.order_id,x.status
FROM XMLTABLE(
       '/order'
       PASSING XMLTYPE('<order><id>1001</id><status>NEW</status></order>')
       COLUMNS
         order_id NUMBER PATH 'id',
         status   VARCHAR2(20) PATH 'status'
     ) x

17. Разбор списка элементов item через XMLTABLE

SELECT x.item_id,x.qty
FROM XMLTABLE(
       '/order/items/item'
       PASSING XMLTYPE(
         '<order><items>
            <item><id>1</id><qty>2</qty></item>
            <item><id>2</id><qty>5</qty></item>
          </items></order>'
       )
       COLUMNS
         item_id NUMBER PATH 'id',
         qty     NUMBER PATH 'qty'
     ) x

18. Разбор атрибута XML в колонку

SELECT x.user_id,x.user_name
FROM XMLTABLE(
       '/user'
       PASSING XMLTYPE('<user id="10"><name>Alice</name></user>')
       COLUMNS
         user_id   NUMBER PATH '@id',
         user_name VARCHAR2(50) PATH 'name'
     ) x

19. Хранение XML в XMLTYPE и чтение id через XMLTABLE

SELECT d.doc_id,x.order_id
FROM xml_docs d,
     XMLTABLE(
       '/order'
       PASSING d.payload
       COLUMNS order_id NUMBER PATH 'id'
     ) x

20. Разбор вложенного адреса

SELECT x.city_name,x.zip_code
FROM XMLTABLE(
       '/customer/address'
       PASSING XMLTYPE('<customer><address><city>Paris</city><zip>75001</zip></address></customer>')
       COLUMNS
         city_name VARCHAR2(50) PATH 'city',
         zip_code  VARCHAR2(20) PATH 'zip'
     ) x

Еще 20 примеров

21. Получение XML-фрагмента через XMLQUERY и RETURNING CONTENT

SELECT XMLQUERY(
         '/customer/address'
         PASSING XMLTYPE('<customer><name>Ann</name><address><city>Paris</city></address></customer>')
         RETURNING CONTENT
       ) AS addr_xml
FROM dual

22. Извлечение текстового значения из XML через XMLCAST

SELECT XMLCAST(
         XMLQUERY('/customer/name/text()'
           PASSING XMLTYPE('<customer><name>Ann</name></customer>')
           RETURNING CONTENT
         ) AS VARCHAR2(50)
       ) AS customer_name
FROM dual

23. Преобразование даты из XML

SELECT XMLCAST(
         XMLQUERY('/doc/date/text()'
           PASSING XMLTYPE('<doc><date>2026-03-27</date></doc>')
           RETURNING CONTENT
         ) AS DATE
       ) AS doc_date
FROM dual

24. Фильтрация XML по наличию узла amount

SELECT doc_id
FROM xml_docs
WHERE XMLEXISTS('/order/amount' PASSING payload)

25. Фильтрация XML по значению статуса

SELECT doc_id
FROM xml_docs
WHERE XMLEXISTS('/order[status="NEW"]' PASSING payload)

26. Генерация XML для одного заказа из таблицы

SELECT XMLELEMENT(
         "order",
         XMLFOREST(
           order_id AS "id",
           status AS "status",
           order_date AS "order_date"
         )
       ) AS order_xml
FROM orders
WHERE order_id = 1001

27. XML c вложенным customer-блоком

SELECT XMLELEMENT(
         "order",
         XMLFOREST(
           o.order_id AS "id",
           o.status AS "status"
         ),
         XMLELEMENT(
           "customer",
           XMLFOREST(u.user_id AS "id", u.email AS "email")
         )
       ) AS order_xml
FROM orders o
JOIN users u ON u.user_id = o.user_id
WHERE o.order_id = 1001

28. XML-список строк заказа с XMLAGG

SELECT XMLELEMENT(
         "items",
         XMLAGG(
           XMLELEMENT(
             "item",
             XMLFOREST(item_id AS "item_id", qty AS "qty")
           )
         )
       ) AS items_xml
FROM order_items
WHERE order_id = 1001

29. Полный заказ с вложенными строками

SELECT XMLELEMENT(
         "order",
         XMLFOREST(o.order_id AS "id", o.status AS "status"),
         XMLELEMENT(
           "items",
           (
             SELECT XMLAGG(
                      XMLELEMENT(
                        "item",
                        XMLFOREST(oi.item_id AS "item_id", oi.qty AS "qty")
                      )
                    )
             FROM order_items oi
             WHERE oi.order_id = o.order_id
           )
         )
       ) AS full_order_xml
FROM orders o
WHERE o.order_id = 1001

30. XMLForest без явного AS для имён колонок

SELECT XMLFOREST(user_id,email) AS user_xml
FROM users
FETCH FIRST 1 ROW ONLY

31. Оборачивание XMLForest в root-тег

SELECT XMLELEMENT("root", XMLFOREST(1 AS "id",'ok' AS "status")) AS xml_val
FROM dual

32. Сериализация XML как VARCHAR2

SELECT XMLSERIALIZE(
         CONTENT XMLELEMENT("ping",'pong')
         AS VARCHAR2(100)
       ) AS xml_txt
FROM dual

33. XMLQuery с фильтром по значению атрибута

SELECT XMLQUERY(
         '/root/item[@id="2"]'
         PASSING XMLTYPE('<root><item id="1"/><item id="2"/></root>')
         RETURNING CONTENT
       ) AS item_xml
FROM dual

34. XMLTable для списка кодов статусов

SELECT x.status_code
FROM XMLTABLE(
       '/statuses/status'
       PASSING XMLTYPE('<statuses><status>NEW</status><status>DONE</status></statuses>')
       COLUMNS status_code VARCHAR2(20) PATH '.'
     ) x

35. Разбор нескольких XML-документов через UNION ALL и XMLTABLE

SELECT x.order_id
FROM (
  SELECT XMLTYPE('<order><id>1</id></order>') AS payload FROM dual
  UNION ALL
  SELECT XMLTYPE('<order><id>2</id></order>') FROM dual
) d,
XMLTABLE(
  '/order'
  PASSING d.payload
  COLUMNS order_id NUMBER PATH 'id'
) x

36. XMLExists в CASE-логике

SELECT CASE
         WHEN XMLEXISTS('/user/email' PASSING XMLTYPE('<user><email>a@b.c</email></user>'))
         THEN 'HAS_EMAIL'
         ELSE 'NO_EMAIL'
       END AS email_flag
FROM dual

37. Разбор nested XML внутри XMLTABLE

SELECT x.order_id,x.city_name
FROM XMLTABLE(
       '/order'
       PASSING XMLTYPE('<order><id>1001</id><shipping><city>Paris</city></shipping></order>')
       COLUMNS
         order_id NUMBER PATH 'id',
         city_name VARCHAR2(50) PATH 'shipping/city'
     ) x

38. Извлечение суммы заказа как NUMBER

SELECT XMLCAST(
         XMLQUERY('/order/amount/text()'
           PASSING XMLTYPE('<order><amount>150.75</amount></order>')
           RETURNING CONTENT
         ) AS NUMBER
       ) AS order_amount
FROM dual

39. Генерация XML для адреса через вложенные элементы

SELECT XMLELEMENT(
         "address",
         XMLELEMENT("city",'Paris'),
         XMLELEMENT("zip",'75001')
       ) AS addr_xml
FROM dual

40. XML из нескольких строк через XMLAgg и ORDER BY

SELECT XMLELEMENT(
         "codes",
         XMLAGG(
           XMLELEMENT("code",status_code)
           ORDER BY status_code
         )
       ) AS codes_xml
FROM statuses

Еще 20 примеров

41. Вставка XML, собранного из реляционных данных

INSERT INTO xml_docs(doc_id,payload)
SELECT 2,
       XMLELEMENT(
         "user",
         XMLFOREST(user_id AS "id", email AS "email")
       )
FROM users
WHERE user_id = 10

42. Обновление XML-документа целиком

UPDATE xml_docs
SET payload = XMLTYPE('<order><id>1001</id><status>DONE</status></order>')
WHERE doc_id = 1

43. Разбор XML из CLOB через XMLTYPE

SELECT XMLCAST(
         XMLQUERY('/root/value/text()'
           PASSING XMLTYPE(TO_CLOB('<root><value>42</value></root>'))
           RETURNING CONTENT
         ) AS NUMBER
       ) AS val_num
FROM dual

44. Извлечение email из XML-профиля

SELECT XMLCAST(
         XMLQUERY('/profile/email/text()'
           PASSING XMLTYPE('<profile><email>alice@example.com</email></profile>')
           RETURNING CONTENT
         ) AS VARCHAR2(200)
       ) AS email_val
FROM dual

45. XMLTable для пар country-code и country-name

SELECT x.country_code,x.country_name
FROM XMLTABLE(
       '/countries/country'
       PASSING XMLTYPE('<countries><country code="FR">France</country><country code="DE">Germany</country></countries>')
       COLUMNS
         country_code VARCHAR2(10) PATH '@code',
         country_name VARCHAR2(50) PATH '.'
     ) x

46. XMLQuery с несколькими return-элементами

SELECT XMLQUERY(
         'for $i in /root/item return <code>{$i/text()}</code>'
         PASSING XMLTYPE('<root><item>A</item><item>B</item></root>')
         RETURNING CONTENT
       ) AS codes_xml
FROM dual

47. XMLExists для поиска конкретного item

SELECT CASE
         WHEN XMLEXISTS('/root/item[text()="B"]'
           PASSING XMLTYPE('<root><item>A</item><item>B</item></root>'))
         THEN 1 ELSE 0
       END AS has_b
FROM dual

48. Вывод XML как текст для API-ответа

SELECT XMLSERIALIZE(
         CONTENT XMLELEMENT(
           "response",
           XMLFOREST('ok' AS "status", SYSTIMESTAMP AS "generated_at")
         )
         AS CLOB
       ) AS api_xml
FROM dual

49. Построение XML-каталога товаров

SELECT XMLELEMENT(
         "catalog",
         XMLAGG(
           XMLELEMENT(
             "product",
             XMLFOREST(product_id AS "id", product_name AS "name", price AS "price")
           )
         )
       ) AS catalog_xml
FROM products

50. Построение XML-ленты заказов по дате

SELECT XMLELEMENT(
         "orders",
         XMLAGG(
           XMLELEMENT(
             "order",
             XMLFOREST(order_id AS "id", order_date AS "dt", status AS "status")
           )
           ORDER BY order_date DESC
         )
       ) AS orders_xml
FROM orders

51. XMLForest с числом и датой

SELECT XMLFOREST(
         1001 AS "id",
         DATE '2026-03-27' AS "doc_date"
       ) AS xml_val
FROM dual

52. Оборачивание XMLAgg в root и child

SELECT XMLELEMENT(
         "rows",
         XMLAGG(
           XMLELEMENT("row", XMLFOREST(user_id AS "id"))
         )
       ) AS rows_xml
FROM users

53. Хранение XML заказа с атрибутом версии

INSERT INTO xml_docs(doc_id,payload)
VALUES (
  3,
  XMLELEMENT(
    "order",
    XMLATTRIBUTES('1.0' AS "version"),
    XMLFOREST(2001 AS "id",'NEW' AS "status")
  )
)

54. XMLSerialize DOCUMENT вместо CONTENT

SELECT XMLSERIALIZE(
         DOCUMENT XMLTYPE('<root><a>1</a></root>')
         AS CLOB
       ) AS doc_xml
FROM dual

55. XMLTable с двумя уровнями вложенности

SELECT x.user_id,x.city_name
FROM XMLTABLE(
       '/root/user'
       PASSING XMLTYPE('<root><user><id>10</id><addr><city>Rome</city></addr></user></root>')
       COLUMNS
         user_id NUMBER PATH 'id',
         city_name VARCHAR2(50) PATH 'addr/city'
     ) x

56. Превращение XML-списка в реляционные строки и join с таблицей

SELECT u.user_id,u.email,x.ext_id
FROM users u
JOIN XMLTABLE(
       '/ids/id'
       PASSING XMLTYPE('<ids><id>10</id><id>20</id></ids>')
       COLUMNS ext_id NUMBER PATH '.'
     ) x
ON u.user_id = x.ext_id

57. XMLQuery для выборки всех item-элементов

SELECT XMLQUERY(
         '/root/item'
         PASSING XMLTYPE('<root><item>1</item><item>2</item></root>')
         RETURNING CONTENT
       ) AS items_xml
FROM dual

58. XMLCast числа из атрибута

SELECT XMLCAST(
         XMLQUERY('/user/@id'
           PASSING XMLTYPE('<user id="10"/>')
           RETURNING CONTENT
         ) AS NUMBER
       ) AS user_id
FROM dual

59. Генерация XML-ответа с кодом и сообщением

SELECT XMLELEMENT(
         "response",
         XMLFOREST(
           200 AS "code",
           'ok' AS "message"
         )
       ) AS response_xml
FROM dual

60. XML из справочника статусов

SELECT XMLELEMENT(
         "statuses",
         XMLAGG(XMLELEMENT("status",status_code))
       ) AS statuses_xml
FROM statuses

Еще 20 примеров

61. XML для экспорта списка городов

SELECT XMLELEMENT(
         "cities",
         XMLAGG(
           XMLELEMENT("city", XMLFOREST(city_code AS "code", city_name AS "name"))
         )
       ) AS cities_xml
FROM city_dim

62. Фильтрация XML-документов по country code

SELECT doc_id
FROM xml_docs
WHERE XMLEXISTS('/order/customer/country[text()="FR"]' PASSING payload)

63. XMLTable для тегов продукта

SELECT x.tag_name
FROM XMLTABLE(
       '/product/tags/tag'
       PASSING XMLTYPE('<product><tags><tag>new</tag><tag>hot</tag></tags></product>')
       COLUMNS tag_name VARCHAR2(30) PATH '.'
     ) x

64. XMLQuery с XQuery-конкатенацией

SELECT XMLQUERY(
         'string(/user/first) || " " || string(/user/last)'
         PASSING XMLTYPE('<user><first>Ann</first><last>Lee</last></user>')
         RETURNING CONTENT
       ) AS full_name_xml
FROM dual

65. XMLCast результата XQuery в VARCHAR2

SELECT XMLCAST(
         XMLQUERY(
           'string(/user/first) || " " || string(/user/last)'
           PASSING XMLTYPE('<user><first>Ann</first><last>Lee</last></user>')
           RETURNING CONTENT
         ) AS VARCHAR2(100)
       ) AS full_name
FROM dual

66. XMLSerialize в JSON-подобный transport-текст не нужен, но как CLOB полезен

SELECT XMLSERIALIZE(
         CONTENT XMLELEMENT("ping",XMLFOREST('ok' AS "status"))
         AS CLOB
       ) AS payload_txt
FROM dual

67. Извлечение набора item-ов и подсчёт строк

SELECT COUNT(*) AS item_cnt
FROM XMLTABLE(
       '/order/items/item'
       PASSING XMLTYPE('<order><items><item/><item/><item/></items></order>')
       COLUMNS dummy VARCHAR2(1) PATH '.'
     ) x

68. XMLAgg для email-списка

SELECT XMLELEMENT(
         "emails",
         XMLAGG(XMLELEMENT("email",email))
       ) AS email_xml
FROM users

69. XMLForest для документа с числами и флагами

SELECT XMLFOREST(
         1 AS "id",
         100.5 AS "amount",
         1 AS "active_flag"
       ) AS xml_val
FROM dual

70. XMLTable для invoice lines с price

SELECT x.item_code,x.price_amt
FROM XMLTABLE(
       '/invoice/lines/line'
       PASSING XMLTYPE('<invoice><lines><line><code>A</code><price>10</price></line><line><code>B</code><price>20</price></line></lines></invoice>')
       COLUMNS
         item_code VARCHAR2(20) PATH 'code',
         price_amt NUMBER PATH 'price'
     ) x

71. Поиск XML-документов со статусом DONE

SELECT doc_id
FROM xml_docs
WHERE XMLEXISTS('/order[status="DONE"]' PASSING payload)

72. XMLQuery для выбора только адресного города

SELECT XMLQUERY(
         '/customer/address/city'
         PASSING XMLTYPE('<customer><address><city>Madrid</city></address></customer>')
         RETURNING CONTENT
       ) AS city_xml
FROM dual

73. XMLCast булева признака в NUMBER

SELECT XMLCAST(
         XMLQUERY('/root/flag/text()'
           PASSING XMLTYPE('<root><flag>1</flag></root>')
           RETURNING CONTENT
         ) AS NUMBER
       ) AS flag_num
FROM dual

74. XMLTable с optional-элементом и NULL

SELECT x.phone_val
FROM XMLTABLE(
       '/user'
       PASSING XMLTYPE('<user><name>Ann</name></user>')
       COLUMNS phone_val VARCHAR2(30) PATH 'phone'
     ) x

75. Генерация XML из констант через dual

SELECT XMLELEMENT(
         "config",
         XMLFOREST('prod' AS "env", 50 AS "page_size")
       ) AS config_xml
FROM dual

76. XML для одного продукта с тегами и ценой

SELECT XMLELEMENT(
         "product",
         XMLFOREST(p.product_id AS "id", p.product_name AS "name", p.price AS "price"),
         XMLELEMENT("tags",
           XMLAGG(XMLELEMENT("tag",t.tag_name))
         )
       ) AS product_xml
FROM products p
JOIN product_tags t ON t.product_id = p.product_id
WHERE p.product_id = 1
GROUP BY p.product_id,p.product_name,p.price

77. XML-список id через XMLAgg

SELECT XMLELEMENT(
         "ids",
         XMLAGG(XMLELEMENT("id",user_id))
       ) AS ids_xml
FROM users

78. XMLSerialize XMLTYPE-колонки в текстовом выводе

SELECT doc_id,
       XMLSERIALIZE(CONTENT payload AS CLOB) AS payload_txt
FROM xml_docs

79. Разбор атрибута currency из XML счета

SELECT x.ccy,x.amount_val
FROM XMLTABLE(
       '/invoice'
       PASSING XMLTYPE('<invoice currency="EUR"><amount>150</amount></invoice>')
       COLUMNS
         ccy VARCHAR2(10) PATH '@currency',
         amount_val NUMBER PATH 'amount'
     ) x

80. Проверка наличия атрибута id

SELECT CASE
         WHEN XMLEXISTS('/user/@id'
           PASSING XMLTYPE('<user id="10"/>'))
         THEN 1 ELSE 0
       END AS has_id
FROM dual

Еще 20 примеров

81. EXTRACTVALUE для старого кода (legacy)

SELECT EXTRACTVALUE(
         XMLTYPE('<order><id>1001</id></order>'),
         '/order/id'
       ) AS order_id
FROM dual

82. XMLType в merge-like staging хранении

CREATE TABLE xml_stage (
  batch_id NUMBER,
  payload XMLTYPE
)

83. Загрузка XML в staging-таблицу

INSERT INTO xml_stage(batch_id,payload)
VALUES (
  1,
  XMLTYPE('<root><item>A</item></root>')
)

84. Разбор XML из staging через XMLTable

SELECT s.batch_id,x.item_val
FROM xml_stage s,
     XMLTABLE(
       '/root/item'
       PASSING s.payload
       COLUMNS item_val VARCHAR2(30) PATH '.'
     ) x

85. Преобразование XML-документов в реляционный вид для join

SELECT x.user_id,u.email
FROM xml_stage s,
     XMLTABLE(
       '/root/user'
       PASSING s.payload
       COLUMNS user_id NUMBER PATH 'id'
     ) x
JOIN users u ON u.user_id = x.user_id

86. XMLAggregate из справочника городов по стране

SELECT XMLELEMENT(
         "country",
         XMLATTRIBUTES(country_code AS "code"),
         XMLAGG(XMLELEMENT("city",city_name))
       ) AS country_xml
FROM city_dim
GROUP BY country_code

87. Генерация XML ответа для KPI

SELECT XMLELEMENT(
         "kpi",
         XMLFOREST(
           kpi_code AS "code",
           plan_val AS "plan",
           fact_val AS "fact"
         )
       ) AS kpi_xml
FROM kpi_table

88. XML с вложенным массивом email-ов

SELECT XMLELEMENT(
         "emails",
         XMLAGG(XMLELEMENT("email",email) ORDER BY email)
       ) AS emails_xml
FROM users

89. Поиск документов, где amount больше 100

SELECT doc_id
FROM xml_docs
WHERE XMLEXISTS('/order[number(amount) > 100]' PASSING payload)

90. Разбор координат из XML

SELECT x.lat_val,x.lon_val
FROM XMLTABLE(
       '/point'
       PASSING XMLTYPE('<point><lat>48.85</lat><lon>2.35</lon></point>')
       COLUMNS
         lat_val NUMBER PATH 'lat',
         lon_val NUMBER PATH 'lon'
     ) x

91. XMLQuery c XQuery for-return

SELECT XMLQUERY(
         'for $i in /root/item return <value>{data($i)}</value>'
         PASSING XMLTYPE('<root><item>10</item><item>20</item></root>')
         RETURNING CONTENT
       ) AS values_xml
FROM dual

92. XMLSerialize для выгрузки в файл-слой

SELECT XMLSERIALIZE(
         CONTENT XMLELEMENT("export", XMLFOREST(SYSDATE AS "dt"))
         AS CLOB INDENT SIZE = 2
       ) AS export_xml
FROM dual

93. XMLForest для параметров приложения

SELECT XMLELEMENT(
         "params",
         XMLAGG(
           XMLELEMENT("param", XMLFOREST(param_code AS "code", param_value AS "value"))
         )
       ) AS params_xml
FROM app_params

94. XML c атрибутами и текстовым содержимым

SELECT XMLELEMENT(
         "status",
         XMLATTRIBUTES('1' AS "code"),
         'OK'
       ) AS status_xml
FROM dual

95. Преобразование XML-списка в id и status

SELECT x.id_val,x.status_val
FROM XMLTABLE(
       '/rows/row'
       PASSING XMLTYPE('<rows><row><id>1</id><status>A</status></row><row><id>2</id><status>B</status></row></rows>')
       COLUMNS
         id_val NUMBER PATH 'id',
         status_val VARCHAR2(10) PATH 'status'
     ) x

96. XMLEXISTS по email-атрибуту

SELECT CASE
         WHEN XMLEXISTS('/user[@email="alice@example.com"]'
           PASSING XMLTYPE('<user email="alice@example.com"/>'))
         THEN 'Y' ELSE 'N'
       END AS email_match
FROM dual

97. XMLType-колонка с выборкой только текста через XMLCast

SELECT d.doc_id,
       XMLCAST(
         XMLQUERY('/order/status/text()'
           PASSING d.payload
           RETURNING CONTENT
         ) AS VARCHAR2(20)
       ) AS status_txt
FROM xml_docs d

98. Генерация XML-профиля клиента из join

SELECT XMLELEMENT(
         "profile",
         XMLFOREST(c.customer_id AS "id", c.customer_name AS "name", a.city AS "city")
       ) AS profile_xml
FROM customers c
LEFT JOIN addresses a ON a.customer_id = c.customer_id

99. XML-отчёт по заказам и сумме

SELECT XMLELEMENT(
         "report",
         XMLAGG(
           XMLELEMENT(
             "order",
             XMLFOREST(order_id AS "id", total_amt AS "amount")
           )
         )
       ) AS report_xml
FROM daily_totals

100. Финальный пример: полный XML-документ с root, списком rows и pretty-serialize

SELECT XMLSERIALIZE(
         CONTENT XMLELEMENT(
           "result",
           XMLAGG(
             XMLELEMENT(
               "row",
               XMLFOREST(user_id AS "id", email AS "email")
             )
             ORDER BY user_id
           )
         )
         AS CLOB INDENT SIZE = 2
       ) AS final_xml
FROM users

Заключение

XML в Oracle — это очень зрелая история. Здесь можно и хранить документы, и извлекать из них данные,
и собирать аккуратные XML-ответы из обычных таблиц. Особенно приятно, что Oracle даёт не один инструмент,
а целую экосистему: XMLType для хранения, XMLTABLE для разбора,
XMLQUERY и XMLEXISTS для XQuery-логики,
XMLELEMENT, XMLFOREST и XMLAGG для генерации.
Если любишь SQL за выразительность, то XML-сценарии в Oracle умеют очень красиво соединять реляционный и документный мир.

Официальная документация Oracle:
Oracle XML DB — Introduction
XMLTABLE
XMLQUERY
XMLFOREST
XMLAGG


 

🔜 Следующая статья:

WRITE в Oracle SQL — как использовать буферную запись


Понравилась статья? Поделиться с друзьями:
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest
0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии