【问题标题】:Is this a bug in the PL/SQL Compiler?这是 PL/SQL 编译器中的错误吗?
【发布时间】:2011-05-29 10:42:14
【问题描述】:

在我们的 SVN 代码存储库中,我遇到了一个包规范,它 -after 删除几行 - 归结为

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

在我看来,这样的规范没有多大意义,因此 根本不应该编译。但也许,我没有看到明显的,所以:这真的是一个错误吗?

为了完整起见:

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

编辑:有人建议在上面给出的规范中return 不是关键字,而是一个(包)变量。然而,情况似乎并非如此,因为以下编译同样可以:

create or replace package tq84 as

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

end tq84;
/

很明显,编译器应该告诉我我多次声明了同一个变量。

EDIT 2:JOTN 是对的,当然,returnIS 是一个变量,此外, 编译器不会预先告知,如果一个同名的变量被声明了两次或更多次,而是运行时环境。

因此,考虑到这一点,可以编译类似的东西

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;
/

这看起来很奇怪,至少乍一看是这样。

那么,我想,这不是编译器错误因为 return 被允许作为变量名,但是编译器是否应该至少是有争议的如果同名变量被多次声明,则会发出警告。

【问题讨论】:

  • 我刚刚添加了如何打开警告。
  • 这不是一个错误......它是一个功能;)

标签: oracle plsql oracle10g


【解决方案1】:

显然它允许您使用名称“return”作为变量。在这种情况下,它声明了一个包变量。我会认为这会失败,因为它是一个关键字,但我尝试了它并且它有效。

试试这个代码:

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; 
/ 

这表明 return 作为一个变量,它允许多次声明另一个名称的同一个变量。

现在如果你尝试访问 somevar,那么你会得到:

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

显然它出于某种原因延迟了检查。

我刚刚发现了如何在编译时检测到这些问题。添加这个:

alter session set plsql_warnings = 'enable:all'; 

上面的代码在编译时带有这些警告:

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 

【讨论】:

    【解决方案2】:

    只是想进一步说明 JOTN 的答案是正确的。编译器允许您声明多个具有相同名称的变量似乎确实很糟糕,但这可能是 PL/SQL 如何实现方法重载的副作用。在运行时,如果名称已被多次声明,它确实会引发错误。

    在像您的原始示例这样的示例中,很明显return 被用作变量名。您可以分配和读取它的值,如下所示。

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多