Oracle
 sql >> Base de données >  >> RDS >> Oracle

comment concaténer des chaînes?

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

Cependant, c'est la faute de wm_concat . Il s'agit d'une fonction et est limitée par la longueur maximale de varchar d'Oracle en PL\SQL de 32 767 et 4 000 en SQL standard. Malheureusement, je suppose qu'en raison de la façon dont wm_concat fonctionne ou en raison de contraintes inférieures dans la fonction ou parce que vous l'utilisez dans une sélection, vous ne pouvez pas vous approcher de la limite supérieure.

Il existe une autre option, stragg , la fonction d'agrégation de chaînes de Tom Kyte. Si nous regardons la comparaison suivante entre les deux, vous verrez qu'ils fonctionnent presque de la même manière et que la limite des deux est une longueur d'environ 4 000, c'est-à-dire le maximum SQL standard. 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.

Quant à le résoudre, je crains que vous ne puissiez pas. Une fois que vous atteignez cette limite, c'est tout. Vous devrez trouver une autre façon de faire vos agrégations ou vous demander si vous vraiment besoin.