web-dev-qa-db-ja.com

ORA-06502:文字列バッファが小さすぎます。文字列サイズが宣言されたサイズ制限を下回っていても

 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);

私が知っていること -

  1. 変数v_field_Aは100文字を超える値を保持できません
  2. SELECTクエリから取得した出力は、10文字を超えていません。

私の質問-文字がvarchar2の制限内にあるときに、スペースバッファーのこの問題にどのように直面することさえ可能ですか?数年前にこの問題に直面しましたが、前回はselectクエリの出力が原因でした。 100文字を超えていたためサイズの問題がありましたが、今回は10文字を超えていません。よくわかりません。どんな助けでもありがたいです

4
Pirate X

変数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がスローされます。

5
Lalit Kumar B

11行* 10文字> 100文字=>エラー-10文字の多数の行を3つの変数のいずれかに連結します。それらの1つは、ループを通じて毎回成長します。

何が欠けていますか?

文字とバイトの比較にも注意してください。 varchar2では、各文字に2バイトかかる可能性があります。

0
dsz

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の制限を回避できますが、最終的な文字列が数百文字しかない場合は不要です。

0
Gordon Linoff

あなたの質問に対する答えは、ループが実行される回数と、ループがIF条件の中に入る回数にあります。

例:

条件:BETWEEN 4 AND 8

this_loop.field_A:= 'test';

ループの実行回数 = 100

[〜#〜] concatination [〜#〜]のため、サイズは間違いなく100 CHARを超えます。

他のLOOP条件の場合も同様です。

Solution[〜#〜] varchar [〜#〜]の代わりに[〜#〜] clob [〜#〜]を使用してみてくださいこの問題を解消します。

Oracleエラーは非常に説明的です。それがいくつかのエラーをスローする場合、それはシナリオをかなり説明します:P。

0
Avrajit Roy

この条件が実行された回数と連結されている値を確認してください。これは複数回連結されるため、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を宣言できます

0
Ritanjan