web-dev-qa-db-fra.com

Référence à la collection non initialisée PL / SQL

Je reçois ORA-06531: Reference to uninitialized collection lorsque j'exécute une procédure stockée avec les détails suivants:

Type de données défini par l'utilisateur:

CREATE OR REPLACE TYPE T IS TABLE OF VARCHAR2;

Définition de la procédure stockée:

CREATE OR REPLACE PROCEDURE TEST ( u IN T, v OUT T)
IS
BEGIN
  FOR i IN u.FIRST..u.LAST LOOP
    v(i) := u(i);
  END LOOP;
END;

J'utilise ce qui suit pour invoquer la procédure:

DECLARE
  v_t T;
  u_t T;
BEGIN
  v_t := T();
  v_t.EXTEND(2);

  v_t(1) := "This is test1";
  v_t(2) := "This is test2";
  TEST(v_t, u_t);
END;
9
rohit_agarwal

Dans votre procédure TEST, vous avez déclaré v en tant que paramètre OUT - cela signifie que la procédure doit initialiser la collection de sortie dans la procédure (par exemple v := T();). Même si vous modifiez le bloc appelant pour initialiser u_t cela n'aidera pas, car le u_t la collection n'est pas transmise à la procédure - elle ne reçoit que ce que la procédure retransmet.

Modifiez votre code comme suit:

CREATE OR REPLACE PROCEDURE TEST ( u IN T, v OUT T) IS
  i NUMBER := u.FIRST;
BEGIN
  v := T();
  v.EXTEND(u.COUNT);

  IF i IS NOT NULL THEN
    LOOP
      v(i) := u(i);
      i := u.NEXT(i);
      EXIT WHEN i IS NULL;
    END LOOP;
  END IF;
END TEST;

DECLARE
  v_t T;
  u_t T;
BEGIN
  v_t := T();
  v_t.EXTEND(2);

  v_t(1) := 'This is test1';
  v_t(2) := 'This is test2';

  TEST(v_t, u_t);

  FOR i IN u_t.FIRST..u_t.LAST LOOP
    DBMS_OUTPUT.PUT_LINE(u_t(i));
  END LOOP;
END;

Veuillez noter que les constantes de chaîne en PL/SQL doivent être placées entre guillemets simples, et non entre guillemets doubles.

De plus, l'utilisation de noms de variables similaires qui ont des significations opposées dans la procédure et le bloc appelant ne fait qu'ajouter à la confusion. Prenez l'habitude d'utiliser des noms significatifs et vous vous épargnerez beaucoup de confusion plus tard.

Partagez et profitez.

15
Bob Jarvis

J'ai eu une question similaire aujourd'hui, vous devez initialiser votre variable u_t, vérifier this réponse pour en savoir plus

0
zaratustra