-
Здравствуйте, уважаемые знатоки Оracle (11.2) и XML. Столкнулся в Оракле с небольшой проблемой. Есть некая таблица table1 в которой есть поле "Query_xml" c типом данных CLOB, хранящее XML. Выглядит xml примерно так:
<?xml version="1.0" encoding="utf-8"?>
<armcollection connector="F100">
<NewApplication>
<applicationid attr1=""/>
<applicationdate attr1="18.10.2012 18:17:51"/>
<newapplicant attr1="1"/>
</NewApplication>
</armcollection>
И у меня не получается добавить новый тэг (с аттрибутом и значением) в данный xml. Надо, чтобы xml стал бы таким:
<?xml version="1.0" encoding="utf-8"?>
<armcollection connector="FPS">
<NewApplication>
<applicationid attr1=""/>
<applicationdate attr1="18.10.2012 18:17:51"/>
<newapplicant attr1="1"/>
<new_field attr1="9"/> -- новая запись
</NewApplication>
</armcollection>
Подскажите, как грамотно реализовать эту задачу с помощью PL/SQL? Запрос, который я написал - при выполнении не выдает никаких ошибок, но при этом - xml не изменяется, тэг не добавляется. Вот запрос:
select AppendChildXML (XMLType(Query_Xml), '/armcollection/NewApplication/new_field', '@attr1', '\"9\"') from Table1
where id= <условие выборки из Table1>;
Commit; Видимо - он совсем не корректен... :) И cразу предвижу второе затруднение. Как потом можно будет изменить значение тэга в xml? Например в <new_field attr1="9"/> поменять значение с 9 на 1? Пытался изменить уже существующие значения полей в качестве тренировки - и тоже, полный облом. :) Заранее спасибо за помощь.
-
Надо заметить, в сети не нашлось материалов, которые мне помогли бы. Либо их нет, либо я плохо смотрел.
-
update надо использовать
-
Второй параметр указывает на несуществующий парент, к которому нужно добавить чайлд.
select AppendChildXML( XMLType('<root/>'), '/root', xmltype('<new_node value="3"/>') ) from dual
-
третий и четвертый параметры - тоже фигня. особенно третий.
-
Обычный порошок, теория понятна. Как это все применить к конкретной ситуации? Большая таблица, CLOB-поле, множество XML и необходимо добавить <new_field attr1="9"/> в определенную XML, хранящемся в CLOB-поле. Вот это у меня и не получается
-
Если теория понятна, то что тебе не понятно?
Ты указал создать чайлд узел (пока не будем замечать, что не узел, а фигню) В качестве парент-узла указал узел, которого нет.
И куда же прикажешь добавить твоего чайлда, если парент узел не существует в природе?
-
так таки? и чишо делать?
-
читать и изучать.
-
Вот это у меня и не получается
а в примере из [3] получается.
-
Уточняю вопрос. По запросу select Query_Xm from Table1 where id= <условие выборки из Table1 возвращается xml, хранящийся в clob
Как мне это дело привинтить к тому, что указал Обычный порошок (09.08.13 13:12)?
-
То есть, третий пример будет работать, не сомневаюсь. Но как пример 3 встроить в запрос? Мои более, чем скромные познания в Oracle не позволяют оценить ситуацию. :) Не вижу я, как одно привинтить к другому?
-
Если в моем ошибочном коде - присутствие clob-поля Query_Xml для меня понятно, select AppendChildXML (XMLType(Query_Xml), '/armcollection/NewApplication/new_field', '@attr1', '"9"') from Table1 where id= <условие выборки из Table1>;
то в третьем примере я не вижу для него места.
-
1. изменить второй параметр у AppendChildXML 2. изменить третий параметр у AppendChildXML 3. убрать четвертый параметр у AppendChildXML
как? выполняя пример из [3] и сравнивая со своим случаем.
-
Отлично. Спасибо! Код select AppendChildXML (XMLType(Query_Xml), '/armcollection/NewApplication', xmltype('<new_field attr1=\"9\"/>'))from Table1
where query_id= <условие выборки из Table1>;
Commit; изменяет xml, как надо. :) Но она, зараза, изменяет xml, но не сохраняется в таблице Table1. Подразумеваю, что где-то должен быть UPDATE Table1 Set Query_Xml=... :)
-
что же делать, что же делать.....
таблица есть. какое поле надо изменить - знаем. новое значение для поля научились получать. ид записи которую надо проапдейтить имеем.
что же делать, что же делать........ в интернете инфы нигде нету.......
Идея! Поищи на викиликс у асанжа. Там стопудово должна быть раскрыта военная тайна пентагона как заапдейтить поле в таблице.
-
спасибо за совет. уже давно все нашел
-
Может кому пригодится. Update xml (добавляем поле)l, хранящегося в сlob-поле. UPDATE Table1 Set Query_Xml =
AppendChildXML (XMLType(Query_Xml), '/armcollection/NewApplication', xmltype('<new_field attr1=\"9\"/>')).GetClobVal()
where query_id=<условие выборки из Table1>;
Commit;
-
Напоследок, доведенный до ума запрос. Дело в том, что в предыдущем запросе [17] при Update clob-поля терялось форматирование xml, т.е. значения xml выравнивались в одну строку. Для сохранения форматирования xml, а так же для невозможности случайного добавления в xml одинаковых элементов пишем такой код. UPDATE Table1 Set Query_Xml =
xmlserialize(document xmltype(AppendChildXML (XMLType(Query_Xml), '/armcollection/NewApplication', xmltype('<new_field attr1=\"9\"/>')).GetCLOBVal()) as clob indent)
where query_id = <условие выборки из Table1>
And EXISTSNODE(XMLTYPE(Query_Xml), '/armcollection/NewApplication/new_field/@attr1')=0;
Commit;
-
>cippership (09.08.13 17:09) [18] чудесно: xmltype(AlreadyXmltype.getClobVal())
про то, что на больших объемах XML все эти миленькие явные приведения(xmltype()) и XPATH приведут к существенному проседанию по времени отклика, умолчим
-
а как надо?
-
Я ведь серьезно говорю, что опыт в Oracle у меня без году неделя. Кщд (11.08.13 14:35) [19], если знаешь более оптимальный вариант - подскажи новичку.
-
Так. Продолжаем ругать меня дальше, но ругать, желательно, конструктивно. Все эти запросы, собственно, важны для новичков, кто в оракл впервые работает с xml. Просьба ораколовским гуру, в случае, если им будет не лень указать на грубые просчеты или отсутствие оптимизации - подтолкнуть мою мысль в правильном направлении или просто показать, как надо. Итак, запрос на изменение значения уже существующего поля с сохранением форматирования структуры xml-документа в поле CLOB: UPDATE Table1 SET Query_Xml =
xmlserialize(document xmltype (UPDATEXML(XMLType(Query_Xml),
''/armcollection/NewApplication'/new_field',xmltype('<new_field attr1=\"1\"/>')).GetCLOBVal()) as clob indent)
where query_id= <условие выборки из Table1>;
Commit;
-
слишком много апострофов в верхнем запросе. Невнимательность моя при копировании. Извиняюсь. исправленный текст запроса: UPDATE Table1 SET Query_Xml =
xmlserialize(document xmltype (UPDATEXML(XMLType(Query_Xml),
'/armcollection/NewApplication/new_field',xmltype('<new_field attr1=\"1\"/>')).GetCLOBVal()) as clob indent)
where query_id= <условие выборки из Table1>;
Commit;
-
с сохранением форматирования
Зачем? Ты его глазами что ли в блокноте разглядываешь?
-
>cippership (12.08.13 08:56) [21] Вы знаете, что такое явное преобразование типов?
1. UPDATEXML - возвращает XMLTYPE; 2. getClobVal() - преобразует (1) в CLOB; 3. следующий за этим xmltype() - приведёт результат(из (2)) в XMLTYPE. Зачем впустую преобразовывать данные?
и, конечно, обратите внимание на "Обычный порошок (12.08.13 13:31) [24]": незачем хранить XML в отформатировнном виде. просто незачем.
-
Кщд (12.08.13 13:48) [25], действительно не здОрово. Но форматирование мне нужно. Точнее не мне - а заказчику. Он рассматривает xml, и возможно глазами в блокноте.. :)
-
>clippership (12.08.13 14:38) [26] "рассматривать" XML нужно спец. программами, коих несть числа при этом, в них можно отформатировать данные так, как нужно пользователю
и информация к размышлению: https://forums.oracle.com/thread/2565779 цитирую: "The trouble is this is formatted using the UNIX end of line marker, Line Feed = #10, even if Oracle is running under Window Server (windows uses Carriage Return + Line Feed = #13#10). This is causing problems when XML docs are delivered to users on Windows machines, who open it in notepad or similar - it means the data isn't visualised properly (not pretty printed)..."
-
Кщд , спасибо. Вот это, действительно, ценная информация.
-
>clippership (12.08.13 15:48) [28] Ваш заказчик рассматривает XML с помощью SQLPlus? сомневаюсь)
-
Наш заказчик рассматривает XML с помощью PL/SQL Developer, нажимая на соответствующую кнопку в ячейке clob-поля.
-
>clippership (13.08.13 08:56) [30] Ваш заказчик при просмотре может перейти на вкладку "XML", либо на вкладке "External" может определить любой другой инструмент для просмотра, в котором отформатирует XML так, как нужно именно ему
ещё раз: хранить XML в отформатированном виде - не вершина разумности
|