web-dev-qa-db-fra.com

ORA-06502: Mémoire tampon de chaîne de caractères est trop petite. Même si la taille de la chaîne est inférieure à la taille de la taille déclarée

 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;

Variable decalared comme

v_field_A            VARCHAR2 (100);

Ce que je sais -

  1. La variable v_field_A ne peut pas contenir plus de 100 caractères
  2. Le résultat de la requête SELECT ne comporte pas plus de 10 caractères. 

Ma question - Comment est-il possible de faire face à cette question de tampon d’espace lorsque les caractères se trouvent dans la limite de varchar2? J’ai fait face à cette question il ya quelques années, mais la dernière fois que la cause était la sortie de la requête select. Il y avait plus de 100 caractères et par conséquent le problème de taille, mais cette fois, il ne dépasse pas 10 caractères. Je suis confus. Toute aide est appréciée

3
Pirate X

La variable v_field_A ne peut pas contenir plus de 100 caractères

Pourquoi pas? C'est très possible puisque vous êtes concaténant la variable pour chaque ligne du CURSOR FOR LOOP

Par exemple,

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

Utilisez DBMS_OUTPUT pour voir la taille actuelle de la variable et la nouvelle valeur ajoutée.

déboguons

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

Erreur

DECLARE
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at line 9

Il est assez clair que nous voulions concaténer une chaîne de longueur 5 avec la variable déclarée comme étant max size 50, contenant actuellement une valeur de taille 50. par conséquent, il génère l'erreur ORA-06502: PL/SQL: numeric or value error: character string buffer too small.

4
Lalit Kumar B

11 lignes * 10 caractères> 100 caractères => erreur - votre concaténation de plusieurs lignes de 10 caractères dans une des trois variables. L'un d'entre eux grandira à chaque fois dans la boucle.

Qu'est-ce que je rate?

Méfiez-vous également des caractères par opposition aux octets. Dans un varchar2, chaque caractère prendra probablement 2 octets.

0
dsz

Vous pouvez faire la concaténation de chaînes dans une requête 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;

Ceci est destiné à simplifier votre code. Vous êtes toujours limité par la longueur des chaînes Oracle. Vous pouvez contourner la limite Oracle dans PL/SQL à l'aide d'un CLOB, mais cela n'est pas nécessaire lorsque la chaîne finale ne contient que quelques centaines de caractères.

0
Gordon Linoff

La réponse à votre question réside dans le nombre de fois que la boucle S’exécute et combien de fois elle passe dans la condition IF.

EXEMPLE:

Condition: ENTRE 4 ET 8 

this_loop.field_A: = 'test';

Nombre de fois que la boucle est exécutée = 100

En raison de CONCATINATION, la taille dépassera certainement plus de 100 CHAR.

De même sera le cas avec d'autres conditions de boucle.

Solution: essayez d'utiliser CLOB _ _ au lieu de _VARCHAR__ pour éliminer ce problème.

Les erreurs Oracle sont très descriptives. S'il y a une erreur, cela explique assez bien le scénario: P.

0
Avrajit Roy

Vérifiez combien de fois cette condition est exécutée et quelles valeurs sont concaténées. Comme cela est concaténé plusieurs fois, il est possible que la taille de v_field_A dépasse 50 caractères

ELSIF this_loop.field_B BETWEEN 4 AND 8
 THEN
    v_field_A := v_field_A || ' ' || this_loop.field_A; 

Pour résoudre ce problème, vous pouvez augmenter la taille de cette variable. Vous pouvez déclarer un varchar jusqu'à 32 767 octets

0
Dawn