|
Навигация
|
Главная » Xml XML в Oracle - это очень простоВладимир Пржиялковский Оглавление
В этой заметке рассмотрены только логические стороны использования XML в Oracle безотносительно к техническим свойствам хранения и доступа. Простой пример CREATE TABLE books (id NUMBER PRIMARY KEY , description XMLTYPE); INSERT INTO books VALUES (100 , XMLTYPE(' 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(' С дугой стороны, Oracle поймет правильно составленные директивы XML и встроенное в текст описание DTD: INSERT INTO books VALUES (101 , XMLTYPE(' ]> Убедитесь в этом сами, что 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(' INSERT INTO xbooks VALUES (NEW XMLTYPE(' В первом случае объект 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 элементах Использование функции 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, например Однако в случае выводимой таблицы Oracle смотрит на это сквозь пальцы, а в случае базовой - нет. Возможно, это есть следствие определенной недоработанности некоторых областей технологий XML в Oracle, что вызвано чересчур быстрыми темпами развития этих технологий. XML в Oracle - это очень просто. Программирование на XML для DB2: Часть 1. Понимание модели данных XML (исходники). Освоение Ajax: Часть 10. Использование JSON для передачи данных (исходники). Лицензирование продуктов ABBYY. Oracle представляет новую платформу для бизнес-анализа. Главная » Xml |
© 2024 Team.Furia.Ru.
Частичное копирование материалов разрешено. |