如何在 oracle XMLTYPE XMLTABLE 中支持 1 级路径目录
Posted
技术标签:
【中文标题】如何在 oracle XMLTYPE XMLTABLE 中支持 1 级路径目录【英文标题】:how to back 1 level of path directory in oracle XMLTYPE XMLTABLE 【发布时间】:2021-06-21 16:36:24 【问题描述】:我试图在路径中支持 1 级文件夹,但它不是工作属性。 我尝试使用“../”和“./”但没有用。 我如何在 Oracle 中做到这一点?
WITH xmlPrePos as
(
select
IDPraga,
IDUsina,
replace(valor, '<?xml version="1.0" encoding="utf-16"?>','') as XML
from dbo_Config
where SiglaCategoria = 'ConfigFiltros' and Sigla='ConfigFiltros'
)
SELECT
IDPraga,
IDUsina,
IDTpVinculo,
Descricao,
Reforma
FROM xmlPrePos,
xmltable('/ConfiguracaoFiltros/TpVinculoConfigFiltros/TpVinculoConfigFiltros'
passing XMLTYPE(xmlPrePos.XML)
COLUMNS
IDTpVinculo INT path 'IDTpVinculo',
Descricao VARCHAR(100) path 'Descricao',
Reforma VARCHAR(100) path '../../SituacaoAreasConfigFiltros/Reforma');
最后一行是我遇到问题的代码。 我的回报是空的。
XML>
<ConfiguracaoFiltros xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SituacaoAreasConfigFiltros>
<Reforma>VERDADEIRO</Reforma>
<Bloqueio>NAO_IMPORTA</Bloqueio>
</SituacaoAreasConfigFiltros>
<TpVinculoConfigFiltros>
<TpVinculoConfigFiltros>
<IDTpVinculo>11</IDTpVinculo>
<Descricao>ARRENDAMENTO / PARCERIA</Descricao>
</TpVinculoConfigFiltros>
<TpVinculoConfigFiltros>
<IDTpVinculo>12</IDTpVinculo>
<Descricao>PROPRIA</Descricao>
</TpVinculoConfigFiltros>
</TpVinculoConfigFiltros>
</ConfiguracaoFiltros>
版本>
Oracle 数据库 11g 企业版版本 11.1.0.6.0 - 64 位生产 PL/SQL 版本 11.1.0.6.0 - 生产 “核心 11.1.0.6.0 生产” 适用于 Linux 的 TNS:版本 11.1.0.6.0 - 生产 NLSRTL 版本 11.1.0.6.0 - 生产
等待结果>
【问题讨论】:
请提供您的 oracle 版本和您的 xml 数据示例 ...以及您当前和预期的结果。为什么要去掉?xml
标头?
在问题中添加信息
11.1 是一个非常老旧且漏洞百出的版本...
我知道..但不幸的是公司仍在使用的版本
【参考方案1】:
由于在 11g 中返回树似乎不起作用,您可以改为使用两个 XMLTable 调用:
WITH xmlPrePos as
(
select
IDPraga,
IDUsina,
replace(valor, '<?xml version="1.0" encoding="utf-16"?>','') as XML
from dbo_Config
where SiglaCategoria = 'ConfigFiltros' and Sigla='ConfigFiltros'
)
SELECT
IDPraga,
IDUsina,
x2.IDTpVinculo,
x2.Descricao,
x1.Reforma
FROM xmlPrePos
CROSS JOIN xmltable(
'/ConfiguracaoFiltros'
passing XMLTYPE(xmlPrePos.XML)
COLUMNS
Reforma VARCHAR(100) path 'SituacaoAreasConfigFiltros/Reforma',
TpVinculoConfigFiltros xmltype path 'TpVinculoConfigFiltros'
) x1
CROSS JOIN xmltable(
'/TpVinculoConfigFiltros/TpVinculoConfigFiltros'
passing x1.TpVinculoConfigFiltros
COLUMNS
IDTpVinculo INT path 'IDTpVinculo',
Descricao VARCHAR(100) path 'Descricao'
) x2;
你的例子得到:
IDPRAGA IDUSINA IDTPVINCULO DESCRICAO REFORMA
------- ------- ----------- ----------------------- ----------
3 1 11 ARRENDAMENTO / PARCERIA VERDADEIRO
3 1 12 PROPRIA VERDADEIRO
db<>fiddle
正如@Sayan 所说,我也曾评论过,您不需要删除 XML 标头;它可以与它一起使用,并且不需要 CTE:
SELECT
dc.IDPraga,
dc.IDUsina,
x2.IDTpVinculo,
x2.Descricao,
x1.Reforma
FROM dbo_Config dc
CROSS JOIN xmltable(
'/ConfiguracaoFiltros'
passing XMLTYPE(dc.valor)
COLUMNS
Reforma VARCHAR(100) path 'SituacaoAreasConfigFiltros/Reforma',
TpVinculoConfigFiltros xmltype path 'TpVinculoConfigFiltros'
) x1
CROSS JOIN xmltable(
'/TpVinculoConfigFiltros/TpVinculoConfigFiltros'
passing x1.TpVinculoConfigFiltros
COLUMNS
IDTpVinculo INT path 'IDTpVinculo',
Descricao VARCHAR(100) path 'Descricao'
) x2;
db<>fiddle
【讨论】:
它就像一个魅力 \o/.. 非常感谢【参考方案2】:如果您的数据如下所示:
<?xml version="1.0" encoding="utf-16"?>
<ConfiguracaoFiltros>
<TpVinculoConfigFiltros>
<TpVinculoConfigFiltros>
<IDTpVinculo>1</IDTpVinculo>
<Descricao>Test1</Descricao>
</TpVinculoConfigFiltros>
</TpVinculoConfigFiltros>
<SituacaoAreasConfigFiltros>
<Reforma>Reforma Test1</Reforma>
</SituacaoAreasConfigFiltros>
</ConfiguracaoFiltros>
您可以在../../
之前简单地添加./
:
DBFiddle
WITH
dbo_Config as (
select
'ConfigFiltros' SiglaCategoria,
'ConfigFiltros' Sigla,
'IDPraga' IDPraga,
'IDUsina' IDUsina,
q'[<?xml version="1.0" encoding="utf-16"?>
<ConfiguracaoFiltros>
<TpVinculoConfigFiltros>
<TpVinculoConfigFiltros>
<IDTpVinculo>1</IDTpVinculo>
<Descricao>Test1</Descricao>
</TpVinculoConfigFiltros>
</TpVinculoConfigFiltros>
<SituacaoAreasConfigFiltros>
<Reforma>Reforma Test1</Reforma>
</SituacaoAreasConfigFiltros>
</ConfiguracaoFiltros>
]' as valor
from dual
)
,xmlPrePos as
(
select
IDPraga,
IDUsina,
replace(valor, '<?xml version="1.0" encoding="utf-16"?>','') as XML
from dbo_Config
where SiglaCategoria = 'ConfigFiltros' and Sigla='ConfigFiltros'
)
SELECT
IDPraga,
IDUsina,
IDTpVinculo,
Descricao,
Reforma
FROM xmlPrePos,
xmltable('/ConfiguracaoFiltros/TpVinculoConfigFiltros/TpVinculoConfigFiltros'
passing XMLTYPE(xmlPrePos.XML)
COLUMNS
IDTpVinculo INT path 'IDTpVinculo',
Descricao VARCHAR(100) path 'Descricao',
Reforma VARCHAR(100) path './../../SituacaoAreasConfigFiltros/Reforma');
但我不会删除 <?xml ...?>
标头:
DBFiddle2
WITH
dbo_Config as (
select
'ConfigFiltros' SiglaCategoria,
'ConfigFiltros' Sigla,
'IDPraga' IDPraga,
'IDUsina' IDUsina,
q'[<?xml version="1.0" encoding="utf-16"?>
<ConfiguracaoFiltros>
<TpVinculoConfigFiltros>
<TpVinculoConfigFiltros>
<IDTpVinculo>1</IDTpVinculo>
<Descricao>Test1</Descricao>
</TpVinculoConfigFiltros>
</TpVinculoConfigFiltros>
<SituacaoAreasConfigFiltros>
<Reforma>Reforma Test1</Reforma>
</SituacaoAreasConfigFiltros>
</ConfiguracaoFiltros>
]' as valor
from dual
)
,xmlPrePos as
(
select
IDPraga,
IDUsina,
valor as XML
from dbo_Config
where SiglaCategoria = 'ConfigFiltros' and Sigla='ConfigFiltros'
)
SELECT
IDPraga,
IDUsina,
IDTpVinculo,
Descricao,
Reforma
FROM xmlPrePos,
xmltable('/ConfiguracaoFiltros/TpVinculoConfigFiltros/TpVinculoConfigFiltros'
passing XMLTYPE(xmlPrePos.XML)
COLUMNS
IDTpVinculo INT path 'IDTpVinculo',
Descricao VARCHAR(100) path 'Descricao',
Reforma VARCHAR(100) path './../../SituacaoAreasConfigFiltros/Reforma');
相同的示例,但您在 DBFiffle 上更新了数据: https://dbfiddle.uk/?rdbms=oracle_11.2&fiddle=23c0d9d500d0b87f1bc3469efd4960b9
【讨论】:
我试过了,但返回 NULL 应该带“VERDADEIRO”.. 或“Reforma Test1”(在你的 xml 示例中) “改革”列不断返回 NULL @FernandoFefu 是的,我只记得 11.1 中有一个错误。等一下,我将添加另一个答案并提供解决方法【参考方案3】:Oracle
WITH
dbo_Config as (
select
'ConfigFiltros' SiglaCategoria,
'ConfigFiltros' Sigla,
'IDPraga' IDPraga,
'IDUsina' IDUsina,
q'[<ConfiguracaoFiltros xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SituacaoAreasConfigFiltros>
<Reforma>VERDADEIRO</Reforma>
<Bloqueio>NAO_IMPORTA</Bloqueio>
</SituacaoAreasConfigFiltros>
<TpVinculoConfigFiltros>
<TpVinculoConfigFiltros>
<IDTpVinculo>11</IDTpVinculo>
<Descricao>ARRENDAMENTO / PARCERIA</Descricao>
</TpVinculoConfigFiltros>
<TpVinculoConfigFiltros>
<IDTpVinculo>12</IDTpVinculo>
<Descricao>PROPRIA</Descricao>
</TpVinculoConfigFiltros>
</TpVinculoConfigFiltros>
</ConfiguracaoFiltros>
]' as valor
from dual
)
,xmlPrePos as
(
select
IDPraga,
IDUsina,
valor as XML
from dbo_Config
where SiglaCategoria = 'ConfigFiltros' and Sigla='ConfigFiltros'
)
SELECT
IDPraga,
IDUsina,
xdata.*
FROM xmlPrePos,
xmltable(
'
for $x in ./ConfiguracaoFiltros
for $y in $x/TpVinculoConfigFiltros/TpVinculoConfigFiltros
return <row>
$y
$x/SituacaoAreasConfigFiltros/Reforma
</row>'
passing XMLTYPE(xmlPrePos.XML)
COLUMNS
xdata xmltype path '.',
IDTpVinculo INT path './TpVinculoConfigFiltros/IDTpVinculo',
Descricao VARCHAR(100) path './TpVinculoConfigFiltros/Descricao',
Reforma VARCHAR(100) path 'Reforma'
) xdata;
【讨论】:
以上是关于如何在 oracle XMLTYPE XMLTABLE 中支持 1 级路径目录的主要内容,如果未能解决你的问题,请参考以下文章
如何在 oracle XMLTYPE XMLTABLE 中支持 1 级路径目录
如何使用 java.sql 包中的 rs.getSQLXML() 函数从 Oracle 数据库中获取 XMLType 列?