2015-11-17 1 views
6

Ich habe gerade mein Abenteuer mit Oracle und PL/SQL begonnen, indem ich einen Legacy-Code analysiert habe.Ein Typ mit Deklaration, aber ohne Definition, der in vielen Paketen verwendet wird

stieß ich auf die folgende Erklärung, die scheinen keine Definition (BODY) zu haben

CREATE OR REPLACE TYPE "TY_STRING_T"; 

aber an vielen Orten viele Pakete verwendet. Zum Beispiel so.

otc ty_string_t := ty_string_t(); 

Ich verstehe, dass dies wie Erstellung einer Instanz der Klasse ist ty_string_t.

Dann wird es zum Beispiel als eine Sammlung verwendet.

Wie kommt es, dass dieser Typ so verwendet wird, während es überhaupt keine Definition gibt? Was vermisse ich? In SQL Developer unter Typen gibt es keinen Körperteil, wenn ich den Knoten erweitern.

EDIT:

für die Abhängigkeiten in all_dependencies Tabelle Suche ergibt folgendes Ergebnis.

SELECT * FROM all_dependencies WHERE name = `TY_STRING_T`; 
------------------------------------------------------------------------------------------------------------------------------ 
| OWNER | NAME  | TYPE | REFERENCED_OWNER | REFERENCED_NAME | REFERENCED_TYPE | REFERENCED_LINK_NAME | DEPENDENCY_TYPE | 
------------------------------------------------------------------------------------------------------------------------------ 
| AAA | TY_STRING_T | TYPE | SYS    | STANDARD  | PACKAGE   | (null)    | HARD   | 
------------------------------------------------------------------------------------------------------------------------------ 
+0

Sind Sie sicher, dass Sie keine übergeordnete Definition in Ihren Paketen haben, so dass Sie einen PL/SQL-Typ haben, der Vorrang hat? Oder vielleicht in einem anderen Schema, obwohl das offensichtlicher wäre. Oder dass der SQL-Level-Typ später nicht neu definiert wird? Soweit ich weiß, können Sie nichts mit einem unvollständigen Typ machen, außer es mit einer Objektdefinition zu vervollständigen; aber Sie bezeichnen es nicht als Objekttyp. –

+0

Danke für die Hinweise. Ich werde sie überprüfen. – Jagger

+0

@AlexPoole Gibt es einen Compilerfehler, wenn Sie versuchen, einen solchen Schematyp zu definieren und ihn dann in der angegebenen Weise zu verwenden? – Jagger

Antwort

4

Die Aussage, die Sie zeigen:

Verwenden Sie die Anweisung CREATE TYPE die Angabe eines Objekttyp, ein SQLJ Objekttyp erstellen:

CREATE OR REPLACE TYPE "TY_STRING_T"; 

an incomplete object type schafft , eine benannte variierende Anordnung (Varray), eine geschachtelte Tabellentyp oder unvollständiger Objekttyp.

...

Ein unvollständiger Typ ist eine Art durch eine Vorwärtstypdefinition erstellt. Es heißt "unvollständig", weil es einen Namen aber keine Attribute oder Methoden hat. Es kann von anderen Typen referenziert werden und kann so dazu verwendet werden, Typen zu definieren, die sich aufeinander beziehen. Sie müssen den Typ jedoch vollständig angeben, bevor Sie ihn zum Erstellen einer Tabelle oder einer Objektspalte oder einer Spalte eines geschachtelten Tabellentyps verwenden können.

Die object-relational developer's guide enthält weitere Informationen über unvollständige Typen und Beispiele für deren Verwendung.

Das ist nicht, was Sie haben. Sie instanziieren und füllen einen Varray, keinen Objekttyp. It would not compile the PL/SQL code with the incomplete type - Sie erhalten einen PLS-00311: the declaration of "TY_STRING_T" is incomplete or malformed Kompilierungsfehler.

Von Kommentaren haben Sie keinen überschreibenden PL/SQL-Typ und (vom Chat) bestätigt die all_dependencies Ansicht, dass Ihre Pakete vom SQL-Level-Typ abhängig sind. Aber es kann nicht so definiert werden, wie Sie es für richtig halten.

Sie können mit der aktuellen Ist-Definition des Typs überprüfen

select dbms_metadata.get_ddl('TYPE', 'TY_STRING_T') from dual; 

Mit der Aussage zeigte man, dass die Renditen:

DBMS_METADATA.GET_DDL('TYPE','TY_STRING_T')          
-------------------------------------------------------------------------------- 

    CREATE OR REPLACE TYPE "STACKOVERFLOW"."TY_STRING_T" ; 

Wieder von Chat, wenn Sie laufen, dass Sie wirklich sehen:

CREATE OR REPLACE TYPE "AAA"."TY_STRING_T" as table of varchar2(32767); 

was viel mehr Sinn macht. Oracle hat den Teil as table... selbst jedoch nicht hinzugefügt - da es glücklich gewesen wäre, es als einen unvollständigen Objekttyp zu belassen; du hättest es nicht benutzen können, schon gar nicht als wäre es ein Varray.

In einem anderen Teil Ihrer Codebasis wurde der Typ mit der neuen, vollständigen Definition neu erstellt. oder jemand hat den Typ manuell neu erstellt (vor dem Erstellen der Pakete, die darauf verweisen). Wenn ich spekulieren müsste, würde ich denken, dass dies ein Problem mit der Quellcodeverwaltung sein könnte - dass unvollständiger Code eingecheckt und versandt wurde und in jeder Umgebung, in der er installiert wurde, korrigiert werden musste. Oder möglicherweise, dass der Code nach der Installation zu einer Version geändert wurde, die nicht mehr korrekt ist.

Der Typname deutet darauf hin, dass es immer eine Tabelle von Strings sein sollte, nicht ein Objekttyp; und die abgeschnittene Version des create-Befehls, die Sie gefunden haben, hätte niemals eine Varray erstellt.

Sie verpassen wirklich nichts in Ihrem Verständnis, es ist nur das, was Sie betrachten, nicht die Realität widerspiegelt.

+0

Sie sind schnell. Ich war auf der Jagd für die Dokumentation, wo es heißt „* oder eine unvollständige Objekttyp *“ +1 –

+0

Frage: Ist nicht die erzeugte Metadaten, die Sie als ** EDITIONABLE TYPE zeigt **. Auf meinem 12c, 'SQL> wählen Sie dbms_metadata.get_ddl ('TYPE', 'TY_STRING_T') von Dual; DBMS_METADATA.GET_DDL ('TYPE', 'TY_STRING_T') ---------------------------------- ---------------------------------- CREATE OR REPLACE EDITIONABLE TYPE "LALIT". "TY_STRING_T" ' –

+0

@LalitKumarB - Ich bin immer noch auf 11g und nicht dort; Ich habe von SQL Developer kopiert und eingefügt. Nein, es wurde in 12c hinzugefügt; [11g docs ohne] (http://docs.oracle.com/cd/E11882_01/server.112/e41084/statements_8001.htm) und [12c mit docs] (https://docs.oracle.com/database/ 121/SQLRF/statements_8001.htm) die editierbare/nicht-editierbare Klausel. Das wird in den [Änderungen] (https://docs.oracle.com/database/121/SQLRF/release_changes.htm) nicht erwähnt. –

0

CREATE OR REPLACE TYPE "AAA". "TY_STRING_T"

Die oben genannte Typ Schaffung ist unvollständig.

SQL> CREATE OR REPLACE TYPE "TY_STRING_T" 
    2/

Type created. 

SQL> DECLARE 
    2 otc ty_string_t := ty_string_t(); 
    3 BEGIN 
    4 otc.EXTEND; 
    5 otc(1) := 'test'; 
    6 end; 
    7/
otc ty_string_t := ty_string_t(); 
    * 
ERROR at line 2: 
ORA-06550: line 2, column 5: 
PLS-00311: the declaration of "TY_STRING_T" is incomplete or malformed 
ORA-06550: line 2, column 5: 
PL/SQL: Item ignored 
ORA-06550: line 4, column 1: 
PLS-00320: the declaration of the type of this expression is incomplete or 
malformed 
ORA-06550: line 4, column 1: 
PL/SQL: Statement ignored 
ORA-06550: line 5, column 1: 
PLS-00320: the declaration of the type of this expression is incomplete or 
malformed 
ORA-06550: line 5, column 1: 
PL/SQL: Statement ignored 

den Chat zwischen OP und @AlexPoole Lesen,

CREATE OR REPLACE TYPE "TY_STRING_T" AS TABLE OF VARCHAR2(32767) 
/

macht mehr Sinn.

SQL> CREATE OR REPLACE TYPE "TY_STRING_T" AS TABLE OF VARCHAR2(32767) 
    2/

Type created. 

SQL> DECLARE 
    2 otc ty_string_t := ty_string_t(); 
    3 BEGIN 
    4 otc.EXTEND; 
    5 otc(1) := 'test'; 
    6 end; 
    7/

PL/SQL procedure successfully completed. 
Verwandte Themen