如何在 Oracle XMLTable() 中将 XPath 与类似 '/abc/[contract = $count]/initialValue' 的变量一起使用?
例如:
XMLTable('root/level1', PASSING xmlContent
COLUMNS initial_value varchar2(100) PATH '/abc/[contract = $count]/initialValue'
)
如何替换/评估 $count 运行时?
您可以传入变量,只需在您的传递子句中定义它们:
with table1 AS
(select xmltype(
'<abc>
<def>
<contract>1</contract>
<oper>SFO</oper>
<lmt>limit1</lmt>
</def>
<def>
<contract>2</contract>
<oper>boston</oper>
<lmt >limit2</lmt>
</def>
</abc>'
) xmlcol from dual
)
SELECT u.*
FROM table1
, XMLTable('/abc/def[contract = $count]'
PASSING xmlcol, 1 as "count"
COLUMNS contract integer path 'contract',
oper VARCHAR2(20) PATH 'oper' ) u
CONTRACT OPER
---------- --------------------
1 SFO
如果在外部 pl/sql 块中定义了“count”变量,则使用 table() 代替,因为 xmltable 路径必须是字符串文字,并且不允许拼接变量。
我假设你的 xml 结构是
<root>
<level1>
<abc>
<contract>3</contract>
<initialValue>4</initialValue>
</abc>
</level1>
</root>
SQL> declare
2 v_count number := 3;
3 begin
4 for r_row in (select extractvalue(value(my_table), '/level1/abc[contract = "' || v_count || '"]/initialValue') xml
5 from table(
6 xmlsequence(
7 extract(XMLType('<root>
8 <level1>
9 <abc>
10 <contract>3</contract>
11 <initialValue>4</initialValue>
12 </abc>
13 </level1>
14 <level1>
15 <abc>
16 <contract>3</contract>
17 <initialValue>7</initialValue>
18 </abc>
19 </level1>
20 <level1>
21 <abc>
22 <contract>4</contract>
23 <initialValue>24</initialValue>
24 </abc>
25 </level1>
26 </root>'),
27 '/root/level1'))) my_table)
28 loop
29 dbms_output.put_line(r_row.xml);
30 end loop;
31 end;
32 /
4
7
使用 xmltable 执行此操作的方法不是将其放入 XPAth,而是在之后的 where 子句中进行过滤:
SQL> declare
2 v_count number := 3;
3 begin
4 for r_row in (select *
5 from XMLTable( 'root/level1' passing xmltype('<root>
6 <level1>
7 <abc>
8 <contract>3</contract>
9 <initialValue>4</initialValue>
10 </abc>
11 </level1>
12 <level1>
13 <abc>
14 <contract>3</contract>
15 <initialValue>7</initialValue>
16 </abc>
17 </level1>
18 <level1>
19 <abc>
20 <contract>4</contract>
21 <initialValue>24</initialValue>
22 </abc>
23 </level1>
24 </root>')
25 columns initial_value varchar2(100) PATH 'abc/initialValue',
26 contract varchar2(100) PATH 'abc/contract')
27 where contract = v_count)
28 loop
29 dbms_output.put_line(r_row.initial_value);
30 end loop;
31 end;
32 /
4
7