O erro imediato é causado por ter dois aliases dados ao resultado da concatenação:Você tem
AS LIST as ids
. Você não pode dar dois aliases ao resultado de um cálculo. Se você quiser que a tabela recém-criada tenha uma coluna LIST
em seguida, exclua as ids
, e vice versa. Então você encontrará outro erro:você está tentando
ORDER BY t1.a
na agregação. Isso não vai funcionar; você não pode ordenar por um CLOB na agregação XML. Você realmente se importa com a ordem em que a agregação acontece? Caso contrário, mude para ORDER BY NULL
. Se você se importa, você tem um problema, pois no Oracle um order_by_clause
simplesmente não pode ordenar por uma expressão CLOB. Você terá que criar uma coluna separada para ordenação usando outros métodos. Na solução geral, não há necessidade da cláusula WITH. Onde quer que você se refira a "input_strings" na consulta (além da cláusula WITH), simplesmente escreva "table_expressions".
EDITAR
Aqui está como isso poderia ser feito para funcionar. Primeiro, mostrarei as instruções CREATE TABLE. Presumirei que
table_expressions
tem uma coluna CLOB de strings de pesquisa e que NÃO HÁ DUPLICATAS nesta coluna. Mesmo assim, a tabela também precisa de uma chave primária separada, de um tipo de dados que não seja LOB ou outro tipo longo e não padrão. Eu uso NUMBER para isso. Então eu agrego por esta coluna de chave primária. Infelizmente, não consigo selecionar a string de pesquisa ao mesmo tempo. Eu poderia
SELECT MAX(t2.a)
mas isso também não funciona com valores CLOB! Em vez disso, preciso de mais uma junção para corresponder a chave primária à string de pesquisa. (Desculpe, a consulta levará muito mais tempo por causa disso...) Na agregação, classifico pelos primeiros 4.000 caracteres do valor da string da coluna
a
. Isso não é tão bom quanto ordenar por toda a string de entrada, mas ainda é melhor do que ordenar por 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
;
Agora vamos verificar o que temos:
select * from a_y;
A IDS
------------------------- ---------------------------------------------------------
atveroeosipsum atveroeosipsumloremipsumdolor,noseatakimataatveroeosipsum
test stetclitakasdtest
stetclitakasd stetclitakasdtest
noseatakimata noseatakimataatveroeosipsum
loremipsumdolor atveroeosipsumloremipsumdolor,loremipsumdolor
consetetursadipscingelitr consetetursadipscingelitr
EDIÇÃO #2
Se você precisar concatenar os ids da tabela
a_x
(coluna b
), não os próprios CLOBs, substitua t1.a
com t1.b
(e, no ORDER BY
cláusula de XMLAGG
, você não precisa de nenhum cast
, apenas 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