Pregunta

Estoy en Oracle 10G y tengo la siguiente estructura de la tabla: ID, párrafo

Quiero agrupar por identificación y concatenar los párrafos. Cada párrafo quizás 1500 caracteres o más.

Cuando intento la función WM_Concat, se queja de que el búfer 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 que el búfer de cadena es demasiado pequeño.

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

¿Cómo puedo solucionar esto?

¿Fue útil?

Solución

Entonces, 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, esta es la culpa de wm_concat. Esta es una función y está limitada por la longitud de Varchar máxima de Oracle en PL SQL de 32,767 y 4,000 en SQL estándar. Desafortunadamente, supongo, debido a la forma en que funciona WM_Concat o debido a cualquier restricción más baja dentro de la función o porque la está utilizando en una selección, no puede llegar al límite superior.

Hay otra opción, stragg, Función agregada de cadena de Tom Kyte. Si observamos la siguiente comparación entre los dos, verá que funcionan casi de manera idéntica y que el límite de ambos es una longitud de alrededor de 4,000, es decir, el máximo SQL estándar. stragg es un poco 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ás que encontrar una forma diferente de hacer tus agregaciones o preguntarte si De Verdad Necesitar.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top