ORA-22905 - Beim Abfragen eines Tabellentyps mit einer SELECT-Anweisung

7
%Vor%

Ich bekomme "ORA-22905: kann nicht auf Zeilen von einem nicht geschachtelten Tabellenelement zugreifen", wenn es auf die Anweisung SELECT from TABLE zugreift.

Ist es sogar möglich, einen Tabellentyp innerhalb von PLSQL abzufragen?

    
Tom 06.10.2013, 11:16
quelle

2 Antworten

24

Es ist möglich, Tabellentypen in PL / SQL abzufragen, aber nur verschachtelte Tabellen und Varrays, deren Typen auf Schemaebene deklariert sind, d. h. außerhalb von PL / SQL.

Der Fehler

  

ORA-22905: kann nicht auf Zeilen von einem nicht verschachtelten Tabellenelement zugreifen

bedeutet, dass Sie versuchen, von einem nicht unterstützten Tabellentyp abzufragen. Ihr Typ type_tab_AB ist wegen der INDEX BY BINARY_INTEGER -Klausel ein assoziatives Array. Entfernen Sie die INDEX BY BINARY_INTEGER -Klausel, um Ihre type_tab_AB zu einem verschachtelten Tabellentyp zu machen. (Varrays würden auch hier funktionieren, aber ich würde nicht empfehlen, sie zu verwenden, es sei denn, Sie kennen eine obere Grenze für die Anzahl der zu erwartenden Zeilen. Wenn Sie einen Varray-Typ deklarieren, müssen Sie die maximale Anzahl von Elementen angeben, während geschachtelte Tabellentypen haben keine solche Einschränkung.)

Nach dieser Änderung funktioniert der Code möglicherweise nicht mehr. Der nächste Fehler, den Sie möglicherweise bekommen (siehe Hinweis unten, wenn Sie das nicht tun) ist

  

PLS-00642: lokale Auflistungstypen sind in SQL-Anweisungen nicht zulässig

Dies liegt daran, dass der Typ, den Sie auswählen, in PL / SQL deklariert ist. Sie müssen type_tab_AB und record_AB außerhalb von PL / SQL mit CREATE TYPE ... deklarieren.

Das nächste Problem, auf das Sie stoßen, ist das Keyword RECORD . Datensatztypen können nur innerhalb von PL / SQL erstellt werden, sie können nicht auf Schemaebene erstellt werden . Ändern Sie RECORD in OBJECT , um dies zu beheben.

Das letzte Problem, auf das Sie stoßen werden, ist mit der SELECT t.AA, t.BB BULK COLLECT INTO tab_AB FROM ... -Anweisung. So wie es aussieht, wird diese Abfrage Ihnen den folgenden Fehler geben:

  

PL / SQL: ORA-00947: nicht genug Werte

Sie wählen zwei Elemente aus jeder Zeile aus und stellen nur eine Tabelle zur Verfügung, in die die Daten massenweise eingefügt werden. Oracle kann nicht wirklich herausfinden, dass Sie die zwei Elemente in Ihren record_AB -Typ stopfen möchten. Sie können dies relativ einfach beheben, indem Sie die Abfrage in SELECT record_AB(t.AA, t.BB) BULK COLLECT INTO tab_AB FROM ... ändern.

Gemeinsam sollten diese Änderungen das Problem beheben. Hier ist ein vollständiges SQL * Plus-Skript, das eine Testtabelle mit einigen Testdaten erstellt und überprüft, ob es den Tabellentyp abfragen kann:

%Vor%

Ich habe das Ergebnis von SELECT in den Inhalt von tab_AB in einen Cursor eingefügt und eine SQL * Plus-Cursorvariable verwendet, um deren Inhalt aufzulisten. Die Ausgabe, die ich erhalte, wenn ich das Skript auf Oracle 11g XE ausführe, nachdem alle Meldungen "Typ erstellt" und "PL / SQL-Prozedur erfolgreich abgeschlossen" lauten, lautet wie folgt:

%Vor%

HINWEIS: Der Einfachheit halber habe ich angenommen, dass der Fragesteller Oracle 11 oder älter verwendet. In Oracle 12 glaube ich, dass Sie Typen verwenden dürfen, die in PL / SQL in einer SQL-Abfrage deklariert sind, so dass Sie möglicherweise nicht auf den PLS-00642-Fehler stoßen. Ich kann nicht sagen, welche anderen Änderungen an meiner Antwort auch für Oracle 12 notwendig sein werden, da ich Oracle 12 noch verwenden muss.

    
Luke Woodward 06.10.2013, 12:52
quelle
2

Sie können keinen Typ abfragen, der in einem pl / sql-Block erstellt wurde. Sie müssen es an der SQL-Eingabeaufforderung erstellen und dann können Sie es abfragen. Siehe unten:

%Vor%     
Lokesh 06.10.2013 12:50
quelle

Tags und Links