Okamžitá chyba je způsobena tím, že výsledku zřetězení jsou přiděleny dva aliasy:Máte AS LIST as ids
. Výsledek výpočtu nelze přiřadit dva aliasy. Pokud chcete, aby nově vytvořená tabulka měla sloupec LIST
poté smažte as ids
a naopak.
Pak narazíte na další chybu:pokoušíte se ORDER BY t1.a
v agregaci. To nebude fungovat; nemůžete objednávat podle CLOB v agregaci XML. Opravdu vás zajímá, v jakém pořadí se agregace děje? Pokud ne, změňte to na ORDER BY NULL
. Pokud vás to zajímá, máte problém, protože v Oracle order_by_clause
prostě nelze seřadit podle výrazu CLOB. Budete muset vytvořit samostatný sloupec pro řazení pomocí jiných metod.
V řešení celkově není potřeba klauzule WITH. Kdekoli v dotazu odkazujete na „vstupní_řetězce“ (jiné než klauzuli WITH), jednoduše napište „tabulkové_výrazy“.
UPRAVIT
Zde je návod, jak by to mohlo fungovat. Nejprve ukážu příkazy CREATE TABLE. Budu předpokládat, že table_expressions
má sloupec CLOB vyhledávacích řetězců a že v tomto sloupci NEJSOU ŽÁDNÉ DUPLIKÁTY. I tak potřebuje tabulka samostatný primární klíč datového typu, který není LOB nebo jiný dlouhý, nestandardní typ. K tomu používám NUMBER.
Poté agreguji podle tohoto sloupce primárního klíče. Bohužel nemohu vybrat hledaný řetězec současně. Mohl jsem SELECT MAX(t2.a)
ale to nefunguje ani s hodnotami CLOB! Místo toho potřebuji další spojení, abych odpovídal primárnímu klíči vyhledávacímu řetězci. (Omlouváme se, dotaz bude kvůli tomu trvat mnohem déle...)
V agregaci seřadím podle prvních 4000 znaků hodnoty řetězce ze sloupce a
. Toto není tak dobré jako řazení podle celého vstupního řetězce, ale stále je to lepší než řazení podle NULL.
create table a_x ( a, b ) as
select to_clob('atveroeosipsumloremipsumdolor'), 1 from dual union all
select to_clob('stetclitakasdtest') , 2 from dual union all
select to_clob('noseatakimataatveroeosipsum') , 3 from dual union all
select to_clob('loremipsumdolor') , 4 from dual union all
select to_clob('consetetursadipscingelitr') , 5 from dual
;
create table table_expressions ( a, pk ) as
select to_clob('atveroeosipsum') , 10 from dual union all
select to_clob('test') , 11 from dual union all
select to_clob('stetclitakasd') , 12 from dual union all
select to_clob('noseatakimata') , 13 from dual union all
select to_clob('loremipsumdolor') , 14 from dual union all
select to_clob('consetetursadipscingelitr'), 15 from dual
;
create table a_y as
select te.a, s.ids
from table_expressions te
join
(select t2.pk, RTRIM(XMLAGG(XMLELEMENT(E,t1.a,',').EXTRACT('//text()')
ORDER BY cast(t1.a as varchar2(4000))).GetClobVal(),',') as ids
from a_x t1
join table_expressions t2
on t1.a like '%' || t2.a || '%'
group by t2.pk
) s
on te.pk = s.pk
;
Nyní se podívejme, co máme:
select * from a_y;
A IDS
------------------------- ---------------------------------------------------------
atveroeosipsum atveroeosipsumloremipsumdolor,noseatakimataatveroeosipsum
test stetclitakasdtest
stetclitakasd stetclitakasdtest
noseatakimata noseatakimataatveroeosipsum
loremipsumdolor atveroeosipsumloremipsumdolor,loremipsumdolor
consetetursadipscingelitr consetetursadipscingelitr
ÚPRAVA #2
Pokud potřebujete zřetězit id z tabulky a_x
(sloupec b
), nikoli samotné CLOB, pak nahraďte t1.a
s t1.b
(a v ORDER BY
klauzule XMLAGG
, nepotřebujete žádné cast
, stačí order by t1.b
).
drop table a_y purge;
create table a_y as
select te.a, s.ids
from table_expressions te
join
(select t2.pk, RTRIM(XMLAGG(XMLELEMENT(E,t1.b,',').EXTRACT('//text()')
ORDER BY t1.b).GetClobVal(),',') as ids
from a_x t1
join table_expressions t2
on t1.a like '%' || t2.a || '%'
group by t2.pk
) s
on te.pk = s.pk
;
select * from a_y;
A IDS
------------------------- ---
atveroeosipsum 1,3
test 2
stetclitakasd 2
noseatakimata 3
loremipsumdolor 1,4
consetetursadipscingelitr 5