oracle - 如何在 oracle XMLTable 的 xpath 中将外部函数作为变量传递
问题描述
我有一个这样的xml文件:
<GroupList>
<Group>
<Title>
<Name>Computer</Name>
<Title>
<Type>
<Name>Book</Name>
</Type>
<DataList>
<DataElement>
<Name>Comment</Name>
<Type>text</Type>
<Value>ABC</Value>
<Ordinality>1</Ordinality>
</DataElement>
<DataElement>
<Name>Location</Name>
<Type>set</Type>
<Value>123</Value>
<Ordinality>1</Ordinality>
</DataElement>
</DataList>
</Group>
</GroupList>
我正在尝试将外部函数作为 xpath 中的变量传递,我需要获取 DataElment/Name ='Location' 值。
这是查询片段:
SELECT *
FROM wd,
XMLTABLE (
'GroupList/Group[Title/Name=''Computer'']'
PASSING xmltype(wd.data), externalfunction as "i"
COLUMNS
name VARCHAR2(200) PATH 'Title/Name'
,type VARCHAR2(200) PATH 'Type/Name'
,location VARCHAr2(200) PATH 'DataElementList/dataElement[$i]/Name'
,location_value VARCHAR2(200) PATH 'DataElementList/dataElement[$i]/Value'
) x
外部函数返回一个数字,当我运行查询时,出现此错误:
ORA-19112: error raised during evaluation: XVM-01008: [XPST0008] Invalid reference
1 DataElementList/dataElement[$i]/Value
将变量 i 传递给 xpath 的正确方法是什么?谢谢您的帮助。
解决方案
@Tina 不确定如何在单个查询中实现,但我已经通过循环拥有一个表来做到这一点。以下是可以通过程序完成的代码......我只是想分享它是否有帮助
create table DataElement with fields Name, Type,value and Ordinality
PROCEDURE GET_DataElement(
in_xml_frag IN CLOB,
in_table_name IN VARCHAR2,
out_xml_rec OUT DataElement%ROWTYPE)
IS
v_xml_rec DataElement%ROWTYPE;
v_row_value VARCHAR2(100);
v_row_division CLOB ;
v_xml SYS.XMLTYPE := XMLTYPE(in_xml_frag);
CURSOR table_fields_rec
IS
SELECT column_name,
data_length column_size,
data_type,
table_name
FROM all_tab_columns
WHERE TABLE_NAME = in_table_name
ORDER BY column_id ASC;
BEGIN
FOR rec IN table_fields_rec
LOOP
IF (v_xml.existsNode('/' || rec.table_name || '/' || rec.column_name || '/text()') = 1) THEN
v_row_value := v_xml.EXTRACT('/' || rec.table_name || '/' || rec.column_name ||'/text()') .GETSTRINGVAL();
v_row_value := COMMON_TOOLS.ELIMINATE_SPECIAL_CHRCTRS(v_row_value);
CASE rec.column_name
WHEN 'Name' THEN
v_xml_rec.Name := v_row_value;
WHEN 'Type' THEN
v_xml_rec.Type := v_row_value;
WHEN 'value' THEN
v_xml_rec.value := v_row_value;
WHEN 'Ordinality' THEN
v_xml_rec.Ordinality := v_row_value;
ELSE
NULL;
END CASE;
ELSE
NULL;
END IF;
END LOOP;
out_xml_rec := v_xml_rec;
END GET_DataElement;
推荐阅读
- c# - 如何播放和暂停 MediaElement?
- android - Android Studio 无法正确绘制按钮
- service - 如何在 Flutter 中创建定时服务
- excel - 引用范围内的单元格
- neo4j - 如何在不使用 MERGE Neo4J 3.5 的情况下防止重复关系?
- reactjs - 在 React Material Container Component 内部滚动不流畅
- android - Android 均衡器在 android 9 设备中不起作用
- css - CSS多列 - 段落分组?
- c# - 如何在 SQL Server 中查找中间有错误空格的数据?
- google-analytics - 谷歌分析:谷歌信号依赖什么查询字符串参数?