Oracle, XMLTABLE, получить значение из тега, если тег рядом равен - PullRequest
0 голосов
/ 03 апреля 2020

У меня есть XML и выражение для получения значений:

SELECT * 
FROM   XMLTABLE('//contract-dates'
                PASSING xmltype('
<contract-dates>
     <other-dates>
       <other-date>
         <date-type>DATE_1</date-type>
         <date-value>2020-01-01</date-value>
       </other-date>
       <other-date>
         <date-type>DATE_2</date-type>
         <date-value>2020-03-30</date-value>
       </other-date>
     </other-dates>
</contract-dates>')

      COLUMNS
        date_1       PATH 'other-dates/other-date[1]/date-value',
        date_2       PATH 'other-dates/other-date[2]/date-value'
);

Проблема начинается, когда первое из этих значений может быть нулевым, поэтому один тег исчезает:

SELECT * 
FROM   XMLTABLE('//contract-dates'
                PASSING xmltype('
<contract-dates>
     <other-dates>
       <other-date>
         <date-type>DATE_2</date-type>
         <date-value>2020-03-30</date-value>
       </other-date>
     </other-dates>
</contract-dates>')

      COLUMNS
        date_1          PATH 'other-dates/other-date[1]/date-value',
        date_2          PATH 'other-dates/other-date[2]/date-value'
);

в этом случае сценарий date_1 содержит дату из тега date-type = "DATE_2", что неверно.

Есть ли способ сказать 'получить значение из date-value, если date-type = "DATE_1" ??

РЕДАКТИРОВАТЬ: xml является частью большего xml, даты контракта - только один из дочерних тегов

1 Ответ

1 голос
/ 03 апреля 2020

Ищите значение дочернего элемента вместо позиции:

date_1       PATH 'other-dates/other-date[date-type="DATE_1"]/date-value',
date_2       PATH 'other-dates/other-date[date-type="DATE_2"]/date-value'

С вашими модифицированными примерами:

SELECT * 
FROM   XMLTABLE('//contract-dates'
                PASSING xmltype('
<contract-dates>
     <other-dates>
       <other-date>
         <date-type>DATE_1</date-type>
         <date-value>2020-01-01</date-value>
       </other-date>
       <other-date>
         <date-type>DATE_2</date-type>
         <date-value>2020-03-30</date-value>
       </other-date>
     </other-dates>
</contract-dates>')

      COLUMNS
        date_1       PATH 'other-dates/other-date[date-type="DATE_1"]/date-value',
        date_2       PATH 'other-dates/other-date[date-type="DATE_2"]/date-value'
);

DATE_1                         DATE_2                        
------------------------------ ------------------------------
2020-01-01                     2020-03-30                    

и

SELECT * 
FROM   XMLTABLE('//contract-dates'
                PASSING xmltype('
<contract-dates>
     <other-dates>
       <other-date>
         <date-type>DATE_2</date-type>
         <date-value>2020-03-30</date-value>
       </other-date>
     </other-dates>
</contract-dates>')

      COLUMNS
        date_1          PATH 'other-dates/other-date[date-type="DATE_1"]/date-value',
        date_2          PATH 'other-dates/other-date[date-type="DATE_2"]/date-value'
);

DATE_1                         DATE_2                        
------------------------------ ------------------------------
                               2020-03-30                    

Кстати вы можете указать тип данных столбцов результата, что может облегчить работу с ними; поскольку значения представлены в формате сенсибеля, вы можете объявить их непосредственно в виде дат здесь:

date_1 date PATH 'other-dates/other-date[date-type="DATE_1"]/date-value',
date_2 date PATH 'other-dates/other-date[date-type="DATE_2"]/date-value'
...