#sql #oracle #oracle10g
#sql #Oracle #oracle10g
Вопрос:
Я пытаюсь добавить атрибут в xml с помощью инструкции Oracle sql. XML хранится в виде данных в столбце таблицы ‘item’. У меня нет проблем с добавлением нового атрибута ‘id’ со значением ‘123’, как указано в приведенном ниже запросе.
UPDATE item SET item_xml = INSERTCHILDXML(item_xml , '/item','@id', '123') where customer_id = '1';
Однако, если я добавлю пространство имен xml и вместо обычного атрибута ‘id’, если я хочу добавить пространство имен типа ‘xml:id’ ниже xml выдает ошибку ‘Недопустимое выражение XPATH‘, пожалуйста, дайте мне знать, как избежать возникновения этой ошибки
UPDATE item SET item_xml = INSERTCHILDXML(item_xml , '/item','@xml:id', '123') where customer_id = '1';
Я понимаю, что мы не используем пространство имен в обычных случаях, однако я привел атрибут ‘id’ в качестве примера, поскольку наше приложение генерирует xml, который используется в другой системе, которая требует атрибутов с пространством имен для нескольких атрибутов.
После обновления xml должен выглядеть примерно так, как показано ниже, пожалуйста, предположите, что атрибут ‘xml: id=»123″‘ изначально отсутствует в xml-блоке таблицы ‘item’ .
<items>
<item xml:id="123">Apple</item>
<items>
Комментарии:
1. Вы пытаетесь добавить новый элемент с этим идентификатором (в этом случае, откуда берется «Apple»?) или добавить атрибут к существующему элементу? Включение вашего начального XML для этого клиента может быть полезным. Основываясь на вашем результате, ваше первое обновление фактически ничего не сделает.
2. Я добавляю атрибут «id» к существующему xml к элементу «item». ‘Apple’ — это значение элемента ‘item’. Таким образом, xpath будет «/items/item». Первый запрос будет работать после правильного xpath, который является ‘/items/item’, тем не менее, как только вы добавите пространство имен ‘@xml:id’, запрос начнет выдавать ошибку, которая является реальной проблемой, мне нужно ее решение. В случае неправильного xpath либо атрибут не будет установлен, но он не выдаст «Недопустимое выражение XPATH».
3. О … вы действительно все еще используете Oracle 10g?
Ответ №1:
Я не думаю, что это поддерживается.
Вы могли бы использовать modify
XPath для этого; с побочным эффектом, что объявление пространства имен отображается в атрибуте, даже если оно уже объявлено в документе; что, надеюсь, не будет касаться вашей системы, расположенной ниже по потоку:
UPDATE item SET item_xml = XMLQuery('
copy $n := .
modify (
for $i in $n/items/item[$item][not(@xml:id)]
return insert node attribute xml:id {$id} into $i
)
return $n'
passing item_xml, 'Apple' as "item", 123 as "id"
returning content
)
where customer_id = 1;
ITEM_XML
----------------------------------------------------------------------------------
<items>
<item xml:id="123" xmlns:xml="http://www.w3.org/XML/1998/namespace">Apple</item>
</items>
Я передал значение элемента и значение идентификатора в качестве параметров, а не жестко кодировал их в XPath; в зависимости от того, где и как вы связываете эти вещи, вы могли бы выполнить одно обновление для всех ваших строк, получая сопоставление элемента / идентификатора из другой таблицы.
Это работает в более поздних версиях Oracle, например, 18c, и, я полагаю, должно работать с 11.2.0.3. Однако это не будет работать в более ранних версиях, поэтому, если вы действительно используете 10g, тогда потребуется другой подход.
Комментарии:
1. Большое спасибо, Алекс, есть ли какой-либо способ предотвратить добавление атрибута xmlns:xml=» w3.org/XML/1998/namespace «. Я вижу, что он добавлен вместе с атрибутом xml: id. Должен ли я выполнить еще один запрос, чтобы удалить его избыточный атрибут «xmlns: xml»? или это может быть подавлено, если вообще?
2. Насколько я вижу, это не добавляется внутренне и не кажется управляемым. Я полагаю, вы могли бы удалить его из окончательного XML / CLOB с помощью
replace()
, но это немного затруднительно.3. Спасибо, Алекс!!