2012-01-11 27 views
5

estoy en Oracle 10g y tienen la siguiente estructura de la tabla: Identificación, párrafocómo concatenar cadenas?

Quiero grupo por id y concatenar los párrafos. Cada párrafo puede tener 1500 caracteres o más.

Cuando pruebo la función wm_concat, se queja de que el buffer de cadena es demasiado pequeño. De hecho, probé muchos de los ejemplos en el sitio web de Oracle y todos fallan con el error de que el buffer de cadenas es demasiado pequeño.

select id, wm_concat(paragraph) from paragraphs group by id 

¿cómo puedo resolver esto?

+0

¿Has probado esta solución (utilizando row_number() y sys_connect_by_path): http://www.oracle-base.com/articles/misc/StringAggregationTechniques.php#row_number –

Respuesta

3

Supongo que el error es ORA-06502 y puedo ver cómo podría pensar que esto no se aplica a usted en esta situación.

Sin embargo, esto es culpa de wm_concat. Esta es una función y está restringida por la longitud varchar máxima de Oracle en PL \ SQL de 32.767 y 4.000 en SQL estándar. Desafortunadamente, supongo que, debido a la forma en que funciona wm_concat o debido a cualquier restricción menor dentro de la función o porque la estás usando en una selección, no puedes llegar al límite superior.

Hay otra opción, stragg, la función de agregado de cadena de Tom Kyte. Si observamos la siguiente comparación entre los dos, verá que funcionan de manera casi idéntica y que el límite de ambos es una longitud de alrededor de 4.000, es decir, el máximo estándar de SQL. stragg es ligeramente más rápido, probablemente debido al almacenamiento en caché.

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. 

En cuanto a resolverlo, me temo que no puedes. Una vez que alcanzas ese límite eso es todo. Tendrá que encontrar una forma diferente de hacer sus agregaciones o preguntarse si realmente necesita .

Cuestiones relacionadas