come per concatenare le stringhe?
-
27-10-2019 - |
Domanda
Sono su Oracle 10g e hanno la seguente struttura della tabella: id, paragrafo
Voglio gruppo da id e concatenare i paragrafi. Ogni paragrafo forse 1500 caratteri o più.
Quando provo la funzione wm_concat, si lamenta che il buffer di stringa è troppo piccolo. Io in realtà provato molti degli esempi sul sito web di Oracle e tutti con l'errore il buffer di stringa è troppo piccolo.
select id, wm_concat(paragraph) from paragraphs group by id
come faccio a risolvere questo?
Soluzione
Quindi, sto cercando di indovinare l'errore è ORA-06502
e posso vedere come si potrebbe pensare che questo non si applica a voi in questa situazione.
Tuttavia, questo è colpa del wm_concat
. Questa è una funzione ed è vincolata da lunghezza massima varchar di Oracle in PL \ SQL di 32.767 e 4.000 in SQL standard. Purtroppo, presumo, a causa del modo in cui wm_concat lavori oa causa di eventuali vincoli inferiore all'interno della funzione o perché si sta utilizzando in un selezionato non può arrivare ovunque vicino al limite superiore.
C'è un'altra opzione, stragg
, funzione di aggregazione stringa di Tom Kyte. Se guardiamo il seguente confronto tra i due vedrete che essi svolgono in modo quasi identico e che il limite di entrambi è una lunghezza di circa 4.000, vale a dire la massima SQL standard. stragg
è leggermente più veloce, probabilmente a causa di 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.
Per quanto riguarda risolverlo, ho paura che non si può. Una volta che si ha colpito quel limite il gioco è fatto. Dovrete trovare un modo diverso di fare le vostre aggregazioni o chiedersi se si davvero necessità di.