Вы можете использовать //[not(text())][not(*)]
до находить элементы без текста и без дочерних элементов .
Таким образом, в вашем контексте вы можете использовать:
CASE
WHEN c2.RESULT_DETAIL IS NULL
OR
XMLEXISTS(
'/RESULT_DETAIL/CLASS[not(text())][not(*)]'
PASSING c2.RESULT_DETAIL
)
THEN 1
ELSE 0
END AS isClassEmpty
Вы можететакже LEFT OUTER JOIN
ваши таблицы, чтобы отсутствующие элементы все еще появлялись, и тогда вы можете просто проверить, является ли значение CLASS
NULL
:
Oracle Setup :
CREATE TABLE XML_TEST ( File_XML ) AS
SELECT XMLTYPE( '<Data>
<EMPLOYER>
<DOSSIER>1</DOSSIER>
<SUMMARY>
<BEGINDATE>2019-02-13</BEGINDATE>
<WORKER>
<NRWORKER>42</NRWORKER>
<RESULT_DETAIL>
<CODE>12345</CODE>
<MINUTES>0</MINUTES>
<CLASS></CLASS>
</RESULT_DETAIL>
</WORKER>
</SUMMARY>
</EMPLOYER>
</Data>' ) FROM DUAL UNION ALL
SELECT XMLTYPE( '<Data>
<EMPLOYER>
<DOSSIER>2</DOSSIER>
<SUMMARY>
<BEGINDATE>2019-02-14</BEGINDATE>
<WORKER>
<NRWORKER>1</NRWORKER>
<RESULT_DETAIL>
<CODE>98765</CODE>
<MINUTES>600</MINUTES>
<CLASS>B</CLASS>
</RESULT_DETAIL>
</WORKER>
</SUMMARY>
</EMPLOYER>
</Data>' ) FROM DUAL UNION ALL
SELECT XMLTYPE( '<Data>
<EMPLOYER>
<DOSSIER>3</DOSSIER>
<SUMMARY>
<BEGINDATE>2019-02-14</BEGINDATE>
<WORKER>
<NRWORKER>7</NRWORKER>
</WORKER>
</SUMMARY>
</EMPLOYER>
</Data>' ) FROM DUAL
Запрос :
SELECT Dossier,
BeginDate,
NRWorker,
Code,
Minutes,
Class,
CASE
WHEN c2.RESULT_DETAIL IS NULL
OR
XMLEXISTS(
'/RESULT_DETAIL/CLASS[not(text())][not(*)]'
PASSING c2.RESULT_DETAIL
)
THEN 1
ELSE 0
END AS isClassEmpty,
CASE WHEN Class IS NULL THEN 1 ELSE 0 END AS isClassEmpty2
FROM XML_TEST x
LEFT OUTER JOIN
XMLTABLE(
'/Data/EMPLOYER'
PASSING x.File_XML
COLUMNS DOSSIER NUMBER(8) PATH 'DOSSIER',
SUMMARY XMLTYPE PATH 'SUMMARY'
) e
ON ( 1 = 1 )
LEFT OUTER JOIN
XMLTABLE(
'/SUMMARY'
PASSING e.SUMMARY
COLUMNS BEGINDATE DATE PATH 'BEGINDATE',
WORKER XMLTYPE PATH 'WORKER'
) c1
ON ( 1 = 1 )
LEFT OUTER JOIN
XMLTABLE(
'/WORKER'
PASSING c1.WORKER
COLUMNS NRWORKER NUMBER(7) PATH 'NRWORKER',
RESULT_DETAIL XMLTYPE PATH 'RESULT_DETAIL'
) c2
ON ( 1 = 1 )
LEFT OUTER JOIN
XMLTABLE(
'/RESULT_DETAIL'
PASSING c2.RESULT_DETAIL
COLUMNS CODE CHAR(5) PATH 'CODE',
MINUTES NUMBER(5) PATH 'MINUTES',
CLASS CHAR(1) PATH 'CLASS'
) c3
ON ( 1 = 1 );
Выход :
DOSSIER | BEGINDATE | NRWORKER | CODE | MINUTES | CLASS | ISCLASSEMPTY | ISCLASSEMPTY2
------: | :-------- | -------: | :---- | ------: | :---- | -----------: | ------------:
1 | 13-FEB-19 | 42 | 12345 | 0 | <em>null</em> | 1 | 1
2 | 14-FEB-19 | 1 | 98765 | 600 | B | 0 | 0
3 | 14-FEB-19 | 7 | <em>null</em> | <em>null</em> | <em>null</em> | 1 | 1
db <> Fiddle здесь