2009-05-22 3 views
6

Voici la procédure stockée que j'ai écrite. Dans ce proc "p_subjectid" est un tableau de nombres transmis à partir du frontend.Erreur Oracle ORA-22905: impossible d'accéder aux lignes d'un élément de table non imbriqué

PROCEDURE getsubjects(p_subjectid subjectid_tab,p_subjects out refCursor) 
     as 

     BEGIN 

      open p_subjects for select * from empsubject where subject_id in 
      (select column_value from table(p_subjectid)); 
      --select * from table(cast(p_subjectid as packg.subjectid_tab)) 
     END getsubjects; 

Ceci est l'erreur que j'obtiens.

Oracle error ORA-22905: cannot access rows from a non-nested table item OR 

comme je l'ai vu dans les différents post, j'ai essayé casting « casting (comme p_subjectid packg.subjectid_tab) » Fonction de table à l'intérieur comme indiqué dans le commentaire below.But je reçois une autre erreur: ORA-00902: invalid datatype.

Et c'est la définition du "subjectid_tab". Est-ce que quelqu'un peut me dire quelle est l'erreur? Quelque chose ne va pas avec la procédure.

Répondre

10

Vous devez déclarer le type sur "le niveau de base de données", comme ammoQ suggéré:

CREATE TYPE subjectid_tab AS TABLE OF NUMBER INDEX BY binary_integer; 

au lieu de déclarer le type dans les PL/SQL. Si vous déclarez le type juste dans le bloc PL/SQL, il ne sera pas disponible pour le "moteur" SQL.

+0

Cela ne fonctionne pas dans Oracle 11g, au cas où quelqu'un d'autre aurait du mal .. PLS-00355: Utilisation de la table pl/sql non définie dans ce contexte. Tout semble bien dans Oracle 12c si. Comme un travail autour de 11g, si vous ne pouvez que lier à des tableaux associatifs (comme nodejs), j'ai bouclé mon tableau associatif dans une table imbriquée (pas de suffixe INDEX BY) d'abord; ce qui tue la performance, mais que pouvez-vous faire? Si quelqu'un connaît un meilleur moyen, n'hésitez pas à tendre la main. –

4

Je pense que vous ne pouvez pas simpy utiliser table() sur une table de nombres; ça doit être une table d'objets.

+0

Ensuite, comment utiliser la clause 'IN' avec le tableau de nombres –

+2

Essayez ceci: "CREATE TYPE subjectid_tab COMME TABLE DE NUMERO INDEX PAR binary_integer;" au lieu de déclarer le type dans PL/SQL. –

+0

je vous remercie pour votre suggestion.Mais j'ai déclaré ce type dans ma spécification de paquet comme de type subjectid_tab est table d'index de nombre par binary_integer; –

1

vous avez à jeter les résultats de la requête en pipeline afin:

Si votre fonction pipelinée renvoie une rowtype de varchar2 définir alors un type (par exemple)

CREATE OR REPLACE char_array_t TYPE est VARRAY (32) de varchar2 (255); sélectionnez * dans la table (cast (fn (x) as user_type_t));

va maintenant fonctionner.

1

J'ai juste eu ce problème hier.

 
DECLARE 
    TYPE number_table IS TABLE OF NUMBER; 
    result_ids number_table := number_table(); 
BEGIN 
    /* .. bunch of code that uses my type successfully */ 

    OPEN ? AS 
    SELECT * 
    FROM TABLE(CAST(result_ids AS number_table)); /* BOOM! */ 
END; 

Ceci échoue dans les deux cas décrits précédemment lors d'un appel à partir d'une routine Java. J'ai découvert que cela était dû au fait que le type number_table n'est pas défini de manière exportable par rapport à la base de données. Le type fonctionne parfaitement en interne à la routine. Mais dès que vous essayez d'exécuter un jeu d'enregistrements retournable qui le référence de quelque façon (y compris les clauses IN?!?), Vous obtenez un type de données non défini.

Donc, la solution est vraiment CREATE TYPE myschema.number_table IS TABLE DE NOMBRE; Ensuite, supprimez la déclaration de type de votre bloc et utilisez la déclaration de niveau de schéma. Utilisez le qualificateur de schéma pour référencer le type juste pour être sûr que vous utilisez le bon.

2

C'est la bonne solution. Vous ne pouvez pas utiliser une table (cast()) si le type que vous avez cast est dans la partie DECLARE du bloc pl/sql. Vous devez vraiment utiliser CREATE TYPE my_type [...]. Sinon, il lancera l'exception "can not fetch row [...]".

Questions connexes