sql - 我怎样才能摆脱这个查询中的 'ORA-01489: result of string concatenation is too long' ?

标签 sql oracle optimization

此查询获取网络中的主导集。例如给定一个网络

A<----->B<br/> B<----->C<br/> B<----->D<br/> C<----->E<br/> D<----->C<br/> D<----->E<br/> F<----->E

它返回
B、E
乙、丙
A、E
但它不适用于大数据,因为我在结果中使用字符串方法。我一直在尝试删除字符串方法并返回 View 或其他内容,但无济于事

With t as (select 'A' as per1, 'B' as per2 from dual union all
         select 'B','C' from dual union all
         select 'B','D' from dual union all
         select 'C','B' from dual union all
         select 'C','E' from dual union all
         select 'D','C' from dual union all
         select 'D','E' from dual union all
         select 'E','C' from dual union all
         select 'E','D' from dual union all
         select 'F','E' from dual)
 ,t2 as (select distinct least(per1, per2) as per1, greatest(per1, per2) as per2 from t union
       select distinct greatest(per1, per2) as per1, least(per1, per2) as per1 from t)
 ,t3 as (select per1, per2, row_number() over (partition by per1 order by per2) as rn from t2)
 ,people as (select per, row_number() over (order by per) rn
             from (select distinct per1 as per from t union
                   select distinct per2 from t)
            )
  ,comb   as (select sys_connect_by_path(per,',')||',' as p
              from   people
              connect by rn > prior rn
             )
  ,find   as (select p, per2, count(*) over (partition by p) as cnt
             from (
                   select distinct comb.p, t3.per2
                   from   comb, t3
                   where  instr(comb.p, ','||t3.per1||',') > 0 or instr(comb.p, ','||t3.per2||',') > 0
                  )
            )
 ,rnk as (select p, rank() over (order by length(p)) as rnk
          from find
          where cnt = (select count(*) from people)
          order by rnk
         )  select distinct trim(',' from p) as p from rnk  where rnk.rnk = 1`

最佳答案

Oracle 的限制之一是 SQL 无法处理超过 4000 个字符的 VARCHAR2。如果您尝试返回超过此大小的字符串,则会抛出 ORA-01489。理想情况下,您应该尝试将结果集分解为多个小行。或者,您可以将其作为 CLOB 返回。

编辑

how i can return the above as a CLOB

嗯...

仔细查看你的代码后,我认为唯一会抛出 ORA-1489 的地方就是这一行:

select sys_connect_by_path(per,',')||',' as p
from   people

将该调用包装在 TO_CLOB() 中会很容易。不幸的是,将 P 转换为 CLOB 会破坏一些后续处理('distinct p,partition by p`),因此它可能不是一个选项。抱歉。

至于其他解决方法......

您的站点有 Oracle Spatial 许可证吗?我知道没有多少网站这样做,但如果您是幸运的网站之一(并且您使用的是 10gR2 或更高版本),那么您应该查看 Oracle Spatial Network Data Model (PDF) .

否则,如果无法限制 sys_connect_by_path() 调用的输出,您可能只需在 PL/SQL 中实现这一点。您可以使用 PIPELINED FUNCTION返回最终输出,以便您仍然可以从 SELECT 语句调用它。

关于sql - 我怎样才能摆脱这个查询中的 'ORA-01489: result of string concatenation is too long' ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2533150/

相关文章:

python - 更新 SQLAlchemy 中的特定行

相同限制的 MySQL SELECT 查询越来越慢

mysql - DBMS 中最先进的 self 修复和 self 保护

javascript - CS5 隐藏层非常慢

optimization - 这是 “Large” GraphViz 图表吗?如何修复?

按照 IN 条件传递的顺序获取 MySQL 记录

mysql - MySQL 是否支持部分索引?

java - ORA-01792 : maximum number of columns in a table or view is 1000

php - 有人知道如何在 Zend 框架中将 Zend_db 组件与 oci8 一起使用吗?

python - 使用 NumPy 加速嵌套循环