在预期位置找不到 FROM 关键字,文本选择 Oracle SQL



我想生成一个表,其中包含子字符串和另一个表的ID,子字符串出现在那里。请参阅问题连接值。

create table table_expressions
(
A clob
);
insert all
into table_expressions (a) values ('atveroeosipsum')
into table_expressions (a) values ('test') 
into table_expressions (a) values ('stetclitakasd') 
into table_expressions (a) values ('noseatakimata') 
into table_expressions (a) values ('loremipsumdolor') 
into table_expressions (a) values ('consetetursadipscingelitr') 
select * from dual;
create table a_x
(
A clob,
B clob
);
insert all
into a_x (a, b) values('atveroeosipsumloremipsumdolor', 1)
into a_x (a, b) values('stetclitakasdtest', 2) 
into a_x (a, b) values('noseatakimataatveroeosipsum', 3)
into a_x (a, b) values('loremipsumdolor', 4)
into a_x (a, b) values('consetetursadipscingelitr', 5)
select * from dual;
create table a_y 
as 
with 
input_strings ( a ) as ( 
select column_value from table_expressions 
) 
select t2.a, listagg(t1.b, ',') within group (order by t1.b) 
as ids from a_x t1 join input_strings t2 on t1.a like '%' || t2.a || '%' 
group by t2.a 

table_expressions包含所需的子字符串 我的真实数据会产生相当多的ID来连接。使用真实数据运行代码后,01489. 00000 - "result of string concatenation is too long" *Cause: String concatenation result is more than the maximum size. *Action: Make sure that the result is less than the maximum size.发生错误。

如何重写代码以将生成的列IDs格式化为 CLOB 格式? 我查看了问题Listagg函数,但我不理解发布的答案中的代码。

此代码:

create table a_y
as
with
input_strings ( a ) as (
select a
from table_expressions                    
)
select   t2.a, RTRIM(XMLAGG(XMLELEMENT(E,t1.a,',').EXTRACT('//text()') ORDER BY t1.a).GetClobVal(),',') AS LIST as ids
from     a_x t1 
join input_strings t2 on t1.a like '%' || t2.a || '%'
group by t2.a
;

产生错误FROM keyword not found where expected。 我想生成一个表格a_y,它应该是这样的,A列和IDs应该是 clob 格式:

A                            | IDs                                    
-----------------------------|-------
atveroeosipsum               | 1,3
test                         | 2
stetclitakasd                | 2
noseatakimata                | 3
loremipsumdolor              | 1,4
consetetursadipscingelitr    | 5

我该如何解决这个问题?

直接错误是由为串联结果提供两个别名引起的:您有AS LIST as ids.不能为计算结果指定两个别名。如果您希望新创建的表具有列LIST则删除as ids,反之亦然。

然后,您将遇到另一个错误:您正在尝试在聚合中ORDER BY t1.a。那行不通;不能在 XML 聚合中按 CLOB 排序。你真的关心聚合发生的顺序吗?如果没有,请更改为ORDER BY NULL。如果你关心,你就有问题了,因为在 Oracle 中,order_by_clause根本无法按 CLOB 表达式排序。您必须使用其他方法创建一个单独的列以进行排序。

在整体解决方案中,不需要 WITH 子句。无论您在查询中引用"input_strings"(WITH 子句除外),只需编写"table_expressions"。

编辑

这是如何使其工作的方法。首先,我将展示 CREATE TABLE 语句。我将假设table_expressions有一个搜索字符串的CLOB列,并且此列中没有重复项。即便如此,该表还需要一个单独的主键,其数据类型不是 LOB 或其他长的非标准类型。我为此使用数字。

然后我按此主键列进行聚合。唉,我不能同时选择搜索字符串。我可以SELECT MAX(t2.a)但这也不适用于 CLOB 值!相反,我需要进一步的连接来将主键与搜索字符串匹配。(抱歉,因此查询将花费更长的时间...

在聚合中,我按列a中字符串值的前 4000 个字符进行排序。这不如按整个输入字符串排序,但它仍然比按 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
;

现在让我们检查一下我们得到了什么:

select * from a_y;
A                          IDS
-------------------------  ---------------------------------------------------------
atveroeosipsum             atveroeosipsumloremipsumdolor,noseatakimataatveroeosipsum
test                       stetclitakasdtest
stetclitakasd              stetclitakasdtest
noseatakimata              noseatakimataatveroeosipsum
loremipsumdolor            atveroeosipsumloremipsumdolor,loremipsumdolor
consetetursadipscingelitr  consetetursadipscingelitr

编辑#2

如果您需要连接表a_x中的 id(第b列),而不是 CLOB 本身,则将t1.a替换为t1.b(并且在XMLAGGORDER BY子句中,您不需要任何cast,只需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

相关内容

  • 没有找到相关文章

最新更新