web-dev-qa-db-fra.com

Passer un tableau de données comme paramètre d'entrée à une procédure Oracle

J'essaie de passer un tableau de données (varchar) dans une procédure Oracle. La procédure Oracle serait appelée à partir de SQL * Plus ou d'une autre procédure PL/SQL comme ceci:

BEGIN
 pr_perform_task('1','2','3','4');
END;

pr_perform_task Lira chacun des paramètres d'entrée et effectuera les tâches.

Je ne sais pas comment je peux y parvenir. Ma première pensée a été d'utiliser un paramètre d'entrée de type varray mais j'obtiens l'erreur Error: PLS-00201: identifier 'VARRAY' must be declared, Lorsque la définition de la procédure ressemble à ceci:

CREATE OR REPLACE PROCEDURE PR_DELETE_RECORD_VARRAY(P_ID VARRAY) IS

Pour résumer, comment puis-je transmettre les données sous forme de tableau, laisser le SP boucler à travers chacun des paramètres et effectuer la tâche?

J'utilise Oracle 10gR2 comme base de données.

31
Sathyajith Bhat

C'est une façon de procéder:

SQL> set serveroutput on
SQL> CREATE OR REPLACE TYPE MyType AS VARRAY(200) OF VARCHAR2(50);
  2  /

Type created

SQL> CREATE OR REPLACE PROCEDURE testing (t_in MyType) IS
  2  BEGIN
  3    FOR i IN 1..t_in.count LOOP
  4      dbms_output.put_line(t_in(i));
  5    END LOOP;
  6  END;
  7  /

Procedure created

SQL> DECLARE
  2    v_t MyType;
  3  BEGIN
  4    v_t := MyType();
  5    v_t.EXTEND(10);
  6    v_t(1) := 'this is a test';
  7    v_t(2) := 'A second test line';
  8    testing(v_t);
  9  END;
 10  /

this is a test
A second test line

Pour développer mon commentaire sur la réponse de @ dcp, voici comment vous pouvez implémenter la solution qui y est proposée si vous souhaitez utiliser un tableau associatif:

SQL> CREATE OR REPLACE PACKAGE p IS
  2    TYPE p_type IS TABLE OF VARCHAR2(50) INDEX BY BINARY_INTEGER;
  3  
  4    PROCEDURE pp (inp p_type);
  5  END p;
  6  /

Package created
SQL> CREATE OR REPLACE PACKAGE BODY p IS
  2    PROCEDURE pp (inp p_type) IS
  3    BEGIN
  4      FOR i IN 1..inp.count LOOP
  5        dbms_output.put_line(inp(i));
  6      END LOOP;
  7    END pp;
  8  END p;
  9  /

Package body created
SQL> DECLARE
  2    v_t p.p_type;
  3  BEGIN
  4    v_t(1) := 'this is a test of p';
  5    v_t(2) := 'A second test line for p';
  6    p.pp(v_t);
  7  END;
  8  /

this is a test of p
A second test line for p

PL/SQL procedure successfully completed

SQL> 

Cela échange la création d'un TYPE Oracle autonome (qui ne peut pas être un tableau associatif) avec la définition d'un package qui peut être vu par tous afin que le TYPE qu'il y définit puisse être utilisé par tous.

43
DCookie

Si les types de paramètres sont tous identiques (varchar2 par exemple), vous pouvez avoir un package comme celui-ci qui fera ce qui suit:

CREATE OR REPLACE PACKAGE testuser.test_pkg IS

   TYPE assoc_array_varchar2_t IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;

   PROCEDURE your_proc(p_parm IN assoc_array_varchar2_t);

END test_pkg;

CREATE OR REPLACE PACKAGE BODY testuser.test_pkg IS

   PROCEDURE your_proc(p_parm IN assoc_array_varchar2_t) AS
   BEGIN
      FOR i IN p_parm.first .. p_parm.last
      LOOP
         dbms_output.put_line(p_parm(i));
      END LOOP;

   END;

END test_pkg;

Ensuite, pour l'appeler, vous devez configurer la baie et la transmettre:

DECLARE
  l_array testuser.test_pkg.assoc_array_varchar2_t;
BEGIN
  l_array(0) := 'hello';
  l_array(1) := 'there';  

  testuser.test_pkg.your_proc(l_array);
END;
/
6
dcp