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

时间:2019-04-27 01:53:04

标签: oracle function plsql

此函数声明显然有一些编译错误,但我找不到错误的地方。每件事似乎都很好 该函数从表中选择注释,并验证它们是否都优于95,如果是,则该函数返回true。

我尝试按照建议替换第一个'('by':='和')',但是它没有按我期望的那样工作。

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.

2 个答案:

答案 0 :(得分:2)

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

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

最后一个问题是在FETCH allNote INTO aNote;之前第二次使用END LOOP;。您无需再次使用它。由于您刚在打开上方的光标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;

答案 1 :(得分:2)

从我的角度来看,您做错了(无论编译函数时遇到什么错误)。为什么?因为似乎该函数应该恰好返回一个值。如果是这样,为什么还要使用游标(和循环)?如果有两行(或更多行)满足该条件,那么您将仅返回获取的最后一个值,所以……有什么意义?

因此,我建议这样的事情:

  • 选择该单个值并返回结果
  • 如果未找到任何内容,请使用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>