#sql #oracle
Вопрос:
Я пытаюсь восстановить 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 Database 11g Enterprise Edition Выпуск 11.1.0.6.0 — 64-битный выпуск PL/SQL Выпуск 11.1.0.6.0 — Производство «ЯДРО 11.1.0.6.0 Производство» TNS для Linux: Версия 11.1.0.6.0 — Производство NLSRTL Версия 11.1.0.6.0 — Производство
Ожидаемый результат>
Комментарии:
1. Пожалуйста, предоставьте свою версию oracle и пример ваших xml-данных
2. … и ваши текущие и ожидаемые результаты. Почему ты убираешь
?xml
заголовок?3. добавлена информация в вопросе
4. 11.1-очень старая и глючная версия…
5. Я знаю это … но, к сожалению, это версия, которую компания все еще использует
Ответ №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
Как сказал @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;
Комментарии:
1. это работает как заклинание о/.. большое спасибо
Ответ №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.2amp;fiddle=23c0d9d500d0b87f1bc3469efd4960b9
Комментарии:
1. Я попробовал это, но возвращаемое значение равно NULL, где должно быть «VERDADEIRO».. или «Reforma Test1» (в примере yout xml)
2. столбцы «Реформа» продолжают возвращать значение NULL
3. @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;