2017-08-09 1 views
0

Ceci est probablement une question simple pour qui connaît PL/SQL. J'ai une procédure stockée qui prend un tableau de varchar en entrée:Exécuter une sélection dans une boucle PL/SQL et retour du curseur?

TYPE MULTI is table of VARCHAR(15) index by BINARY_INTEGER; 


PROCEDURE MYPROC(
    SINGLE        IN  MULTI, 
    P_RESULT        OUT MY_PCK.MYCURSOR, 
    P_SOMETHING       OUT VARCHAR2, 
); 

Le curseur fonctionne parce que je l'ai testé dans d'autres cas, mais c'est le premier avec un paramètre de tableau.

J'ai un problème avec le corps, comment puis-je attribuer chaque valeur que je reçois de la sélection au curseur?

BEGIN 
    FOR i IN SINGLE.first .. SINGLE.last 
    LOOP 
    --BEGIN OPEN P_RESULT FOR this --this on left gives me error 
           SELECT MT.DESCR INTO P_SOMETHING 
           FROM MYTABLE1 MT 
           WHERE MT.IDS = SINGLE(i) 
           AND and rownum < 2; 
--dbms_output.put_line(SINGLE(i)); --if i use this instead of select i get the values i send to this procedure. 
    END LOOP; 

i essayé aussi:

SELECT MT.DESCR INTO P_RESULT but gives error 

Qu'est-ce que je fais mal? Merci dans le conseil.

+0

Quelle erreur avez-vous? – I3rutt

+0

PLS-00428: une clause INTO est attendue dans cette instruction SELECT. Si j'utilise une clause into comme: MT.DESCR INTO P_SOMETHING où P_SOMETHING est une sortie varchar2, j'obtiens: ORA-01422: l'extraction exacte renvoie plus que le nombre de lignes demandé. Je ne sais vraiment pas comment résoudre ce problème ... –

+0

Pour résoudre rapidement essayez d'ajouter ceci dans la clause WHERE: et rownum <2 – I3rutt

Répondre

0

Vous ne pouvez pas utiliser votre type de collection PL/SQL dans une instruction SQL dans 11g. Vous pouvez créer un type de collection SQL ou en trouver un auquel vous avez déjà accès (avec une longueur de chaîne appropriée) et l'utiliser pour au moins vérifier le mécanisme. Par exemple, ceci utilise une variable locale de type SYS.HSBLKNAMLST, qui est définie comme table of varchar2(30), plus que suffisant pour correspondre à la longueur de chaîne de votre propre type PL/SQL. Cette variable est peuplée de votre passé dans le type PL/SQL, et qui est ensuite utilisée dans une requête pour ouvrir le curseur:

PROCEDURE MYPROC(
    SINGLE        IN  MULTI, 
    P_RESULT        OUT MY_PCK.MYCURSOR 
) IS 
    LOCAL_COLL SYS.HSBLKNAMLST := SYS.HSBLKNAMLST(); 
BEGIN 
    FOR i IN SINGLE.first .. SINGLE.last 
    LOOP 
    LOCAL_COLL.extend(); 
    LOCAL_COLL(LOCAL_COLL.last) := SINGLE(i); 
    END LOOP; 

    OPEN P_RESULT FOR 
    SELECT MT.DESCR 
    FROM MYTABLE1 MT 
    LEFT JOIN TABLE(LOCAL_COLL) LC 
    ON LC.COLUMN_VALUE = MT.IDS 
    WHERE LC.COLUMN_VALUE IS NULL; 

END; 

Je suis un peu confus au sujet de la requête que vous montriez dans votre boucle bien; vous semblez essayer de rouvrir le curseur pour chaque élément du tableau, bien que vous essayiez peut-être d'ajouter le résultat de la requête pour chaque élément au même curseur - pensait que le != signifierait que toutes les lignes seraient incluses à quelque point. Je suppose que vous essayez d'obtenir tous les enregistrements avec des valeurs IDS qui ne sont pas dans le tableau. Si vous voulez vraiment tout ce qui est alors ce serait:

OPEN P_RESULT FOR 
    SELECT MT.DESCR 
    FROM TABLE(LOCAL_COLL) LC 
    JOIN MYTABLE1 MT 
    ON MT.IDS = LC.COLUMN_VALUE; 

Vous pouvez voir quels types intégrés sont disponibles pour vous en interrogeant le dictionnaire de données, par exemple:

select owner, type_name, coll_type, elem_type_name, length 
from all_coll_types 
where elem_type_name = 'VARCHAR2' 
and coll_type = 'TABLE' 
and owner = 'SYS' 
order by length; 

Il serait préférable de créer votre propre type SQL si vous le pouvez.

+0

Le! = Était une erreur (test ...), désolé pour cela. Je vais essayer ce que tu as écrit. –