2012-01-11 41 views
5

Oracle 10 g çıkıyorum ve Aşağıdaki tabloda yapıya sahiptir: id, id tarafından grubaDizeleri nasıl birleştirilir?

istediğim paragraf ve paragrafları bitiştirmek. Her paragraf 1500 karakterden fazla olabilir.

wm_concat işlevini denediğimde, dize arabelleğinin çok küçük olduğundan şikayet ediyor. Aslında Oracle'ın web sitesindeki birçok örneği denedim ve hepsi de string buffer'ın çok küçük olduğu hatayla başarısız oluyor.

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

Bunu nasıl çözerim?

+0

Bu çözümü denediniz mi (row_number() ve sys_connect_by_path kullanarak): http://www.oracle-base.com/articles/misc/StringAggregationTechniques.php#row_number –

cevap

3

Yani, hata ORA-06502 olduğunu tahmin ediyorum ve bunun bu durumun sizin için geçerli olmadığını düşündüğümüzü anlayabiliyorum. Ancak, bu wm_concat hatasıdır. Bu bir fonksiyondur ve Oracle'ın maksimum varchar uzunluğunu PL \ SQL'de 32,767 ve 4,000 standart SQL'de sınırlamaktadır. Ne yazık ki, wm_concat'in çalıştığı veya işlev içindeki herhangi bir alt kısıtlama nedeniyle veya bir seçimde kullandığınız için üst limitin yakınında bir yere ulaşamayacağınızı farz ediyorum.

Başka bir seçenek var, stragg, Tom Kyte'nin string toplama işlevi. İkisi arasında aşağıdaki karşılaştırmaya bakarsak, neredeyse aynı şekilde performans gösterdiklerini ve her ikisinin de sınırının 4000 civarında, yani standart SQL maksimum olduğunu göreceksiniz. stragg, muhtemelen önbelleğe alma nedeniyle biraz daha hızlıdır.

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. 

Bunu çözmek için gelince, korkarım ki yapamazsınız. O sınıra ulaştığınızda o kadar. Toplamalarınızı yapmanın farklı bir yolunu bulmanız veya 'un gerçekten gereksinim duyup duymadığını kendinize sorun.