2009-05-22 4 views
6

Hier ist die gespeicherte Prozedur, die ich schrieb.In diesem Prozess "p_subjectid" ist ein Array von Zahlen vom Front-End übergeben.Oracle-Fehler ORA-22905: kann nicht auf Zeilen von einem nicht verschachtelten Tabellenelement zugreifen

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; 

Dies ist der Fehler, den ich bekomme.

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

, wie ich in verschiedener Post gesehen habe, habe ich versucht, in dem Kommentar "cast (p_subjectid als packg.subjectid_tab)" innerhalb Tabellenfunktion als gegeben Casting below.But ich bin immer ein anderen Fehler: ORA-00902: invalid datatype.

Und das ist die Definition der "subjectid_tab".

Kann mir bitte jemand sagen, was ist der Fehler.Ist etwas falsch mit meinem Verfahren.

Antwort

10

Sie haben den Typ auf „Datenbankebene“ zu erklären, wie ammoQ vorgeschlagen:

CREATE TYPE subjectid_tab AS TABLE OF NUMBER INDEX BY binary_integer; 

statt den Typ innerhalb PL/SQL zu deklarieren. Wenn Sie den Typ nur im PL/SQL-Block deklarieren, steht er der SQL-Engine nicht zur Verfügung.

+0

Dies funktioniert nicht in Oracle 11g, falls jemand anderes Probleme hat. PLS-00355: Verwendung von pl/sql Tabelle nicht in diesem Zusammenhang definiert. In Oracle 12c sieht alles gut aus. Als Workaround in 11g, wenn Sie nur an assoziative Arrays (wie nodejs) binden können, habe ich zuerst mein assoziatives Array in eine geschachtelte Tabelle (kein INDEX BY-Suffix) geloopt; was die Leistung tötet, aber was kannst du tun? Wenn jemand einen besseren Weg kennt, zögern Sie nicht, die Hand zu reichen. –

4

Ich denke, Sie können nicht einfach Tabelle() auf einer Tabelle von Zahlen verwenden; es muss eine Tabelle von Objekten sein.

+0

Dann, wie 'IN' Klausel mit der Tabelle der Zahlen –

+2

verwenden Versuchen Sie Folgendes: "CREATE TYPE subjectid_tab als Tabelle der Nummer Index von binary_integer;" statt den Typ in PL/SQL zu deklarieren. –

+0

danke für Ihren Vorschlag.Aber ich habe diesen Typ in meiner Paketspezifikation als Typ subjectid_tab ist Tabelle des Zahlenindex von binary_integer; –

1

müssen Sie die Ergebnisse der Pipeline-Abfrage werfen so:

Wenn Ihre Pipeline-Funktion eine rowtype von varchar2 gibt dann eine Art definieren (zum Beispiel)

CREATE OR TYPE char_array_t REPLACE VARRAY (32) von varchar2 (255); * aus der Tabelle auswählen (cast (fn (x) as user_type_t));

wird jetzt funktionieren.

1

Ich hatte gerade dieses Problem gestern.

Dies schlägt auf beide Arten fehl, die Sie zuvor beschrieben haben, wenn Sie von einer Java-Routine aufgerufen werden. Ich fand heraus, dass dies auf die Tatsache zurückzuführen ist, dass der Typ number_table nicht exportierbar definiert ist, als von der Datenbank geliefert werden kann. Der Typ funktioniert intern hervorragend zur Routine. Aber sobald Sie versuchen, ein Mehrzweck-Recordset auszuführen, das es in irgendeiner Weise referenziert (einschließlich IN-Klauseln?!?), Erhalten Sie einen Datentyp, der nicht definiert ist.

Also die Lösung ist wirklich CREATE TYPE myschema.number_table IST TABELLE DER NUMMER; Lassen Sie dann die Typdeklaration von Ihrem Block fallen und verwenden Sie die Schemadefinition. Verwenden Sie das Schemaqualifikationsmerkmal, um nur auf den Typ zu verweisen, um sicherzustellen, dass Sie den richtigen Typ verwenden.

2

Dies ist die gute Lösung. Sie können keine Tabelle (cast()) verwenden, wenn sich der Typ, den Sie gewirkt haben, im DECLARE-Teil des pl/sql-Blocks befindet. Sie müssen wirklich CREATE TYPE my_type [...] verwenden. Andernfalls wird die Ausnahme "Kann Zeile [...] nicht abrufen" ausgelöst.