在预期的位置找不到 FROM 关键字,文本选择 Oracle SQL
FROM keyword not found where expected, text selection Oracle SQL
我想生成一个 table,其中包含另一个 table 的子字符串和 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 function,但我不理解发布的答案中的代码。
此代码:
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
。
我想生成一个 table a_y,它看起来应该是这样的,列 A
ans IDs
应该是 clob 格式:
A | IDs
-----------------------------|-------
atveroeosipsum | 1,3
test | 2
stetclitakasd | 2
noseatakimata | 3
loremipsumdolor | 1,4
consetetursadipscingelitr | 5
我该如何解决这个问题?
直接错误是由于为串联结果指定了两个别名引起的:您有 AS LIST as ids
。您不能为计算结果提供两个别名。如果你想让新创建的table有一个列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 列,并且该列中没有重复项。即便如此,table 还需要一个单独的主键,其数据类型不是 LOB 或其他非标准类型的长数据类型。我为此使用 NUMBER。
然后我按这个主键列聚合。唉,我不能同时select搜索字符串。我可以 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
如果您需要连接来自 table a_x
(列 b
)的 ID,而不是 CLOB 本身,则将 t1.a
替换为 t1.b
(并且,在 XMLAGG
的 ORDER 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
我想生成一个 table,其中包含另一个 table 的子字符串和 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 function,但我不理解发布的答案中的代码。
此代码:
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
。
我想生成一个 table a_y,它看起来应该是这样的,列 A
ans IDs
应该是 clob 格式:
A | IDs
-----------------------------|-------
atveroeosipsum | 1,3
test | 2
stetclitakasd | 2
noseatakimata | 3
loremipsumdolor | 1,4
consetetursadipscingelitr | 5
我该如何解决这个问题?
直接错误是由于为串联结果指定了两个别名引起的:您有 AS LIST as ids
。您不能为计算结果提供两个别名。如果你想让新创建的table有一个列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 列,并且该列中没有重复项。即便如此,table 还需要一个单独的主键,其数据类型不是 LOB 或其他非标准类型的长数据类型。我为此使用 NUMBER。
然后我按这个主键列聚合。唉,我不能同时select搜索字符串。我可以 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
如果您需要连接来自 table a_x
(列 b
)的 ID,而不是 CLOB 本身,则将 t1.a
替换为 t1.b
(并且,在 XMLAGG
的 ORDER 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