2010-12-22 3 views
14

In unserem SVN-Repository-Code, stieß ich auf eine Package-Spezifikation, die ein paar Lines- Entfernen -nach läuft darauf hinaus,Ist das ein Fehler im PL/SQL Compiler?

unten
create or replace package tq84 as 
    return varchar2(10); 
end tq84; 
/

Es scheint mir, dass eine solche Spezifikation macht nicht viel Sinn und daher sollte überhaupt nicht kompiliert werden. Aber vielleicht, ich sehe das Offensichtliche nicht, also: Ist das wirklich ein Bug?

Für Vollständigkeit halber:

me @ xxx.yyy.zz > select * from v$version; 
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi 
PL/SQL Release 10.2.0.4.0 - Production 
CORE 10.2.0.4.0  Production 
TNS for IBM/AIX RISC System/6000: Version 10.2.0.4.0 - Productio 
NLSRTL Version 10.2.0.4.0 - Production 

bearbeiten: Es wurde vorgeschlagen, dass, wie oben return in der Beschreibung angegeben ist nicht das Schlüsselwort, sondern eine (Paket-) variabel. Dies scheint jedoch nicht der Fall zu sein, da die folgenden kompiliert ebenso fein:

create or replace package tq84 as 

    return varchar2(10); 
    return number; 
    return date; 

end tq84; 
/

und klar, der Compiler soll mir sagen, dass ich die gleiche Variable mehrfach erklären.

EDIT 2: JOTN ist natürlich recht, und returnIST eine Variable, und darüber hinaus die Compiler sagen nicht im Voraus, wenn eine Variable mit dem gleichen Namen zweimal deklariert wird oder mehr statt Es ist die Laufzeitumgebung, die das tut.

Also, in diesem Sinne ist es möglich, so etwas wie

create or replace package return as 
    subtype return is varchar2(10); 
end return; 
/

create or replace package tq84 as 

    constant constant 

    return . return := 'return'; 

    function function 

    return return . return; 

end tq84; 
/

zu kompilieren, die zumindest auf den ersten Blick seltsam aussieht.

Also, ich denke, es ist nicht ein Compiler Fehler weilreturn als Variablennamen erlaubt, aber dann ist es strittig, ob der Compiler mindestens eine Warnung ausgeben, wenn eine Variable mit dem gleichen Namen soll, ist, mehrfach erklärt.

+0

Ich habe gerade hinzugefügt, wie Sie die Warnungen einschalten. – JOTN

+3

Es ist kein Fehler ... es ist ein Feature;) – guigui42

Antwort

9

Anscheinend erlaubt es Ihnen, den Namen "Rückkehr" als Variable zu verwenden. In diesem Fall deklariert es eine Paketvariable. Ich hätte gedacht, dass das scheitern würde, weil es ein Schlüsselwort ist, aber ich habe es ausprobiert und es hat funktioniert.

diesen Code Versuchen:

create or replace package tq84 as 
    return varchar2(10); 
    somevar varchar2(5); 
    somevar varchar2(5); 
end tq84; 
/

set serveroutput on 
BEGIN 
    tq84.return:='Test'; 
    dbms_output.put_line(tq84.return); 
END; 
/

, dass die Rückkehr als Variable zeigt und es erlaubt die gleiche Variable eines anderen Namen mehr als einmal deklariert werden.

Nun, wenn Sie versuchen, somevar zuzugreifen, können Sie diese dann erhalten:

PLS-00371: at most one declaration for 'TQ84.SOMEVAR' is permitted 

So offenbar verzögert es, dass der Check aus irgendeinem Grund.

Ich habe gerade herausgefunden, wie Sie diese Probleme zur Kompilierzeit erkennen können.Fügen Sie diese:

alter session set plsql_warnings = 'enable:all'; 

Dieser Code kompiliert oben mit diesen Warnungen:

LINE/COL ERROR 
-------- ----------------------------------------------------------------- 
1/1  PLW-05018: unit TQ84 omitted optional AUTHID clause; default 
     value DEFINER used 

2/3  PLW-06010: keyword "RETURN" used as a defined name 
4/3  PLW-05001: previous use of 'SOMEVAR' (at line 3) conflicts with 
     this use 
3

Nur weitere Darstellung hinzufügen wollte, dass JOTN Antwort richtig ist. Es scheint schlecht, dass der Compiler Sie mehrere Variablen mit dem gleichen Namen deklarieren lässt, aber vielleicht ist dies ein Nebeneffekt von wie PL/SQL das Überladen von Methoden implementiert. Zur Laufzeit wird ein Fehler gemeldet, wenn der Name mehrfach deklariert wurde.

In einem Beispiel wie Ihrem ursprünglichen Beispiel ist es klar, dass return als Variablenname verwendet wird. Sie können den Wert wie folgt zuweisen und lesen.

dev> set serveroutput on 
dev> create or replace package test 
    2 as 
    3 return varchar2(10); 
    4 end test; 
    5/

Package created. 

dev> exec test.return := 'Hi!'; 

PL/SQL procedure successfully completed. 

dev> exec dbms_output.put_line(test.return); 
Hi! 

PL/SQL procedure successfully completed. 

dev> create or replace package test 
    2 as 
    3 return varchar2(10); 
    4 return varchar2(20); 
    5 end test; 
    6/

Package created. 

dev> exec test.return := 'Hi!'; 
BEGIN test.return := 'Hi!'; END; 

      * 
ERROR at line 1: 
ORA-06550: line 1, column 12: 
PLS-00371: at most one declaration for 'TEST.RETURN' is permitted 
ORA-06550: line 1, column 7: 
PL/SQL: Statement ignored