質問
私はOracle10gを使用していて、次のテーブル構造を持っています:ID、段落
IDでグループ化し、段落を連結したいと思います。各段落はおそらく1500文字以上です。
WM_CONCAT関数を試すと、文字列バッファーが小さすぎると不満を述べています。私は実際にOracleのウェブサイトで多くの例を試しましたが、それらはすべてエラーで失敗しましたが、文字列バッファーが小さすぎます。
select id, wm_concat(paragraph) from paragraphs group by id
これを解決するにはどうすればよいですか?
解決
だから、私はエラーがあると推測しています ORA-06502
そして、この状況でこれがあなたに当てはまらないとあなたがどのように考えるかもしれないかを見ることができます。
しかし、これはのせいです wm_concat
. 。これは関数であり、32,767のPl SQLのOracleの最大Varchar長、および標準SQLの4,000によって制約されています。残念ながら、WM_CONCATの動作方法、または関数内の制約が低いため、または上限近くに入ることができないセレクトで使用しているために、私は想定しています。
別のオプションがあります、 stragg
, 、Tom Kyteの文字列集約関数。次の比較を見ると、2つの比較を見ると、ほぼ同一に実行され、両方の制限が約4,000の長さ、つまり標準SQLの最大値であることがわかります。 stragg
おそらくキャッシュのために、少し速いです。
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.
それを解決することに関しては、私はあなたができないのではないかと心配しています。その制限に達したら、それだけです。あなたはあなたの集計を行うための別の方法を見つけるか、あなたが 本当 する必要があります。
所属していません StackOverflow