oracle XMLTABLE не работает должным образом

Я использовал метод EXTRACT для извлечения значений из столбца типа XML в базе данных Oracle 11g.

Если в моей таблице 10 строк, поскольку EXTRACT используется в предложении select, когда я помещаю какое-либо условие в XPATH, например

'/Items/OperatingSystem/@Version[contains(.,"4.04")]'

В возвращаемых строках отображается ноль, если выражение XPATH не совпадает, но отображаются все 10 строк.

Поэтому я попытался перейти к XMLTABLE, поскольку обнаружил, что это последняя версия (EXTRACT устарела). Как мы знаем, она используется в предложении FROM. Я попробовал несколько базовых запросов и обнаружил, что он возвращает только те строки, которые совпадают с выражением XPATH. (Пропускает возвращаемые нулевые строки в случае EXTRACT)

Одна странная проблема, которую я обнаружил при использовании XMLTABLE: в моей локальной среде, когда я использую выражение XPATH

'/Items/OperatingSystem/@Version[contains(.,"4.04")]'

В результате он выбирает только строки с именем, содержащим в нем «Ди».

Но когда я запускаю тот же запрос в наших тестовых средах

Он выбирает все строки вместо выбора только с именем, содержащим «Ди». Я не смог найти ни малейшего намека на то, почему это происходит. Я попробовал еще несколько запросов, поставив условие для других полей, таких как Возраст и т. Д., Но результат тот же. Он возвращает все строки.

Вот сведения о версии - Локальная версия Oracle -

Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production
PL/SQL Release 11.2.0.2.0 - Production
"CORE   11.2.0.2.0  Production"
TNS for 64-bit Windows: Version 11.2.0.2.0 - Production
NLSRTL Version 11.2.0.2.0 - Production

Версия Oracle Testing Environment -

Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
PL/SQL Release 11.2.0.3.0 - Production
"CORE   11.2.0.3.0  Production"
TNS for HPUX: Version 11.2.0.3.0 - Production
NLSRTL Version 11.2.0.3.0 - Production

Есть ли в этих версиях какие-либо изменения, связанные с XMLTABLE?

Образцы данных

Предположим, у меня есть следующая таблица

NAME    | XMLDATA       |   CRT_TS
Ubuntu  | UbuntuXMLDATA | 20-OCT-2016
Windows | WindowsXMLDATA| 20-OCT-2016

UbuntuXMLDATA

<Items>
<OperatingSystem Name="Ubuntu 12.04" Version="12.04" />
<OperatingSystem Name="Ubuntu 14.04" Version="14.04" />
<OperatingSystem Name="Ubuntu 16.04" Version="16.04" />
</Items>

WindowsXMLDATA

<Items>
<OperatingSystem Name="Windows" Version="8" />
<OperatingSystem Name="Windows" Version="7" />
</Items>

В таблице выше xmls представлены в столбце XMLDATA.

Запрос

select Name,rx.COLUMN_VALUE as XPATH_OUTPUT from Operating_System, XMLTABLE('/Items/OperatingSystem/@Version[contains(.,"4.04")]' PASSING XMLTYPE(XMLDATA)) rx where CRT_TS = 20-OCT-2016;

Ожидаемый результат

Name    | XPATH_OUTPUT
Ubuntu  | 14.04

Фактический результат

Name    | XPATH_OUTPUT
Ubuntu  | 12.04
Ubuntu  | 14.04
Ubuntu  | 16.04

Проблема, с которой я столкнулся, заключается в том, что указанный выше запрос отлично работает в моей локальной базе данных. Но против тестовой среды он возвращает три строки вместо одной. Я не могу понять, почему? Это связано с несоответствием версии Oracle (я привел подробности выше)?


person Kuldeep Singh    schedule 20.10.2016    source источник
comment
Пожалуйста, опубликуйте образцы данных, запрос и неожиданный результат, который у вас есть   -  person Aleksej    schedule 20.10.2016
comment
@Aleksej Я предоставил образцы данных. Пожалуйста, посмотри, сможешь ли ты помочь   -  person Kuldeep Singh    schedule 20.10.2016


Ответы (2)


Я не уверен, ошибка это или нет. В xmltable, если вы не используете псевдоним для передачи xml. ". ' является корнем xml.

Попробуйте этот xpath.

'/Items/OperatingSystem/@Version[contains(.,"4.04")]' '/Items/OperatingSystem/@Version[contains(.,"OperatingSystem")]' '/Items/OperatingSystem/@Version[contains(.,"Ubuntu")]'

Результат всегда будет. 3 ряда.

содержит (., "xxxx")] Проверить, содержит ли весь документ строку

Решение 1

Измените xquery.

'/Items/OperatingSystem[contains(@Version,"14.04")]/@Version'

Решение 2

Добавьте псевдоним для xml. XMLTABLE('$doc/Items/OperatingSystem/@Version[contains(.,"4.04")]' PASSING XMLTYPE(XMLDATA) as "doc")

person Arkadiusz Łukasiewicz    schedule 21.10.2016
comment
Большое спасибо за объяснение. - person Kuldeep Singh; 21.10.2016

Для тех, кто сталкивается с подобной проблемой, я могу решить проблему, изменив выражение XPATH. Выражение XPATH обновлено до

/Items/OperatingSystem[contains(@Version,"4.04")]/@Version

Вместо использования оператора точки (.) Для получения значения текущего атрибута, задавая сам @Version.

person Kuldeep Singh    schedule 21.10.2016