Я работаю с базой данных oracle 11g r2 и в основном должен иметь возможность анализировать и выбирать некоторые узлы из нее. Я часами рыскал по сети и читал руководство по oracle xml db, пытаясь найти подходящее решение для моей проблемы, но, похоже, не могу придумать правильный способ сделать это. У меня достаточно опыта в программировании, но я вообще не имею опыта работы с базами данных xml, sql или oracle, поэтому извините, если это тривиальный вопрос.
Хорошо, так на вопрос:
У меня есть очень простой файл XML, сохраненный как catalog.xml, и он выглядит следующим образом:
<catalog>
<cd>
<title>Hide your heart</title>
<artist>Bonnie Tyler</artist>
<country>UK</country>
<company>CBS Records</company>
<price>9.90</price>
<year>1988</year>
</cd>
<cd>
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
</catalog>
Теперь я хочу иметь возможность извлечь название компакт-диска, заданного определенному исполнителю. Так, например, если художник «Боб Дилан», тогда название должно быть «империя бурлеск»
Теперь я создал таблицу XMLType в Oracle следующим образом:
CREATE TABLE BINARY OF XMLType XMLTYPE STORE AS BINARY XML;
Затем я продолжил загружать свой XML-файл в Oracle:
insert into BINARY values (XMLTYPE(BFILENAME ('XML_DIR','catalog.xml'),nls_charset_id('AL32UTF8')));
Пока все хорошо.
Теперь для части извлечения:
Сначала я попробовал:
SELECT extract(b.object_value, '/catalog/cd/title')
FROM binary b
WHERE existsNode(b.object_value,'/catalog/cd[artist="Bob Dylan"]') = 1;
EXTRACT(B.OBJECT_VALUE,'/CATALOG/CD/TITLE')
--------------------------------------------------------------------------------
<Title>Hide your heart</Title>
<Title>Empire Burlesque</Title>
1 row selected.
Это не сработало, потому что файл xml был в одной строке, поэтому я понял, что мне нужно разбить мой xml на отдельные строки. Для этого мне пришлось преобразовать узлы в виртуальную таблицу, используя функции XMLSequence () и table (). Эти функции преобразуют два узла заголовка, перенастроенных методом extract (), в виртуальную таблицу, состоящую из двух объектов XMLType, каждый из которых содержит один элемент заголовка.
Вторая попытка:
SELECT value(d)
FROM binary b,
table (xmlsequence(extract(b.object_value,'/catalog/cd'))) d
WHERE existsNode(b.object_value,'/catalog/cd[artist="Bob Dylan"]') = 1;
VALUE(D)
--------------------------------------------------------------------------------
<cd>
<title>Hide your heart</title>
<artist>Bonnie Tyler</artist>
<country>UK</country>
<company>CBS Records</company>
<price>9.90</price>
<year>1988</year>
</cd>
<cd>
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
2 rows selected.
Это лучше, так как теперь он разделен на 2 разные строки, поэтому я должен иметь возможность выбрать где и выбрать заголовок в зависимости от исполнителя.
Однако именно здесь у меня возникают проблемы, я пытался буквально часами, но я не могу понять, как использовать результаты вышеупомянутого запроса в моем следующем. Поэтому я попытался использовать suquery, выполнив это:
select extract(sub1, 'cd/title')
from
(
SELECT value(d)
FROM binary b,
table (xmlsequence(extract(b.object_value,'/catalog/cd'))) d
) sub1
WHERE existsNode(sub1,'/cd[artist="Bob Dylan"]') = 1;
Однако sql * plus показывает ошибку:
ORA-00904: "SUB1": invalid identifier.
Я пробовал десятки вариантов использования подзапросов, но, похоже, не могу понять, как это правильно.
Я слышал, что вы можете сделать это, используя переменные или pl / sql, но я не уверен, с чего начать.
Любая помощь будет принята с благодарностью, так как я попробовал все, что в моем распоряжении.