(495) 925-0049, ITShop интернет-магазин 229-0436, Учебный Центр 925-0049
  Главная страница Карта сайта Контакты
Поиск
Вход
Регистрация
Рассылки сайта
 
 
 
 
 

XML в Oracle - это очень просто

Владимир Пржиялковский

Оглавление

Введение

Тип XMLTYPE появился в Oracle в версии 9.0. До этого наиболее подходящим для хранения документов в формате XML был тип CLOB (и менее подходящим - тип VARCHAR2, ограниченный максимумом 4000 знаков). Сам по себе объектный, новый тип XMLTYPE технически может храниться либо по-прежнему в виде CLOB, либо в виде объекта (начиная с версии 9.2). И еще одно замечание: несмотря на то, что технологии XML и Java идут "рука об руку", рамки приводимых ниже примеров не требуют от вашей БД установленных возможностей Java.

В этой заметке рассмотрены только логические стороны использования XML в Oracle безотносительно к техническим свойствам хранения и доступа.

Простой пример

CREATE TABLE books
(id NUMBER PRIMARY KEY
, description XMLTYPE);

INSERT INTO books VALUES
(100
, XMLTYPE('<cover>
<title>Oracle SQL*Loader</title>
<author>Jonathan Gennick</author>
<author>Sanjay Mishra</author>
<pages>269</pages>
</cover>'));

SET long 1000

SELECT id, description FROM books;

SELECT id, b.description.XMLDATA FROM books b;

XMLDATA - специально созданный для XMLTYPE "псевдостолбец".

XMLTYPE - тип XML

XMLTYPE дает возможность сообщить БД, что заносимый текст - это не просто строка, а строка документа XML. Следующая попытка приведет к ошибке:

INSERT INTO books VALUES (101, XMLTYPE('<cover><title></title>'));

С дугой стороны, Oracle поймет правильно составленные директивы XML и встроенное в текст описание DTD:

INSERT INTO books VALUES
(101
, XMLTYPE('<?xml version="1.0"?>
<!DOCTYPE cover [
<!ELEMENT cover (title, author*, pages)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT author (#PCDATA)>
<!ELEMENT pages (#PCDATA)>
]>
<cover>
<title>SQL*Plus Pocket Reference</title>
<author>Jonathan Gennick</author>
<pages>94</pages>
</cover>'));

Убедитесь в этом сами, что Oracle действительно соотносит описание DTD самому тексту документа!

Для выборки можно использовать специально придуманные для XMLTYPE функции. Так, функция EXTRACTVALUE извлекает значения элемента из документа XML:

SELECT id, EXTRACTVALUE(description, '/cover/title')
FROM books;

Функция EXISTSNODE дает возможность использовать в SQL условие отбора XPath (язык отбора, принятый в технологиях XML):

SELECT id, b.description.XMLDATA
FROM books b
WHERE b.description.EXISTSNODE('/cover[author="Sanjay Mishra"]')=1;

XMLTYPE - объектный тип Oracle

Доказательством утверждения в заголовке служит создание следующей таблицы объектов типа XMLTYPE, "таблицы документов XML":

CREATE TABLE xbooks OF XMLTYPE;

Работать с ними можно, как и с XML-атрибутом в обычной таблице:

INSERT INTO xbooks VALUES
(XMLTYPE('<cover>
<title>Oracle SQL*Loader</title>
<author>Jonathan Gennick</author>
<author>Sanjay Mishra</author>
<pages>269</pages>
</cover>'));

INSERT INTO xbooks VALUES
(NEW XMLTYPE('<?xml version="1.0"?>
<cover>
<title>SQL*Plus Pocket Reference</title>
<author>Jonathan Gennick</author>
<pages>94</pages>
</cover>'));

В первом случае объект XML создается с помощью конструктора, а во втором, к тому же, используется оператор NEW. Последний применяется в Oracle для работы с объектами, однако его использование носит лишь рекомендательный характер, так как в SQL он ничего содержательного не дает.

Далее:

SELECT * FROM xbooks;

SELECT VALUE(x) FROM xbooks x;

SELECT XMLDATA FROM xbooks;

Так же как для таблиц объектов прочих типов, элементы таблицы объектов XML имеют ссылки, то есть позволяют ссылаться на себя через REF в других типах и таблицах:

SELECT REF(x) FROM xbooks x;

SELECT DEREF(REF(x)) FROM xbooks x;

У этого типа нет свойств, но есть методы. В этом можно убедиться, сделав запрос от имени SYS:

COLUMN text FORMAT A80

SELECT text
FROM user_source
WHERE name ='XMLTYPE' AND type='TYPE'
ORDER BY line;

Исследование каталога rdbms/admin позволяет обнаружить и исходное описание этого типа (но не его тела!) в файле dbmsxmlt.sql. К сожалению, в документации описания этих методов разбросаны по разным местам, не всегда последовательны и ясны. Так, например, EXTRACT и EXISTSNODE (о последней речь шла выше), возведены в ранг функций SQL, то есть описаны в книжке документации по SQL в разделе "Функции", в то время как из предыдущего запроса к словарю-справочнику следует, что это методы. О том же говорит синтаксис употребления. Для EXISTSNODE пример уже приводился, а для EXTRACT он может выглядеть так:

SELECT b.description.EXTRACT('/cover/title') FROM books b;

(Сравните с примером использования функции EXTRACTVALUE выше).

Вот некоторые другие примеры методов XMLTYPE:

SELECT b.description.GETCLOBVAL() FROM books b;

SELECT b.description.GETSTRINGVAL() FROM books b;

SELECT b.description.GETROOTELEMENT() FROM books b;

Обратите внимание, что некоторые методы XMLTYPE, например TOOBJECT, могут использоваться только процедурно, так как сами исполнены в виде процедур, а не функций.

Правда, объектность типа XMLTYPE реализована не в полной степени. Так, попытка создать в таблице столбец из коллекции документов XML (вложенной таблицы или массива VARRAY) в версии 9.2 терпит неудачу. Это относится только к БД; в PL/SQL этих проблем не возникает:

SQL> declare type xml_nt is table of xmltype index by varchar2(10);
2 begin null; end;
3 /

PL/SQL procedure successfully completed.

Взаимные преобразования табличного вида и XMLTYPE

Связь двух форм описания данных - табличной и XML - достигается не одною только возможностью создавать в таблицах столбец типа XMLTYPE. Возможно преобразование данных из одного вида в другой, благодаря чему исходный формат хранения данных может оказаться не столь существенен.

Преобразование из XMLTYPE в табличную форму

Для преобразования данных типа XMLTYPE в обычный табличный вид можно использовать функции SQL и методы XMLTYPE, в первую очередь упоминавшуюся метод-функцию EXTRACT:

COLUMN xdoc FORMAT A80

SELECT ROWNUM, id, b.description.EXTRACT('/cover/author') xdoc
FROM books b;

Обратите внимание на возможность и способ обработки нескольких авторов в XML элементах <author>.

Использование функции SQL EXTRACTVALUE, в свою очередь, оставляет возможность отбора не более одного элемента XML для формирования каждой строки результата SELECT, но зато безболезненно убирает обрамляющие значение элемента XML метки:

SELECT id, EXTRACTVALUE(b.description.EXTRACT('/cover/title'), '/title') xdoc
FROM books b;

То же самое можно записать проще, что уже демонстрировалось в начале статьи.

Преобразование из табличной формы в XMLTYPE

Для обратного преобразования удобно воспользоваться функциями, объединенными в стандарте SQL:2003 названием SQL/XML. В версии Oracle 9.2 реализованы следующие (не все) функции из этого стандартного набора:

- XMLElement
- XMLAttributes
- XMLAgg
- XMLConcat
- XMLForest

Вот некоторые примеры использования в схеме SCOTT:

SELECT XMLELEMENT("Employee", ename) FROM emp;

SELECT XMLELEMENT("Employee",
XMLATTRIBUTES(ename AS "Name", empno AS "Number"))
FROM emp;

Обратите внимание, что в результатах выдаются поля типа XMLTYPE:

CREATE TABLE xtable (n) AS SELECT XMLELEMENT("Name", ename) FROM emp;

DESCRIBE xtable

Следующий пример - агрегирующей функции XMLAGG, допускающей использование в запросах с группировкой GROUP BY, подобно тому, как агрегирующие функции MIN, AVG и другие применяются для обычных данных, а не XMLTYPE:

SET LONG 2000

SELECT XMLELEMENT("department", XMLATTRIBUTES(deptno AS "no")),
XMLAGG(XMLELEMENT("employee", ename))
FROM emp
GROUP BY deptno;

Интересно, что последний запрос допускает создания на своей основе выводимой таблицы, но не базовой:

CREATE VIEW xview (a, b) AS
SELECT XMLELEMENT("department", XMLATTRIBUTES(deptno AS "no")),
XMLAGG(XMLELEMENT("employee", ename))
FROM emp
GROUP BY deptno;

(срабатывает)

CREATE TABLE xtable (a, b) AS
SELECT XMLELEMENT("department", XMLATTRIBUTES(deptno AS "no")),
XMLAGG(XMLELEMENT("employee", ename))
FROM emp
GROUP BY deptno;

(ошибка!)

Это объясняется тем, что столбцы A и B в обоих случаях Oracle пытается создавать как XMLTYPE, а наши данные таковы, что в столбце B содержатся, строго говоря, некорректные строки XML, например

<employee>CLARK</employee><employee>KING</employee> ....

Однако в случае выводимой таблицы Oracle смотрит на это сквозь пальцы, а в случае базовой - нет. Возможно, это есть следствие определенной недоработанности некоторых областей технологий XML в Oracle, что вызвано чересчур быстрыми темпами развития этих технологий.

Ссылки по теме


 Распечатать »
 Правила публикации »
  Обсудить материал в конференции Oracle »
Написать редактору 
 Рекомендовать » Дата публикации: 02.07.2004 
 

Магазин программного обеспечения   WWW.ITSHOP.RU
Oracle Database Standard Edition 2 Processor License
Oracle Database Personal Edition Named User Plus License
Oracle Database Standard Edition 2 Named User Plus License
Oracle Database Personal Edition Named User Plus Software Update License & Support
VMware Horizon 7 Standard : 10 Pack (CCU)
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Новости ITShop.ru - ПО, книги, документация, курсы обучения
Программирование на Microsoft Access
CASE-технологии
СУБД Oracle "с нуля"
Программирование на Visual С++
ЕRP-Форум. Творческие дискуссии о системах автоматизации
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
Обсуждения в форумах
Сайт инструмент (1)
Я бывший программист пользовался 1 сайтом проверенным он мне действительно помог я блогодоря...
 
Где взять лицензионный ключ для AllFusion Process Modeler (BPwin) 7? (5)
Выручайте!!! где найти ключ, ужасно срочно нужна программа. заранее спасибо!
 
работа на дому! (5)
Доброго времени суток дорогие друзья. Многоуровневый маркетинг окончательно признан...
 
Регистрация на Oracle.com (4)
Сразу прошу прощения за тупой вопрос, но вчера зарегался на oracle.com (чтоб 9i слить себе...
 
Ищу кодера (2)
Добрый день! Ищу кодера который сможет сделать копии сайтов. Сколько будет стоить скопировать...
 
 
 



    
rambler's top100 Rambler's Top100