Ich vermute also, dass der Fehler ORA-06502
ist und ich verstehe, wie Sie vielleicht 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, dass Sie aufgrund der Funktionsweise von wm_concat oder aufgrund von niedrigeren Einschränkungen innerhalb der Funktion oder weil Sie es in einer Auswahl verwenden, nicht in die Nähe der Obergrenze kommen können.
Es gibt noch eine weitere Option, stragg
, die String-Aggregatfunktion von Tom Kyte. Wenn wir uns den folgenden Vergleich zwischen den beiden ansehen, werden Sie sehen, dass sie fast identisch funktionieren und dass die Grenze beider eine Länge von etwa 4.000 ist, d. h. 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 lösen. Sobald Sie diese Grenze erreicht haben, war es das. Sie müssen einen anderen Weg finden, Ihre Aggregationen durchzuführen, oder sich fragen, ob Sie wirklich müssen.