我的函数声明中有错误 PLS-00103,我找不到问题

Posted

技术标签:

【中文标题】我的函数声明中有错误 PLS-00103,我找不到问题【英文标题】:I have the error PLS-00103 in my function declaration and i can't find the problem 【发布时间】:2019-04-27 01:53:04 【问题描述】:

这个函数声明显然有一些编译错误,但我找不到问题所在.. 一切看起来都很好 函数从表中选择笔记并验证它们是否都优于95,如果是则函数返回true。

我尝试按照建议将第一个 '(' 替换为 ':=' 和 ')',但它没有像我预期的那样工作..

CREATE OR REPLACE FUNCTION BonnePerformance(codeP in CHAR(12), codeS in INTEGER)
RETURN VARCHAR2 IS
estBon VARCHAR2;
aNote INTEGER;
CURSOR allNote IS 
SELECT note
FROM Inscription
WHERE codePermanent = codeP AND codeSession = codeS;
BEGIN 
OPEN allNote;
FETCH allNote INTO aNote;
WHILE allNote%FOUND LOOP
IF aNote > 95 THEN
estBon := 'TRUE';
ELSE 
estBon := 'FALSE';
END IF;
FETCH allNote INTO aNote;
END LOOP;
CLOSE allNote;
RETURN estBon;
END;
/

这里是错误

LINE/COL ERROR
-------- -----------------------------------------------------------------
1/40     PLS-00103: Encountered the symbol "(" when expecting one of the
         following:
         := ) , default varying character large
         The symbol ":=" was substituted for "(" to continue.

【问题讨论】:

我在代码中看到的唯一错误是第 4 行的变量声明没有数字。参数可以声明为VARCHAR2,但变量必须用数字声明,如VARCHAR2(32767)。更改后,代码在我的系统上编译。当您更改代码时,我建议您使用游标 FOR 循环而不是显式游标/打开/获取语法 - 它会更快更简单。 感谢@JonHeller 的回复,我照你说的做了,但还是不行。总是同样的错误... 【参考方案1】:

在我看来,你做错了(不管你在编译函数时遇到的错误)。为什么?因为似乎该函数应该只返回一个值。如果是这样,为什么要使用游标(和循环)?如果有两个(或更多)行满足条件,您将只返回最后一个获取的值,那么......有什么意义呢?

因此,我建议这样:

选择那个单个值并返回结果 如果没有找到,请正确处理,使用EXCEPTION 部分 换句话说,不要“隐藏”游标循环中没有行满足条件的事实。不要偷懒。让某天将维护您的代码的其他人知道发生了什么。你写的不是一本神秘的书,而是一个函数

这就是我的意思。先测试用例:

SQL> create table inscription
  2    (codepermanent varchar2(10),
  3     codesession   int,
  4     note          number
  5    );

Table created.

SQL> insert into inscription
  2    select 'x', 1, 20 from dual union all
  3    select 'y', 2, 99 from dual;

2 rows created.

功能:

SQL> create or replace function bonneperformance
  2    (codep in varchar2, codes in int)
  3  return varchar2
  4  is
  5    estbon varchar2(10) := 'UNKNOWN';
  6  begin
  7    select case when note > 95 then 'TRUE'
  8                else 'FALSE'
  9           end
 10    into estbon
 11    from inscription
 12    where codepermanent = codep
 13      and codesession = codes;
 14
 15    return estbon;
 16  exception
 17    when no_data_found then
 18      return estbon;
 19  end;
 20  /

Function created.

测试:

SQL> select bonneperformance('x', 1) result from dual;

RESULT
--------------------
FALSE

SQL> select bonneperformance('y', 2) result from dual;

RESULT
--------------------
TRUE

SQL> select bonneperformance('z', 3) result from dual;

RESULT
--------------------
UNKNOWN

SQL>

【讨论】:

【参考方案2】:

您的代码给出了错误,因为为函数参数定义的长度 (12) 被违反,应将其删除为 .. BonnePerformance(codeP in CHAR, codeS in INTEGER)。顺便说一句,始终将字符串类型变量用作可变长度是一个好习惯。所以,将CHAR 转换为VARCHAR2

此外,您在将 estBon 局部变量定义为 VARCHAR2 时遇到问题。这种情况下,字符串类型参数需要一个长度,例如estBon VARCHAR2(100)。长度取决于您的需要。

最后一个问题是在END LOOP; 之前第二次使用FETCH allNote INTO aNote;。你不需要再次使用它。由于您在打开上面的光标allNote 后已经使用过。因此,将您的整个代码转换为 ;

CREATE OR REPLACE FUNCTION BonnePerformance(codeP in VARCHAR2,
                                            codeS in INTEGER)
  RETURN VARCHAR2 IS
  estBon VARCHAR2(100);
  aNote  INTEGER;
  CURSOR allNote IS
    SELECT note
      FROM Inscription
     WHERE codePermanent = codeP
       AND codeSession = codeS;
BEGIN
  OPEN allNote;
  FETCH allNote
    INTO aNote;
  WHILE allNote%FOUND LOOP
    IF aNote > 95 THEN
      estBon := 'TRUE';
    ELSE
      estBon := 'FALSE';
    END IF;
  END LOOP;
  CLOSE allNote;
  RETURN estBon;
END;

【讨论】:

以上是关于我的函数声明中有错误 PLS-00103,我找不到问题的主要内容,如果未能解决你的问题,请参考以下文章

执行脚本时遇到 PLS-00103 错误

oracle函数错误pls-00103

(PLS-00103:在简单声明游标语句和循环选择数据期间遇到符号“;”)

错误(5,1):PLS-00103:创建函数时遇到符号“CREATE”错误

错误(8,1):PLS-00103:遇到符号“SET”

PL/SQL 函数错误 - PLS-00103:遇到符号“IS”