Конференция "Базы" » Oracle и редактирование XML в CLOB-поле
 
  • cippership (09.08.13 12:18) [0]
    Здравствуйте, уважаемые знатоки Оracle (11.2) и XML.
    Столкнулся в Оракле с небольшой проблемой.
    Есть некая таблица table1 в которой есть поле "Query_xml" c типом данных CLOB, хранящее XML.
    Выглядит xml примерно так:

    <?xml version="1.0" encoding="utf-8"?>
    <armcollection connector="F100">
    <NewApplication>
     <applicationid attr1="{2edf54c3-a8d6-41e0-9738-30f94709bbc9}"/>
     <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="{2edf54c3-a8d6-41e0-9738-30f94306bbc9}"/>
     <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?
    Пытался изменить уже существующие значения полей в качестве тренировки - и тоже, полный облом. :)

    Заранее спасибо за помощь.
  • cippership (09.08.13 12:20) [1]
    Надо заметить, в сети не нашлось материалов, которые мне помогли бы. Либо их нет, либо я плохо смотрел.
  • 5000RUB (09.08.13 12:59) [2]
    update надо использовать
  • Обычный порошок (09.08.13 13:12) [3]
    Второй параметр указывает на несуществующий парент, к которому нужно добавить чайлд.

    select
    AppendChildXML(
    XMLType('<root/>'),
    '/root',
    xmltype('<new_node value="3"/>')
    )
    from dual
  • Обычный порошок (09.08.13 13:16) [4]
    третий и четвертый параметры - тоже фигня.
    особенно третий.
  • cippership (09.08.13 14:17) [5]
    Обычный порошок, теория понятна.
    Как это все применить к конкретной ситуации? Большая таблица, CLOB-поле, множество XML и необходимо добавить  <new_field attr1="9"/>   в определенную XML, хранящемся в CLOB-поле.
    Вот это у меня и не получается
  • Обычный порошок (09.08.13 14:41) [6]
    Если теория понятна, то что тебе не понятно?

    Ты указал создать чайлд узел (пока не будем замечать, что не узел, а фигню)
    В качестве парент-узла указал узел, которого нет.

    И куда же прикажешь добавить твоего чайлда, если парент узел не существует в природе?
  • cippership (09.08.13 14:49) [7]
    так таки? и чишо делать?
  • Обычный порошок (09.08.13 14:54) [8]
    читать и изучать.
  • Обычный порошок (09.08.13 14:56) [9]
    Вот это у меня и не получается

    а в примере из [3] получается.
  • cippership (09.08.13 14:58) [10]
    Уточняю вопрос.
    По запросу
    select Query_Xm from Table1
    where id= <условие выборки из Table1

    возвращается xml, хранящийся в clob

    Как мне это дело привинтить к тому, что указал Обычный порошок   (09.08.13 13:12)?
  • cippership (09.08.13 15:00) [11]
    То есть, третий пример будет работать, не сомневаюсь. Но как пример 3 встроить в запрос?
    Мои более, чем скромные познания в Oracle не позволяют оценить ситуацию.  :)
    Не вижу я, как одно привинтить к другому?
  • cippership (09.08.13 15:03) [12]
    Если в моем ошибочном коде - присутствие clob-поля Query_Xml для меня понятно,
    select AppendChildXML (XMLType(Query_Xml), '/armcollection/NewApplication/new_field', '@attr1', '"9"')  from Table1
    where id= <условие выборки из Table1>;


    то в третьем примере я не вижу для него места.
  • Обычный порошок (09.08.13 15:04) [13]
    1. изменить второй параметр у AppendChildXML
    2. изменить третий параметр у AppendChildXML
    3. убрать четвертый параметр у AppendChildXML

    как?
    выполняя пример из [3] и сравнивая со своим случаем.
  • cippership (09.08.13 15:21) [14]
    Отлично. Спасибо!
    Код
    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=...


    :)
  • Обычный порошок (09.08.13 15:41) [15]
    что же делать, что же делать.....

    таблица есть.
    какое поле надо изменить  - знаем.
    новое значение для поля научились получать.
    ид записи которую надо проапдейтить имеем.

    что же делать, что же делать........
    в интернете инфы нигде нету.......

    Идея!
    Поищи на викиликс у асанжа.
    Там стопудово должна быть раскрыта военная тайна пентагона как заапдейтить поле в таблице.
  • cippership (09.08.13 16:05) [16]
    спасибо за совет. уже давно все нашел
  • cippership (09.08.13 16:11) [17]
    Может кому пригодится. 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;

  • cippership (09.08.13 17:09) [18]
    Напоследок, доведенный до ума запрос.
    Дело в том, что в предыдущем запросе [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;

  • Кщд (11.08.13 14:35) [19]
    >cippership   (09.08.13 17:09) [18]
    чудесно:
    xmltype(AlreadyXmltype.getClobVal())

    про то, что на больших объемах XML все эти миленькие явные приведения(xmltype()) и XPATH приведут к существенному проседанию по времени отклика, умолчим
  • cippership (12.08.13 08:54) [20]
    а как надо?
  • cippership (12.08.13 08:56) [21]
    Я ведь серьезно говорю, что опыт в Oracle у меня без году неделя.
    Кщд   (11.08.13 14:35) [19], если знаешь более оптимальный вариант - подскажи новичку.
  • clippership (12.08.13 10:09) [22]
    Так. Продолжаем ругать меня дальше, но ругать, желательно, конструктивно.
    Все эти запросы, собственно, важны для новичков, кто в оракл впервые работает с 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;

  • clippership (12.08.13 10:11) [23]
    слишком много апострофов в верхнем запросе. Невнимательность моя при копировании. Извиняюсь. исправленный текст запроса:
    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;

  • Обычный порошок (12.08.13 13:31) [24]
    с сохранением форматирования

    Зачем?
    Ты его глазами что ли в блокноте разглядываешь?
  • Кщд (12.08.13 13:48) [25]
    >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 в отформатировнном виде. просто незачем.
  • clippership (12.08.13 14:38) [26]
    Кщд   (12.08.13 13:48) [25], действительно не здОрово.
    Но форматирование мне нужно. Точнее не мне - а заказчику. Он рассматривает xml, и возможно глазами в блокноте.. :)
  • Кщд (12.08.13 15:40) [27]
    >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]
    Кщд , спасибо. Вот это, действительно, ценная информация.
  • Кщд (12.08.13 19:24) [29]
    >clippership   (12.08.13 15:48) [28]
    Ваш заказчик рассматривает XML с помощью SQLPlus?
    сомневаюсь)
  • clippership (13.08.13 08:56) [30]
    Наш заказчик рассматривает XML с помощью PL/SQL Developer, нажимая на соответствующую кнопку в ячейке clob-поля.
  • Кщд (13.08.13 09:38) [31]
    >clippership   (13.08.13 08:56) [30]
    Ваш заказчик при просмотре может перейти на вкладку "XML", либо на вкладке "External" может определить любой другой инструмент для просмотра, в котором отформатирует XML так, как нужно именно ему

    ещё раз: хранить XML в отформатированном виде - не вершина разумности
 
Конференция "Базы" » Oracle и редактирование XML в CLOB-поле
Есть новые Нет новых   [119683   +127][b:0][p:0.002]