我正在使用Oracle DBMS,并且有一个表,其中一个字段包含XML代码,因此我希望从该字段创建一个View。同一视图应包含一组属性,如拥有XML的那些属性。 我已经有了一个解决方案,但它太麻烦了(大约有50个字段),并希望加快这个过程。
具有该属性的一段代码 ....
<AREAMEDIC200 titulo="campo1; " valor="False" />
<AREAMEDIC210 titulo="campo2; " valor="False" />
<AREAMEDIC220 titulo="campo3; " valor="True" />
...
SQL的一部分
CREATE VIEW teste AS
Select NPROCESSO,
trim(extract(MENUXML, '//AREAMEDIC200/@valor')) AS c1,
trim(extract(MENUXML, '//AREAMEDIC210/@valor')) AS c2,
trim(extract(MENUXML, '//AREAMEDIC220/@valor')) AS c3,
.....
FROM TABELA1;
任何人都有任何建议可以加快开发速度吗?
问候
答案 0 :(得分:0)
假设MENUXML
的类型为XMLType,并且具有根节点,则可以使用xmltable
将值提取为行:
select t.nprocesso, x.titulo, x.valor
from tabela1 t,
xmltable('/TOPLEVEL/*' passing t.menuxml
columns titulo varchar2(10) path '@titulo',
valor varchar2(5) path '@valor') x
NPROCESSO TITULO VALOR
---------- ---------- -----
1 campo1; False
1 campo2; False
1 campo3; True
然后你可以将它转移到列中,但是你仍然必须在某处列出可能的值 - 值的数量必须被称为解析时间,所以它不能完全灵活:
select *
from (
select t.nprocesso, rtrim(x.titulo, ';') as titulo, x.valor
from tabela1 t,
xmltable('/TOPLEVEL/*' passing t.menuxml
columns titulo varchar2(10) path '@titulo',
valor varchar2(5) path '@valor') x
)
pivot (min(valor) as v for (titulo) in ('campo1' as campo1, 'campo2' as campo2,
'campo3' as campo3))
... 除了导致11.2.0.3中的核心转储(ORA-07445: exception encountered: core dump [evaopn3()+125] [SIGSEGV]
如果您感兴趣,除NO_XML_QUERY_REWRITE
提示外可能会注意到1580106.1没有帮助。)
由于你实际上并没有说过你的11g,假装一个支点的旧方法仍然有效,但稍微多一些工作:
select nprocesso,
max(case when titulo = 'campo1; ' then valor end) as campo1,
max(case when titulo = 'campo2; ' then valor end) as campo2,
max(case when titulo = 'campo3; ' then valor end) as campo3
from (
select t.nprocesso, x.titulo, x.valor
from tabela1 t,
xmltable('/TOPLEVEL/*' passing t.menuxml
columns titulo varchar2(10) path '@titulo',
valor varchar2(5) path '@valor') x
)
group by nprocesso
order by nprocesso;
NPROCESSO CAMPO1 CAMPO2 CAMPO3
---------- ------ ------ ------
1 False False True
SQL Fiddle demo。只要包含提示,pivot
版本就可以在那里工作(我相信11.2.0.2)。
您只需要为50个可能值中的每一个重复max...
子句。不确定你是否会认为这比你现在所做的更容易。
编辑:如果MENUXML
确实是varchar2
,您可以将其转换为XMLType,并同时添加根节点,以便允许:
...
xmltable('/ROOT/*' passing xmltype('<ROOT>' || t.menuxml || '</ROOT>')
...