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:
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.