Frage

Ich bin auf Oracle 10g und habe die folgende Tabellenstruktur: ID, Absatz

Ich möchte die Absätze nach ID gruppieren und verkettet. Jeder Absatz vielleicht 1500 Zeichen oder mehr.

Wenn ich die WM_CONCAT -Funktion versuche, beschwert sich der String -Puffer zu klein. Ich habe tatsächlich viele Beispiele auf der Website von Oracle ausprobiert, und sie alle fehlen mit dem Fehler, den der String -Puffer zu klein ist.

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

Wie löse ich das?

War es hilfreich?

Lösung

Ich vermute also, der Fehler ist ORA-06502 Und ich kann sehen, wie Sie denken, dass dies in dieser Situation nicht auf Sie zutrifft.

Dies ist jedoch die Schuld von wm_concat. Dies ist eine Funktion und wird durch die maximale Varchar -Länge von Oracle in PL sql von 32.767 und 4.000 in Standard -SQL eingeschränkt. Leider nehme ich an, aufgrund der Art und Weise, wie WM_CONCAT funktioniert oder aufgrund von geringeren Einschränkungen innerhalb der Funktion oder weil Sie es in einem Auswahl verwenden, können Sie nicht in der Nähe der Obergrenze erhalten.

Es gibt eine andere Option, stragg, Tom Kytes String -Aggregat -Funktion. Wenn wir uns den folgenden Vergleich zwischen den beiden ansehen, werden Sie feststellen, dass sie fast identisch abschneiden und dass die Grenze von beiden eine Länge von rund 4.000 beträgt, dh das Standard -SQL -Maximum. stragg ist etwas schneller, wahrscheinlich aufgrund von Caching.

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.

Ich fürchte, Sie können es nicht können. Sobald Sie diese Grenze erreicht haben, war das. Sie müssen eine andere Möglichkeit finden, Ihre Aggregationen durchzuführen oder sich zu fragen, ob Sie Ja wirklich müssen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top