Question

Je suis sur Oracle 10g et ont la structure de tableau suivant: id, paragraphe

Je veux groupe par id et concaténer les paragraphes. Chaque paragraphe peut-être 1500 caractères ou plus.

Lorsque je tente la fonction wm_concat, il se plaint que la mémoire tampon de chaîne est trop petite. J'ai essayé beaucoup d'exemples sur le site Web d'Oracle et tous échouent avec l'erreur la mémoire tampon de chaîne est trop petite.

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

comment puis-je résoudre ce problème?

Était-ce utile?

La solution

Alors, je devine l'erreur est ORA-06502 et je peux voir comment vous pourriez penser que cela vous ne s'applique pas dans cette situation.

Cependant, cela est la faute de wm_concat. Ceci est une fonction et est limitée par la longueur maximale de varchar Oracle PL \ SQL de 32767 et 4000 dans la norme SQL. Malheureusement, je suppose, à cause de la façon dont wm_concat œuvres ou à cause de contraintes plus faibles au sein de la fonction ou parce que vous utilisez dans un que vous sélectionnez ne trouverez nulle part près de la limite supérieure.

Il y a une autre option, stragg , chaîne de Tom Kyte fonction d'agrégation. Si nous regardons la comparaison suivante entre les deux, vous verrez qu'ils effectuent à peu près identique et que la limite des deux est une longueur d'environ 4000, à savoir le maximum standard SQL. stragg est légèrement plus rapide, probablement en raison de la mise en cache.

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 ce qui concerne la résolution, je crains que vous ne pouvez pas. Une fois que vous appuyez sur cette limite qui est tout. Vous devez trouver une autre façon de faire vos agrégations ou demandez-vous si vous vraiment besoin.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top