FOR this_loop
IN (SELECT field_A, field_B
FROM TABLE_NAME
WHERE num = i_num)
LOOP
IF this_loop.field_B BETWEEN 1 AND 3
THEN
v_A := v_A || ' ' || this_loop.field_A;
ELSIF this_loop.field_B BETWEEN 4 AND 8
THEN
v_field_A := v_field_A || ' ' || this_loop.field_A; -- Error is at this line
ELSIF this_loop.field_B BETWEEN 9 AND 15
THEN
v_B := v_B || ' ' || this_loop.field_A;
END IF;
END LOOP;
変数デカール
v_field_A VARCHAR2 (100);
私が知っていること -
SELECT
クエリから取得した出力は、10文字を超えていません。私の質問-文字がvarchar2の制限内にあるときに、スペースバッファーのこの問題にどのように直面することさえ可能ですか?数年前にこの問題に直面しましたが、前回はselect
クエリの出力が原因でした。 100文字を超えていたためサイズの問題がありましたが、今回は10文字を超えていません。よくわかりません。どんな助けでもありがたいです
変数v_field_Aは100文字を超える値を保持できません
何故なの? 連結CURSOR FOR LOOPの各行の変数なので、非常に可能です。
例えば、
SQL> DECLARE
2 v_name VARCHAR2(50);
3 BEGIN
4 FOR i IN
5 (SELECT ename FROM emp
6 )
7 LOOP
8 v_name := v_name || i.ename;
9 END LOOP;
10 END;
11 /
DECLARE
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at line 8
DBMS_OUTPUTを使用して、変数の現在のサイズと追加される新しい値を確認します。
デバッグしましょう
SQL> DECLARE
2 v_name VARCHAR2(50);
3 BEGIN
4 FOR i IN
5 (SELECT ename FROM emp
6 )
7 LOOP
8 dbms_output.put_line('Length of new value = '||LENGTH(i.ename));
9 v_name := v_name || i.ename;
10 dbms_output.put_line('Length of variable = '||LENGTH(v_name));
11 END LOOP;
12 END;
13 /
Length of new value = 5
Length of variable = 5
Length of new value = 5
Length of variable = 10
Length of new value = 4
Length of variable = 14
Length of new value = 5
Length of variable = 19
Length of new value = 6
Length of variable = 25
Length of new value = 5
Length of variable = 30
Length of new value = 5
Length of variable = 35
Length of new value = 5
Length of variable = 40
Length of new value = 4
Length of variable = 44
Length of new value = 6
Length of variable = 50
Length of new value = 5
エラー
DECLARE
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at line 9
かなり明確です。長さ5
の文字列を、現在最大サイズ50
の値を保持している最大サイズ50
として宣言された変数に連結したかったのです。したがって、エラーORA-06502: PL/SQL: numeric or value error: character string buffer too small
がスローされます。
11行* 10文字> 100文字=>エラー-10文字の多数の行を3つの変数のいずれかに連結します。それらの1つは、ループを通じて毎回成長します。
何が欠けていますか?
文字とバイトの比較にも注意してください。 varchar2では、各文字に2バイトかかる可能性があります。
SQLクエリで文字列連結を行うことができます。
SELECT field_A,
LISTAGG(CASE WHEN field_B BETWEEN 1 AND 3 THEN field_A END, ' ') WITHIN GROUP (ORDER BY field_A) as val1,
LISTAGG(CASE WHEN field_B BETWEEN 4 AND 8 THEN field_A END, ' ') WITHIN GROUP (ORDER BY field_A) as val2,
LISTAGG(CASE WHEN field_B BETWEEN 9 AND 15 THEN field_A END, ' ') WITHIN GROUP (ORDER BY field_A) as val3
FROM TABLE_NAME
WHERE num = i_num;
これは、コードを簡略化することを目的としています。 Oracle文字列の長さによって制限されます。 CLOBを使用してPL/SQLでのOracleの制限を回避できますが、最終的な文字列が数百文字しかない場合は不要です。
あなたの質問に対する答えは、ループが実行される回数と、ループがIF条件の中に入る回数にあります。
例:
条件:BETWEEN 4 AND 8
this_loop.field_A:= 'test';
ループの実行回数 = 100
[〜#〜] concatination [〜#〜]のため、サイズは間違いなく100 CHARを超えます。
他のLOOP条件の場合も同様です。
Solution:[〜#〜] varchar [〜#〜]の代わりに[〜#〜] clob [〜#〜]を使用してみてくださいこの問題を解消します。
Oracleエラーは非常に説明的です。それがいくつかのエラーをスローする場合、それはシナリオをかなり説明します:P。
この条件が実行された回数と連結されている値を確認してください。これは複数回連結されるため、v_field_Aのサイズが50文字を超える可能性があります。
ELSIF this_loop.field_B BETWEEN 4 AND 8
THEN
v_field_A := v_field_A || ' ' || this_loop.field_A;
これを解決するには、この変数のサイズを大きくします。 32,767バイトまでのvarcharを宣言できます