我使用的是Oracle 10g,并具有以下表结构:id,段落
我想按ID分组并连接段落。每个段落可能超过1500个字符。
当我尝试wm_concat函数时,它抱怨字符串缓冲区太小。实际上,我在Oracle网站上尝试了许多示例,但所有示例均因字符串缓冲区太小而失败。
select id, wm_concat(paragraph) from paragraphs group by id
我该如何解决?
因此,我猜是错误的所在ORA-06502,我可以看到您在这种情况下如何认为这不适用于您。
ORA-06502
但是,这是的错wm_concat。这是一个函数,并受PL \ SQL中Oracle的最大varchar长度(32,767和标准SQL中的4,000)的约束。不幸的是,由于wm_concat的工作方式或函数中的任何较低约束,或者由于您在select中使用它,因此我认为您无法获得接近上限的任何信息。
wm_concat
还有另一个选项,straggTom Kyte的字符串聚合函数。如果我们看一下两者之间的以下比较,您会发现它们的性能几乎相同,并且两者的长度上限均为4,000,即标准SQL的最大值。stragg快一些,可能是由于缓存。
stragg
SQL> set serveroutput on SQL> SQL> create table tmp_test ( a varchar2(30) ); Table created. SQL> insert into tmp_test 2 select object_name 3 from all_objects 4 ; 81219 rows created. SQL> commit ; Commit complete. SQL> SQL> declare 2 3 i integer := 1; 4 k number(10); 5 v_stragg varchar2(32767); 6 v_test varchar2(32767) := ''; 7 start_time timestamp; 8 9 begin 10 11 select count(*) 12 into k 13 from tmp_test; 14 15 for i in 1 .. k loop 16 start_time := systimestamp; 17 begin 18 19 select wm_concat(a) into v_test 20 from tmp_test 21 where rownum < i; 22 23 exception when others then 24 dbms_output.put_line('wm_concat: ' || length(v_test)); 25 dbms_output.put_line(systimestamp - start_time); 26 exit; 27 end; 28 end loop; 29 30 for i in 1 .. k loop 31 start_time := systimestamp; 32 33 select stragg(a) into v_test 34 from tmp_test 35 where rownum < i; 36 37 if v_test = 'OVERFLOW' then 38 dbms_output.put_line('stragg: ' || length(v_stragg)); 39 dbms_output.put_line(systimestamp - start_time); 40 exit; 41 else v_stragg := v_test; 42 end if; 43 end loop; 44 end; 45 / wm_concat: 3976 +000000000 00:00:00.005886000 stragg: 3976 +000000000 00:00:00.005707000 PL/SQL procedure successfully completed.
至于解决,恐怕你做不到。一旦达到该极限就可以了。您将必须找到一种不同的汇总方法,或者问自己是否 确实 需要这样做。