Я новичок XPath; Я нашел способ сделать то, что хочу, но задаюсь вопросом, есть ли другой способ, который может сэкономить мне некоторое повторение в моем коде.Oracle XPath: Атрибут родительского узла?
У меня есть эта таблица:
CREATE TABLE t (
quark_p1 VARCHAR2(4)
, quark_p2 VARCHAR2(7)
, quark_p3 VARCHAR2(6)
, one VARCHAR2(1)
, two VARCHAR2(1)
, three VARCHAR2(1)
, four VARCHAR2(1)
, five VARCHAR2(1)
, six VARCHAR2(1)
, seven VARCHAR2(1)
, eight VARCHAR2(1)
, nine VARCHAR2(1)
)
;
Следующая PL/SQL анонимный блок делает то, что я хочу, извлекая в эту таблицу структуру из моего заданного XML:
BEGIN
INSERT INTO t (
quark_p1
, quark_p2
, quark_p3
, one
, two
, three
, four
, five
, six
, seven
, eight
, nine
)
SELECT x.quark_p1
, x.quark_p2
, x.quark_p3
, x.one
, x.two
, x.three
, x.four
, x.five
, x.six
, x.seven
, x.eight
, x.nine
FROM XMLTABLE('/BASIS/QUARK'
PASSING XMLTYPE (
'<BASIS>
<QUARK P1="up" P2="charm" P3="bottom">
<NEST>
<ONE>A</ONE>
<TWO>B</TWO>
<THREE>C</THREE>
<FOUR>D</FOUR>
<FIVE>E</FIVE>
<SIX>F</SIX>
<SEVEN>G</SEVEN>
<EIGHT>H</EIGHT>
<NINE>I</NINE>
</NEST>
</QUARK>
<QUARK P1="up" P2="strange" P3="top">
<NEST>
<ONE>J</ONE>
<TWO>K</TWO>
<THREE>L</THREE>
<FOUR>M</FOUR>
<FIVE>N</FIVE>
<SIX>O</SIX>
<SEVEN>P</SEVEN>
<EIGHT>Q</EIGHT>
<NINE>R</NINE>
</NEST>
</QUARK>
</BASIS>')
COLUMNS quark_p1 VARCHAR2(4) PATH '@P1'
, quark_p2 VARCHAR2(7) PATH '@P2'
, quark_p3 VARCHAR2(6) PATH '@P3'
, one VARCHAR2(1) PATH 'NEST/ONE'
, two VARCHAR2(1) PATH 'NEST/TWO'
, three VARCHAR2(1) PATH 'NEST/THREE'
, four VARCHAR2(1) PATH 'NEST/FOUR'
, five VARCHAR2(1) PATH 'NEST/FIVE'
, six VARCHAR2(1) PATH 'NEST/SIX'
, seven VARCHAR2(1) PATH 'NEST/SEVEN'
, eight VARCHAR2(1) PATH 'NEST/EIGHT'
, nine VARCHAR2(1) PATH 'NEST/NINE'
) x;
END;
/
Это приводит к следующий, что я после:
SQL> SELECT * FROM t
2 ;
QUARK_P1 QUARK_P2 QUARK_P3 O T T F F S S E N
-------- -------- -------- - - - - - - - - -
up charm bottom A B C D E F G H I
up strange top J K L M N O P Q R
SQL>
Поскольку уровень «NEST» повторяется так часто, Я бы хотел поместить его в исходный узел и получить те же результаты. Я ищу, чтобы сделать что-то вроде следующего:
BEGIN
INSERT INTO t (
quark_p1
, quark_p2
, quark_p3
, one
, two
, three
, four
, five
, six
, seven
, eight
, nine
)
SELECT x.quark_p1
, x.quark_p2
, x.quark_p3
, x.one
, x.two
, x.three
, x.four
, x.five
, x.six
, x.seven
, x.eight
, x.nine
-- Notice, I changed the starting node from /BASIS/QUARK to /BASIS/QUARK/NEST....
FROM XMLTABLE('/BASIS/QUARK/NEST'
PASSING XMLTYPE (
'<BASIS>
<QUARK P1="up" P2="charm" P3="bottom">
<NEST>
<ONE>A</ONE>
<TWO>B</TWO>
<THREE>C</THREE>
<FOUR>D</FOUR>
<FIVE>E</FIVE>
<SIX>F</SIX>
<SEVEN>G</SEVEN>
<EIGHT>H</EIGHT>
<NINE>I</NINE>
</NEST>
</QUARK>
<QUARK P1="up" P2="strange" P3="top">
<NEST>
<ONE>J</ONE>
<TWO>K</TWO>
<THREE>L</THREE>
<FOUR>M</FOUR>
<FIVE>N</FIVE>
<SIX>O</SIX>
<SEVEN>P</SEVEN>
<EIGHT>Q</EIGHT>
<NINE>R</NINE>
</NEST>
</QUARK>
</BASIS>')
-- ...and I changed all the paths here
COLUMNS quark_p1 VARCHAR2(4) PATH '../@P1'
, quark_p2 VARCHAR2(7) PATH '../@P2'
, quark_p3 VARCHAR2(6) PATH '../@P3'
, one VARCHAR2(1) PATH 'ONE'
, two VARCHAR2(1) PATH 'TWO'
, three VARCHAR2(1) PATH 'THREE'
, four VARCHAR2(1) PATH 'FOUR'
, five VARCHAR2(1) PATH 'FIVE'
, six VARCHAR2(1) PATH 'SIX'
, seven VARCHAR2(1) PATH 'SEVEN'
, eight VARCHAR2(1) PATH 'EIGHT'
, nine VARCHAR2(1) PATH 'NINE'
) x;
END;
/
Это, мне кажется, что это должно работать, но я получаю эту ошибку:
FROM XMLTABLE('/BASIS/QUARK/NEST'
*
ERROR at line 28:
ORA-06550: line 28, column 10:
PL/SQL: ORA-19110: unsupported XQuery expression
ORA-06550: line 2, column 5:
PL/SQL: SQL Statement ignored
SQL>
я упускаю что-то простое, или я не могу отсюда?
Спасибо.
Разве это не так, что каждый элемент соответствие '/ BASIS/QUARK/NEST' будет рассматриваться как корень для каждой записи (я основываю это на всех тестах, которые я только что сделал, и я не смог достичь своей цели)? Поэтому вы не сможете ссылаться на родителя, потому что его не будет. Я не понимаю, почему вы хотите изменить свой код? И, еще один момент, чтобы обратиться к родителям, вы должны написать его так: '//../@ P1', с двойным знаком косой черты перед ним. –